QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 3895|回复: 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>
    9 m/ @2 H* i( X<>// File: mazeserver.cpp
    ; F" r' D% h- a9 r' Q* O//
    ' v" u5 _/ B6 `// Desc: see main.cpp' m6 h, A5 R1 I9 D
    //
    + _8 A$ q: E! ?2 r. d// Copyright (c) 1999-2001 Microsoft Corp. All rights reserved.2 E& J  Y0 M# n- @7 O" V* @
    //-----------------------------------------------------------------------------* @5 m+ N7 D+ Q, P+ i0 N
    #define STRICT
    8 I8 z& H. I+ t5 w2 F#define D3D_OVERLOADS
    6 L7 t$ }8 p  z1 ]* Y3 b3 ?' H#include &lt;windows.h&gt;
    , `9 d& a7 A% U#include &lt;d3dx.h&gt;
    , N; e' n- U: a#include &lt;stdio.h&gt;( F- ]# C. p( n/ O: O1 @# L& g
    #include &lt;math.h&gt;
    - i4 A, [4 ^$ f" t9 B. e" j4 M#include &lt;mmsystem.h&gt;( U, J# t/ B$ R
    #include &lt;dplay8.h&gt;
    . ~* v+ v  q9 |  I. g$ z* n9 s% I' ]#include &lt;dpaddr.h&gt;
    ) `( y+ I8 n8 a/ u" [' n, `#include &lt;dxerr8.h&gt;3 V) o% G3 B" V* j7 H
    #include "DXUtil.h"9 q- z5 C2 a, _' m' B
    #include "MazeServer.h"
    : y) E4 U: f+ B* ~#include "ackets.h"
    + k& }5 G3 ^) u1 R#include "Maze.h", o, n% i% F) o9 y5 Z
    #include &lt;malloc.h&gt;; M% _9 ?- v! |" S) L
    #include &lt;tchar.h&gt;</P>
      Y- H8 L( C' m" K3 V2 ~1 }; A  q5 S3 q* I$ W3 `/ B/ p  `
    <>//-----------------------------------------------------------------------------
    0 q2 [, I. Z+ C7 ^// Name:
    / p6 y0 \) m2 F// Desc: 2 O4 Q' }% t4 G/ k1 G( s; `
    //-----------------------------------------------------------------------------
    9 q8 W7 K' ?3 a* `- v1 B9 KCMazeServer::CMazeServer()* j1 A0 o0 b' ~$ o) x) c/ y
    {
    % i, }. W1 `6 m7 I( ^/ X* p    m_dwPlayerCount         = 0;
    & G; S2 P# l, F2 W/ D& E    3 E4 g: B) E# j$ I& i" O8 B" s
        m_wActiveThreadCount   = 0;9 \. t: g- d2 V4 ^# V$ N
        m_wMaxThreadCount      = 0;/ b. |( `. N- `, ~9 M. N% t% \
        m_fAvgThreadCount      = 0;% h' x+ M3 j! `! h, c; G
        m_fAvgThreadTime       = 0;- v7 v7 b# p) y9 t4 T
        m_fMaxThreadTime       = 0;</P>
      o3 ]! b1 N& C8 ?' D4 x<>    m_dwServerReliableRate  = 15;
    $ w/ O, n1 L5 X! G( ]0 r    m_dwServerTimeout       = 150;! o. O. v0 J& B. q4 Z
        m_dwLogLevel            = 2;* y2 O: w* q* H, u5 f& l
        m_pMaze                 = NULL;</P>
    0 j# E/ |! E% R# v<>    m_ClientNetConfig.ubReliableRate = 15;
    ; \0 K9 _  W/ Y    m_ClientNetConfig.wUpdateRate    = 150;
    4 ]( ~4 ~! i' {0 p* i/ l    m_ClientNetConfig.wTimeout       = 150;</P>( A( d* f. ?# B- O
    <>    m_ClientNetConfig.dwThreadWait = 0;</P>
    * I% e" u* W/ W2 w6 b  H<>    m_ClientNetConfig.ubClientPackIndex = 0;# l8 [# b' o' v. }1 Q! q* B: L. p
        m_ClientNetConfig.ubServerPackIndex = 0;  v/ ^6 V$ {( i( O9 s
        for(WORD x = 0; x &lt; PACK_ARRAY_SIZE; x++)$ j5 A- Z- J. }2 `5 i( Z: U
        {/ m& _3 P; U2 z+ `& C  W9 A) E* }
            m_ClientNetConfig.wClientPackSizeArray[x] = 0;: {! I' L/ n" W' V! a
            m_ClientNetConfig.wServerPackSizeArray[x] = 0;
    * T0 ~: D8 G" q& L& Z    }
    * e, j8 N1 B& |7 c0 R% i, @4 j}</P>
    ( V) q% `3 j7 Q6 A2 w6 F6 r. Y9 U
    <>7 G7 [# b0 I9 X1 r" _2 C, j
    //-----------------------------------------------------------------------------
    ! @* j$ T" T) B! N9 m// Name:   |& }+ I. v. f# b$ v0 ^8 I" V
    // Desc: 3 L9 c1 A: J, @* W+ E
    //-----------------------------------------------------------------------------
    4 w2 A0 x, a( T3 a6 jHRESULT CMazeServer::Init( BOOL bLocalLoopback, const CMaze* pMaze )& R" f* M, W2 X- v8 J
    {" X* H4 O; ], {/ L/ @; ~% e$ J
        m_bLocalLoopback = bLocalLoopback;6 f! c' ?# n( X# H
        m_pMaze = pMaze;
    3 ]) a' v! V2 C& o8 A' G. J; Y# J    if( m_pMaze == NULL )
    0 _$ T+ g/ [0 m. y7 D4 s' T        return DXTRACE_ERR( TEXT("aram"), E_FAIL );</P>- y( K. J1 a  o5 q+ q0 H
    <>    // Grab height and width of maze7 G$ @$ w1 _  t& V# d
        m_dwWidth = m_pMaze-&gt;GetWidth();
    1 g: x* W/ l4 S; b; ?5 x/ |' o    m_dwHeight = m_pMaze-&gt;GetHeight();</P>
    * h3 y' j9 j/ r* j9 ]0 f<>    m_ClientNetConfig.dwMazeWidth  = m_dwWidth;
    6 A7 `3 [- b; s2 H    m_ClientNetConfig.dwMazeHeight = m_dwHeight;</P>
    3 ]- e& \& O* P2 J# k<>    // Validate size. Must be a power-of-2 times LOCK_GRID_SIZE. Compute the shifts.$ E  f, e1 L( _4 F# b
        if( m_dwWidth &gt; SERVER_MAX_WIDTH || m_dwHeight &gt; SERVER_MAX_HEIGHT )
    1 e+ p3 ^0 s. w6 @1 }5 {# W        return DXTRACE_ERR( TEXT("Maze height and width need to be less than 128"), E_INVALIDARG );
    2 G: T( K% K" z9 e6 e* p) L: G    if( (m_dwWidth % LOCK_GRID_SIZE) != 0 || (m_dwHeight % LOCK_GRID_SIZE) != 0 )* U% ~- I  e+ s3 b7 u" D
            return DXTRACE_ERR( TEXT("Maze height and width need to be divisable by 16"), E_INVALIDARG );</P>
    & l* [. R* a% G* ]% u# n* o<>    DWORD scale = m_dwWidth / LOCK_GRID_SIZE;
    * {  }3 P* t% J4 n6 e9 t& }    m_dwMazeXShift = 0;1 V2 r4 A5 m/ O2 ~0 F/ ]5 k. T* }
        while ( (scale &gt;&gt;= 1) )
    + o0 S9 _8 @, n  J6 t  U        m_dwMazeXShift++;</P>: ^, F8 A6 F- H
    <>    scale = m_dwHeight / LOCK_GRID_SIZE;
    8 o0 G* w" m: o4 D( A    m_dwMazeYShift = 0;
    # n) m2 I* j$ Q) d% O- T# r. y    while ( (scale &gt;&gt;= 1) )( a( b: f; s8 z) x
            m_dwMazeYShift++;</P>
    9 T: q3 C8 c% {% q<>    if( ((DWORD(LOCK_GRID_SIZE) &lt;&lt; m_dwMazeXShift) != m_dwWidth) ||
    4 x& X, L. M4 E2 E        ((DWORD(LOCK_GRID_SIZE) &lt;&lt; m_dwMazeYShift) != m_dwHeight) )
    % ~" m; e& c/ F9 i. p/ o/ T        return DXTRACE_ERR( TEXT("Maze height and width need to be power of 2"), E_INVALIDARG );</P>
    $ b# {$ I7 [5 g' c( {0 q; r) @<>    // Initialise the player list
    ! f  B! z9 ]3 A8 U    ZeroMemory( m_PlayerDatas, sizeof(m_PlayerDatas) );" y; l+ [1 n, \% P; U6 l; m9 R
        m_pFirstActivePlayerData = NULL;7 Y2 g+ q8 x  H5 C! ~# ^* }0 F
        m_pFirstFreePlayerData = m_PlayerDatas;
    ; o5 C9 @# `* Z, D    for( DWORD i = 1; i &lt; MAX_PLAYER_OBJECTS-1; i++ )
    1 k3 C8 r5 S* j    {8 O. @: R, w# J: U( ?+ Q& W
            m_PlayerDatas.pNext = &amp;m_PlayerDatas[i+1];7 H6 z/ i6 d- y, I5 a2 I! [
            m_PlayerDatas.pPrevious = &amp;m_PlayerDatas[i-1];# k. ?$ P1 F4 c
        }</P>
    . x" W; w- U0 f: j/ d<>    m_PlayerDatas[0].pNext = &amp;m_PlayerDatas[1];
    4 Q' i; j6 X; o3 i9 T    m_PlayerDatas[MAX_PLAYER_OBJECTS-1].pPrevious = &amp;m_PlayerDatas[MAX_PLAYER_OBJECTS-2];
    , g, a$ M' J0 G! c4 C8 I4 r( T    m_dwActivePlayerDataCount = 0;- c; t2 f6 M/ Y; B2 E
        m_dwPlayerDataUniqueValue = 0;</P>
    2 ~+ N9 ~8 k5 f" u- U; V* t2 m<>    // Initialise the cells# o& {" [( O  k* a( F) J
        ZeroMemory( m_Cells, sizeof(m_Cells) );
    6 s# ^* C2 f( Z- T! W- \4 D    ZeroMemory( &amp;m_OffMapCell, sizeof(m_OffMapCell) );</P>; \! Y' T6 n/ I1 Q: c- |
    <>    return S_OK;  `# V4 a6 P' Y
    }</P>
    2 M! R4 I& G, b! y  A/ {3 w$ |+ K) K! K
    <>
      r/ c1 Q3 L: Q; Z//-----------------------------------------------------------------------------; y* X) V8 g* d6 y2 @1 Z1 [
    // Name: & y* _9 ?9 D, f# r! U7 b, c; C
    // Desc: % }- c1 z/ v) s: S: w/ m
    //-----------------------------------------------------------------------------
    ) Y, V. t, ]9 r. p+ h. kvoid CMazeServer::Shutdown()1 I5 F9 Q/ f& G& d
    {
    ) e4 Y9 I& u( o; x' W}</P>
    ) X+ f1 n1 Z3 h+ P- b% U. g( ~' C2 U% o! p# C; B
    <>& j0 W: `8 Y6 ?
    //-----------------------------------------------------------------------------! _/ z* ]0 D* E1 G  ^* m# y" z0 _1 v3 y
    // Name:
    % N3 \1 q) F& ~* ?// Desc: 9 G) N% I8 y# F+ Y, C1 g& k
    //-----------------------------------------------------------------------------
    * O0 L& }' J+ _9 f, i6 U3 s9 Svoid CMazeServer:ockRange( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )
    ( m8 W* s4 U7 R* g, P5 ~{
    : o( D* W& S+ L/ k    m_LockGrid.LockRange( x1&gt;&gt;m_dwMazeXShift, y1&gt;&gt;m_dwMazeYShift ," u# Y& ?+ Q+ x1 t
                              x2&gt;&gt;m_dwMazeXShift, y2&gt;&gt;m_dwMazeYShift );
    7 ]+ a7 S( h* W4 P# ^}</P>
    1 U/ R7 f0 k- m
    8 h; K; o: ?5 M6 i/ b$ F* i: z- F. b<>% B! ^7 O" u% I4 j
    //-----------------------------------------------------------------------------& e8 q6 X4 n3 k  C7 f8 L5 z3 X
    // Name:
    * @" }5 V  c$ E3 b. ]// Desc: 2 u) q( Y% L! x5 U
    //-----------------------------------------------------------------------------  Q. z, |+ k: ~( e: ^1 O
    void CMazeServer::UnlockRange( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )4 W+ b7 g( r, {9 K
    {
    & w1 r8 q, o$ l# S    m_LockGrid.UnlockRange( x1&gt;&gt;m_dwMazeXShift, y1&gt;&gt;m_dwMazeYShift ,
    ) j7 Y; Z& m& q9 X  G1 x* z% |6 O5 j% `                            x2&gt;&gt;m_dwMazeXShift, y2&gt;&gt;m_dwMazeYShift );2 T: n7 L9 K0 }. ~# @) n4 w
    }</P>' d, w. K5 p. C; q( @
    ( z7 b3 M) t8 m( H1 A  m/ g7 T# i
    <>
    + ]% ?1 Z5 A5 @! s6 l' ~//-----------------------------------------------------------------------------
    6 w2 z* N$ B8 }7 T& [5 \* v// Name:
    * [3 K( a- w2 S2 i& s. H// Desc:
    : U+ j1 a7 v, R( j//-----------------------------------------------------------------------------
    9 G7 a$ {& ?4 q( j# Svoid CMazeServer:ockCell( DWORD x, DWORD y )
    3 g4 X- I- a) l1 J/ y# F{
    & d" `6 ~% K9 E5 c4 M1 U    if( x == 0xffff )
    ' H- }8 \; m* s0 S0 Q1 m3 W/ g        m_OffMapLock.Enter();
    % K/ [  |: J  r) Q7 G! t3 n" Y    else
    8 D) o3 X& S* r4 m        m_LockGrid.LockCell(x&gt;&gt;m_dwMazeXShift,y&gt;&gt;m_dwMazeYShift);
    ) w, G# }0 H. x. p/ K1 Y7 C" M; e}</P>. I- c1 X. {& I% C6 B' l

    " v6 r6 V* _) h+ S<>- r  p+ E# [" D- y# `% d. y
    //-----------------------------------------------------------------------------7 K1 n9 A6 r& |
    // Name: ! t# M  U$ _3 n  p# S$ L& s
    // Desc: : i$ s/ @8 ^" W  T# H# W) }
    //-----------------------------------------------------------------------------
      }& H+ V/ x' \+ |3 hvoid CMazeServer::UnlockCell( DWORD x, DWORD y )& L/ L0 |( j' ~0 ^) Y2 Q, q' K
    {
    ! C1 {; Q+ U; L# r, C( Q    if( x == 0xffff ); ?# R) y" N" ?; d
            m_OffMapLock.Leave();* K5 I5 K) ?: h
        else
    $ Z( i( m" D/ t/ |        m_LockGrid.UnlockCell(x&gt;&gt;m_dwMazeXShift,y&gt;&gt;m_dwMazeYShift);- S; ?* ~3 \0 s5 l
    }</P>
    ) S% ]8 @- b  |: X
    % L# r7 q" C- {( B7 `% D/ q<>7 u7 q* @* u9 x
    //-----------------------------------------------------------------------------
    : j) A, W$ b1 \! n) U4 Y// Name: ! Y0 h6 _4 y; @- j/ R8 E7 Z
    // Desc: ) i7 ~2 }& V0 w
    //-----------------------------------------------------------------------------
    7 }' }' \( \" i/ B8 Hvoid CMazeServer:ockCellPair( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )
    " ]6 B  D, |; c+ @{( O3 S* w* V& Q6 d5 J2 U  g, f) T
        if( x1 == x2 &amp;&amp; y1 == y2 )
      t+ _( s( q# b1 P    {
    8 K: L* o5 `  r" E. @        if( x1 != 0xffff &amp;&amp; y2 != 0xffff )6 ]( u( o" B  ?+ H: Y, r
                LockCell( x1, y1 );* e& a& |, ^. N% z
            else8 m6 I; V8 ~0 O
                m_OffMapLock.Enter();</P>
    6 g. K* e0 b% m1 ]8 }<>        return;
    ( ~- ]/ i; K  |( ]6 Q9 p0 U    }</P>
      M+ G: B3 j  f6 o& u<>    DWORD x1shift = x1&gt;&gt;m_dwMazeXShift;4 R3 _; T/ X) W* L  v. t1 `
        DWORD x2shift = x2&gt;&gt;m_dwMazeXShift;& v. y) ~$ f0 ^7 _2 r8 Q+ u+ n
        DWORD y1shift = y1&gt;&gt;m_dwMazeYShift;
    ) H" }8 ]/ y" z4 L  R' H  d0 ?    DWORD y2shift = y2&gt;&gt;m_dwMazeYShift;</P>
    7 w* G+ R/ c0 K% d6 _- J: Q0 I<>    if( x1 == 0xffff )3 _. ?- ~: W1 l( `" t) \# i4 T
        {5 u: H; t0 \' l+ O! v: a$ C. g
            m_OffMapLock.Enter();
    6 Z$ F) g' c+ P9 l# R1 i. B        m_LockGrid.LockCell(x2shift,y2shift);
    & w( u  [+ y6 S( C8 T0 u5 R    }- H( V3 F, d2 D( `' m; w4 X* I
        else if( x2 == 0xffff )
      P$ N8 O4 M/ _# f    {
    ' k) d2 u, l3 u        m_OffMapLock.Enter();
      G7 g. W* u1 S9 Z( J0 e% }        m_LockGrid.LockCell(x1shift,y1shift);( w& Z! P" |7 y- X  s
        }4 u5 S, i, H7 N: T# x0 O9 B
        else
    6 B9 s0 R8 t! z* K5 M3 S    {$ i1 @8 L$ n3 _; J) O" B
            m_LockGrid.LockCellPair(x1shift,y1shift,x2shift,y2shift);0 J7 A7 D& x8 |6 L- U& \% H
        }
    " m6 G! Q& r, B8 g$ I1 v! O4 [' F2 ?}</P>4 x8 N1 o% ]  v$ f% S

    ; n6 c' o8 x* ]& T<>
    : ^7 P. w3 J: z' T//-----------------------------------------------------------------------------7 X! t4 x& g% {! u$ p# j
    // Name: 5 G3 L2 Z0 `  h* P* [6 S/ U
    // Desc:
    ; C, I" F: X/ V4 h$ n( N) U//-----------------------------------------------------------------------------) J8 a5 o% x+ M0 ?
    void CMazeServer::UnlockCellPair( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )/ {7 [$ K3 J& w! R
    {
    + s: }& o/ ?( V    if( x1 == x2 &amp;&amp; y1 == y2 )" H$ u  I9 n: K1 G
        {
    3 f  n. ^# t5 D        if( x1 != 0xffff &amp;&amp; y2 != 0xffff )/ I: G- K8 n5 k: l5 y
                UnlockCell( x1, y1 );
    2 L( o. H+ R$ w        else
    1 ~7 x7 C! |2 i8 J1 I) u& v4 q            m_OffMapLock.Leave();</P>0 t2 F) Z% G0 V2 G, X
    <>        return;
    8 L2 s% b# }* U, f# ^% Y" c- A& n    }</P>% R" O; x8 ^' h: V" [' ?
    <P>    DWORD x1shift = x1&gt;&gt;m_dwMazeXShift;0 }- Y% s+ e0 q
        DWORD x2shift = x2&gt;&gt;m_dwMazeXShift;5 s. ~* {7 a$ l1 l8 @
        DWORD y1shift = y1&gt;&gt;m_dwMazeYShift;
    " w3 E' p& A; Z# Z! B    DWORD y2shift = y2&gt;&gt;m_dwMazeYShift;</P>: ]! F# U2 k1 D! \( w
    <P>    if( x1 == 0xffff )
    " T  g. }* R% |1 L6 r    {
    ( a! [! ]2 J$ T0 @        m_LockGrid.UnlockCell(x2shift,y2shift);! d. l5 L+ x" k; O  u( Y' _' e
            m_OffMapLock.Leave();$ G1 W, G' b7 L0 ^* _% x
        }8 l$ U% T7 c, h- B# @
        else if( x2 == 0xffff )1 U/ Q& k" C3 ?% D- B8 V
        {$ P4 m# b  W4 l. L3 N) l: G6 `8 Z0 U
            m_LockGrid.UnlockCell(x1shift,y1shift);
    7 H/ [" G' f# w& B1 F        m_OffMapLock.Leave();! J2 Y& q" ^- S% r, U) W! q; U6 F
        }
    2 `6 T0 P) i" W- P# O, M* O; w    else
    9 S- |, e6 b+ u3 g7 i    {5 o; s. d8 H# p- Z' w3 r+ }1 w
            m_LockGrid.UnlockCellPair(x1shift,y1shift,x2shift,y2shift);0 w1 |7 _& K! w( i
        }
    3 U6 o& l! T8 s$ P/ {' M}</P>
    4 K3 i( j  A3 Y+ ?" F
    3 d+ s* e0 m, k<P>5 A  A% m$ k6 D
    //-----------------------------------------------------------------------------; `7 \4 F3 k3 C5 F# K, C2 x" _
    // Name:
    ; ?& c" z; s, [' |% M" h+ D// Desc: 4 Q5 x1 x- t. m
    //-----------------------------------------------------------------------------
    6 R1 Z( b1 c+ F! x6 s6 ovoid CMazeServer::OnAddConnection( DWORD id )
    - ^& p5 ~9 S, J  i( Q, q{
    ) M) f& g' y1 s9 U) e/ N    m_AddRemoveLock.Enter();</P>
    - i* |" S4 O$ t* y<P>    // Increment our count of players
    # o+ f! ]1 L, p$ T( K4 z: ~    m_dwPlayerCount++;
    6 G! D1 q: j: I( S" x    if( m_dwLogLevel &gt; 0 )
    " U5 I, N  S% z, e% X    {
    ! B7 [1 f9 z! G+ J+ X/ f$ I( p4 Y% ]* R! h        ConsolePrintf( SLINE_LOG, TEXT("Adding player DPNID %0.8x"), id );
    / l6 v2 m; m# ]' T. O        ConsolePrintf( SLINE_LOG, TEXT("Players connected = %d"), m_dwPlayerCount );
    / U# a# t; {, i    }</P>8 ]' ^3 ?  R3 M3 h# d: V; u% c% s% p1 M
    <P>    if( m_dwPlayerCount &gt; m_dwPeakPlayerCount )
    8 k0 e5 S8 ]2 f        m_dwPeakPlayerCount = m_dwPlayerCount;</P>' d. i% m, ]/ G
    <P>    // Create a player for this client7 h% x. b/ h7 Z/ L4 o6 C
        PlayerData* pPlayerData = CreatePlayerData();: K5 F# |' x4 P, ~+ A
        if( pPlayerData == NULL )* z: q8 I% D$ n
        {
      g8 }9 Q* a# N3 y0 B3 m& U        ConsolePrintf( SLINE_LOG, TEXT("ERROR! Unable to create new PlayerData for client!") );
    7 H, g. F8 e$ m! K        DXTRACE_ERR( TEXT("CreatePlayerData"), E_FAIL );  n2 j4 E! u& w+ i! {
            m_AddRemoveLock.Leave();0 M8 b6 b/ |2 U6 F. V; T
            return;
    * ?/ y( M) Z' V    }</P>6 ]* X; }6 x2 z; m* M- ^3 }
    <P>    // Store that pointer as local player data. m5 e/ H$ T3 Z
        SetPlayerDataForID( id, pPlayerData );</P>
    & V7 T# o2 \" e- f+ @<P>    // Grab net config into to send to client, t4 |( D0 V7 U
        m_ClientNetConfigLock.Enter();
    : I! r( q  c9 t0 `) E( m$ a    ServerConfigPacket packet( m_ClientNetConfig );
    ; a5 F7 J/ b  J+ j    m_ClientNetConfigLock.Leave();</P>9 b/ |7 n- W( z, P& i
    <P>    // Send it1 [" V7 ^6 K; q5 ?! g" ?3 N4 o- S
        SendPacket( id, &amp;packet, sizeof(packet), TRUE, 0 );</P>" X  U+ X% `7 h
    <P>    m_AddRemoveLock.Leave();/ X, Q1 T6 e! b6 o9 g4 I6 k# {! i# O
    }</P>
    3 g1 v8 S+ n$ N* |4 M0 |. e+ O1 r& c- ]) l0 _2 M' }
    <P>
    & F$ n( n% ~/ R% M9 S9 k//-----------------------------------------------------------------------------
    : Q* P& d) q; r  G% U" i8 ?// Name: $ E, V; ^5 j- F5 z0 ?
    // Desc:
    * [$ K6 |- k  L8 }//-----------------------------------------------------------------------------
      u2 T" g8 f5 `* `* w4 `void CMazeServer::OnRemoveConnection( DWORD id )
    - L! ^) E- K" a3 R* l5 G" Y{
      f# ]5 z% K3 ~( M  u    m_AddRemoveLock.Enter();</P>1 u( Y) o$ V, y6 Z
    <P>    // Decrement count of players
    . _% W5 n6 V# h9 V* y  @8 ?    m_dwPlayerCount--;</P>; |$ I) @0 B. r3 O5 S- V
    <P>    if( m_dwLogLevel &gt; 0 )2 O8 Y7 q* V. |  H
        {
    ; [1 v# ~; n5 p9 I( h- f        ConsolePrintf( SLINE_LOG, TEXT("Removing player DPNID %0.8x"), id );
    . _( l1 e( `2 l        ConsolePrintf( SLINE_LOG, TEXT("Players connected = %d"), m_dwPlayerCount );( N* ]& B+ i2 N/ Q! i$ z
        }</P>
    1 G2 D* S& l+ ]8 S: R# j& S7 R$ x<P>    // Find playerdata for this client
      p$ S6 x+ ?) N0 u( ~    PlayerData* pPlayerData = GetPlayerDataForID( id );
    0 e: r3 V6 \5 r    if( pPlayerData != NULL )
    7 R, i- }' E# p. y    {
    0 v% G" i+ O. D1 E' d' ~& e        // Destroy it& |: n+ r- t+ L3 F) e0 n3 d5 r$ d7 x
            RemovePlayerDataID( pPlayerData );
    % ]# x' I+ h9 _  Q; n1 k# \        DestroyPlayerData( pPlayerData );
    ; B! L1 l' I  J    }</P>2 [0 ~' z+ w3 H8 n7 O" ^5 z6 K8 e+ V
    <P>    m_AddRemoveLock.Leave();
    9 u: c& d- k- a+ q5 z2 u7 b}</P>- P3 s# p; n" V( h# M
    ! ^" Z5 n: p' F; b: |
    <P>
    ; i$ `% c/ d6 a5 T  l//-----------------------------------------------------------------------------2 _4 w3 _& u- R% f
    // Name:
    8 h* l2 @; z$ t: x2 d// Desc:
    ! G( j  O! X& j1 X' l6 S) y//-----------------------------------------------------------------------------
    1 W/ b/ `; q/ q5 lHRESULT CMazeServer::OnPacket( DWORD dwFrom, void* pData, DWORD size )1 y/ ]% J5 J  Z$ v' z
    {* h8 i# n5 a9 `7 ]  V" l; k# P. Z
        BOOL fFoundSize = FALSE;</P>" k9 w7 v- W6 W( C/ d: I! `$ D
    <P>    // Increment the number of thread we have in this process.
    8 c) J1 t  E5 ?/ ?- H9 c    m_csThreadCountLock.Enter();</P>
    & n7 i. v2 r- o0 J$ D. o5 J4 g% c<P>    //Get the start time of when we entered the message handler.
    4 N  \; I; L% v! M( ^    FLOAT   fStartTime = DXUtil_Timer( TIMER_GETAPPTIME );</P>* O% x2 U2 \+ {$ k1 d- }2 R
    <P>    m_wActiveThreadCount++;$ G" [: T+ [; F% H, Y1 Z( W
        if(m_wActiveThreadCount &gt; m_wMaxThreadCount)! B: w+ C4 |# R5 x& U: h! d9 Q) p
            m_wMaxThreadCount = m_wActiveThreadCount;
    # X% F: t$ g4 A# ~2 x2 d8 }, y    - j- Y. ^9 C  S8 u# h! p
        // Calculate and average.
    - T# s1 X/ v6 A7 R+ Q    FLOAT fdiff = m_wActiveThreadCount - m_fAvgThreadCount;: M6 E: e' C0 ~3 I& M
        m_fAvgThreadCount += fdiff/32;; f5 ]5 C3 Q, X
        " u! q; \4 _, @6 ?6 G
        m_csThreadCountLock.Leave();</P>
    . w! B/ h' z$ V% ~+ c<P>8 f! T7 g/ x# q- f! G
        ClientPacket* pClientPack = (ClientPacket*)pData;% G. R* U$ G* M9 [
        switch( pClientPack-&gt;wType )- X- ^9 c1 u  C# m1 y
        {
    6 M5 Z# I  c" v        case PACKETTYPE_CLIENT_POS:
    , f# j# |* j+ E' f) D- R5 B7 u            % o. c6 O) q; a% ~# ^/ L& u  c
                // Check to see if the packet has a valid size. Including 7 K1 I( o+ c# n5 @
                // the custom pack size.
    - C7 Y# F" S) w' Q7 C1 b5 q            if( size &lt; sizeof(ClientPosPacket))) a& K) N! o; m1 m) h  h
                    fFoundSize = FALSE;
    . `5 M4 `% {; ~3 \$ j            else if( ! IsValidPackSize(size - sizeof(ClientPosPacket)))
    : b& V$ \, k0 A4 R  s% y& z9 g. L                fFoundSize = FALSE;
    , `1 {# v! W$ L( E            else
    % {, p* H. s8 z7 o; R5 r& W4 ?* R                fFoundSize = TRUE;</P>
    * [: X, C# e% s" K. c% s<P>            // If valid sized packet, handle the position.: d- K4 @* f4 h& l
                if(fFoundSize)
    ' e* E8 o. w1 Q8 @/ \0 \                HandleClientPosPacket( dwFrom, (ClientPosPacket*)pClientPack );' {- h3 y1 e' `0 p; E
                else
    1 b) c4 W8 P/ @* T/ a" k& H* o" K9 N                m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );</P>
    $ k: C  `: k! f<P>            break;</P>
    ' {* U+ [2 I' E- R<P>        case PACKETTYPE_CLIENT_VERSION:
    , R: I& ^5 C$ o2 B% ^0 d2 h            if( size == sizeof(ClientVersionPacket) )0 z! X8 ]6 [) ~# F' Z, Y4 I8 i
                    HandleClientVersionPacket( dwFrom, (ClientVersionPacket*)pClientPack );
    ( O4 X6 A  d; C* ^8 B            else3 }: u+ p4 ]$ d' b5 q4 C- K: A
                    m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );  [  F7 {. z' I( e+ x
                break;</P>
    . z% M7 T9 X4 ^( Y<P>        case PACKETTYPE_SERVER_CONFIG:</P>
    3 p% g& x; a  w) M9 o6 K7 d# G<P>            // Server config packet sent to all users (including server). Just ignore and continue.</P>  M/ [- J% ?1 B& O8 g
    <P>            break;: X) \" J9 B' j
            default:
    2 O, ^) u4 z6 t2 I2 ~            HandleUnknownPacket( dwFrom, pClientPack, size );+ e! E% m- ^' R4 B
                break;$ B1 U- I' q. K
        }</P>
    " K) b) l+ }5 l. ]6 h<P>    //If the user wants to hold the thread, Sleep for given amount of time.1 w4 e8 M' ?4 H$ E  R7 p8 s2 U
        if ( m_dwServerThreadWait &gt; 0 )" x4 D0 T* a5 `3 f/ L
        {
      q1 d" Z. h* X+ s; K3 V+ P        Sleep( m_dwServerThreadWait );
    " s2 O& h1 e; [( y5 O! ?    }0 g+ Q4 h( K$ l7 e7 d& g. t
       
    4 P) }) v: `  y: U" u1 b    // Retrieve thread data for this process.
    ; u1 G" e) e) r5 u; [* O    m_csThreadCountLock.Enter();</P>" B5 o4 d& ^" f6 {0 u3 x& B
    <P>    m_wActiveThreadCount--;</P>
    # \" f% e7 X% G<P>    FLOAT fDiffTime = (DXUtil_Timer( TIMER_GETAPPTIME ) - fStartTime) - m_fAvgThreadTime;
    / z6 o$ _6 S) T, t    m_fAvgThreadTime += fDiffTime/32;</P>  k3 Y' X( B" G, Y) y$ m2 ]
    <P>    //Get the Max time in the thread.
      Q; Q- j9 q) b    if ( fDiffTime &gt; m_fMaxThreadTime )6 w/ H! w: W8 Q/ N1 A* \2 n
        {
    - t3 `2 l, p& V        m_fMaxThreadTime = fDiffTime;
    % e& K, b2 X6 |7 p    }</P>
    ) w# T& A) n. x/ q! p/ S<P>    m_csThreadCountLock.Leave();</P>
    * E" Q/ |# j# k- R7 N2 R<P>    return S_OK;
    * q1 S" @& X( T& ]  D3 u  Y}</P>
    4 Z8 |1 i5 ]2 I. c0 q7 U& N/ a. p
    5 J8 _' e7 J2 X: ?" H<P>//-----------------------------------------------------------------------------
    ' ^3 `. V0 C7 o// Name:
    " j, q( u! j; T" q# b) t6 c$ S% g. H// Desc: 6 o$ B( `# l& `9 |* r) J
    //-----------------------------------------------------------------------------
    2 |, h! G4 ?$ l( w9 W7 s+ U# e  L- kBOOL CMazeServer::IsValidPackSize( DWORD dwSize )
      f( i5 \9 Q3 T4 \1 Z9 Y8 a7 E{
    5 z8 J( b  G  N9 v9 S& l" ^    BOOL fFoundSize = FALSE;
    1 z5 f$ j4 l: M# [2 q. m' n    BYTE ubPackLocation = m_ClientNetConfig.ubClientPackIndex;( a: Y% w+ y. O& ?3 |9 h: v# V+ u
        : h$ W. a! @6 n
        // Check through the array of valid pack sizes.9 @: n9 p+ r% `3 H5 Y, P- K
        if(dwSize != m_ClientNetConfig.wClientPackSizeArray[ubPackLocation])
    3 l0 y' I8 b4 K7 @    {4 s' P( Z8 Q/ }6 P6 M! E" M
            for( --ubPackLocation; ubPackLocation != m_ClientNetConfig.ubClientPackIndex; ubPackLocation--)7 E9 b) t4 g6 d. X3 {7 P$ J- Y
            {
    - U! h* J; U. z6 ?9 I5 ^            if(dwSize == m_ClientNetConfig.wClientPackSizeArray[ubPackLocation])4 }$ z3 ]0 q# \. e- [8 X6 A
                {+ R' d/ ^) |- K* C' O6 l
                    // Found valid size in the array.
    3 ~) ?  c5 r: @                fFoundSize = TRUE;
    3 ^/ B1 C, V6 y7 V; i+ d% Q. c                break;) A/ F2 c1 f5 p3 S
                }
    3 B4 q  y: R- M; ?            if(ubPackLocation &gt;= PACK_ARRAY_SIZE)  ubPackLocation = PACK_ARRAY_SIZE;  //Wrap the array.! ?  j; j( T& _0 v5 \7 a/ j. b8 U$ C
            }* o/ h5 M* S% Y6 c* V) p' A& e5 L
        }% ]% ^0 ~  r; c  h- J( ~) c+ l
        else
      l- e* }$ _2 m* k, L5 D4 H( V3 K4 o    {$ I  w$ [2 c! A! P0 ]3 |
            fFoundSize = TRUE;
    % B) _* h) c$ X2 Y1 d    }</P>
    ! ]: I6 d( \: D2 R  k1 N<P>    return fFoundSize;
      {! [9 f5 u7 J, h* Z2 w}</P>
    / c5 d% }- j" S<P>! w4 A8 ^# P* B% u0 i
    //-----------------------------------------------------------------------------' N& G! |4 q& e  Y1 J  E3 ?- q) ~) H
    // Name:
    + Y; P3 m, y4 m! j// Desc: ) i& p8 e# q& H# T
    //-----------------------------------------------------------------------------9 g8 a  O) `: l$ l* k/ }' Z
    void CMazeServer::OnSessionLost( DWORD dwReason )  e/ ]- B; `8 m& E9 f: M0 E- V
    {
    4 y. H- o+ ^& H& k. C% c4 x& P    ConsolePrintf( SLINE_LOG, TEXT("ERROR! Session was lost") );( |- s, r" r) \8 d8 J  @: {
    }</P>
    6 o: ]9 f3 Z7 J, A7 k8 m' c: i/ r# j" x9 ~& T' f2 R
    <P>" Y# J' p0 v  n  h
    //-----------------------------------------------------------------------------  f1 j% }! I2 C2 R! }5 g3 G
    // Name: : H+ v0 P. h. X7 j) Y- w
    // Desc:
    ( p5 g0 c( E) w2 G: i3 l- w//-----------------------------------------------------------------------------3 g! J% ~0 Z1 a7 k; \! ?% c  Y
    PlayerData* CMazeServer::CreatePlayerData()/ \5 U7 D/ \6 w6 _" `* Q" U7 e( ~0 f
    {
    , {$ v; b) _# e- C! m# J8 g5 W$ F  Q    m_PlayerDataListLock.Enter();</P>
    ; X. W. g8 V. {/ D6 ^<P>    // Grab first free player in the list1 K0 E; X9 u) T. z) P; G
        PlayerData* pPlayerData = m_pFirstFreePlayerData;</P>
    3 v. B* q8 I# Q5 t/ ~. [3 a. y<P>    if( pPlayerData )
    6 X6 g& l) E: r" k: {$ a" H2 O    {- ?- D" l0 T  e3 }) Q7 g
            LockPlayerData( pPlayerData );</P># p/ O% q8 s8 ~, O
    <P>        // Got one, so remove it from the free list
    ) a3 m2 a4 @: V% ^. s" t        if( pPlayerData-&gt;pPrevious )5 B( ^' V7 {. K0 z2 C0 b" G+ Y
                pPlayerData-&gt;pPrevious-&gt;pNext = pPlayerData-&gt;pNext;
    2 }7 \" }+ V% K+ r        if( pPlayerData-&gt;pNext )
    . [% }" P9 Y# D5 @* S9 i2 s            pPlayerData-&gt;pNext-&gt;pPrevious = pPlayerData-&gt;pPrevious;
    3 X0 h  B2 S1 D+ B: c* M5 X: n        m_pFirstFreePlayerData = pPlayerData-&gt;pNext;</P>* Y% n: H/ }& T9 M5 V' a+ |
    <P>        // Add it to the active list) c4 f) L, O& I
            if( m_pFirstActivePlayerData )
    9 c& C% ~7 @0 w) V! S7 a3 y: d            m_pFirstActivePlayerData-&gt;pPrevious = pPlayerData;
    ' z/ R$ i2 _1 Z; s! q+ @1 ^( ^        pPlayerData-&gt;pNext = m_pFirstActivePlayerData;$ ~& [& |$ `4 T$ f) M
            pPlayerData-&gt;pPrevious = NULL;
    1 n% ^/ y0 W; o0 N# m  k        m_pFirstActivePlayerData = pPlayerData;</P>7 S( l  x8 H9 c4 e
    <P>        // Update count of players
    " T6 W& M9 @- M' q8 h        m_dwActivePlayerDataCount++;</P>
      h1 ~+ [/ m4 `' Y9 R& y# f' z6 i<P>        // Generate the ID for this player7 M# E! @+ T0 M! h8 t  O9 B
            m_dwPlayerDataUniqueValue++;+ k1 w+ o: A5 n6 J
            pPlayerData-&gt;dwID = (DWORD) ((pPlayerData-m_PlayerDatas)|(m_dwPlayerDataUniqueValue&lt;&lt;PLAYER_OBJECT_SLOT_BITS));</P>
    - [" U# v* [. T) D5 }5 h& b<P>        pPlayerData-&gt;pNextInIDHashBucket = NULL;: b0 ]3 k+ j+ v' N- K
            pPlayerData-&gt;NetID = 0;* ~0 \+ K  e. X
            pPlayerData-&gt;dwNumNearbyPlayers = 0;</P>8 M# [1 G, `) J( @6 z. G) C+ J
    <P>        // Insert into the "off-map" cell; \6 [& }) J& X. N" R0 x
            pPlayerData-&gt;fPosX = pPlayerData-&gt;fPosY = -1;
    $ q- e& H! N* B/ A        pPlayerData-&gt;wCellX = pPlayerData-&gt;wCellY = 0xffff;; ?7 l1 _; g$ z9 B
            m_OffMapLock.Enter();- @. R2 g1 T6 t5 s  [
            pPlayerData-&gt;pNextInCell = m_OffMapCell.pFirstPlayerData;
    " Z+ o' Y( [9 S  o- E) ?        m_OffMapCell.pFirstPlayerData = pPlayerData;
    ( d! `2 O; \# C! M$ H        m_OffMapLock.Leave();</P>0 E$ {' g/ F  }# p/ {" [
    <P>        // Mark as active
      o( r# n! O# R& {        pPlayerData-&gt;bActive = TRUE;</P>
    - s& l: l: I1 S, f3 A8 A<P>        UnlockPlayerData( pPlayerData );/ |/ v: g! [# W6 O2 e
        }</P>. c3 ^  e( |0 r9 i0 f/ g5 U
    <P>    m_PlayerDataListLock.Leave();</P>
    0 s/ U4 C% m: t( F) f<P>    return pPlayerData;
    6 k- ~3 k8 Y0 q8 N* ~3 T4 L}</P>- R5 p( W; y6 f
    : D# ^1 W  s! G& T
    <P>
    - W6 c! I) `& Z. T9 i* O- U//-----------------------------------------------------------------------------, v( G3 I. X/ c% t& D
    // Name: - p0 G! q4 T* N  u6 H
    // Desc: 5 m" b+ J% q$ }9 x. r
    //-----------------------------------------------------------------------------. K, b: y% s# M; U, q1 s
    void CMazeServer:estroyPlayerData( PlayerData* pPlayerData )
    ) W4 a( X; w8 e2 I9 j& i{
    8 J/ p$ E$ _  u/ v+ m3 l    m_PlayerDataListLock.Enter();& \8 b" {  S. f/ S. W
        LockPlayerData( pPlayerData );</P>: f; l  x$ }- _' R  @. w4 v
    <P>    // Remove the player from its cell
    ) d7 x2 W8 p8 K3 r) D    RemovePlayerDataFromCell( pPlayerData );</P>
    0 M1 z0 V) U7 j6 [8 ?2 D<P>    // Mark as inactive
    $ Z+ |: Y& f! v7 c, z    pPlayerData-&gt;bActive = FALSE;</P>
    * ]% F0 D6 G2 L6 m<P>    // Remove player from active list
    & A, C/ b4 ~) f& [    if( pPlayerData-&gt;pPrevious )7 [1 `7 u7 F2 P7 C' Z: A
            pPlayerData-&gt;pPrevious-&gt;pNext = pPlayerData-&gt;pNext;
    % |3 s' s2 r7 Q4 W+ u    if( pPlayerData-&gt;pNext )8 h) u& e) k, d6 p- n
            pPlayerData-&gt;pNext-&gt;pPrevious = pPlayerData-&gt;pPrevious;</P>
    / M- B8 ^% Q7 _8 o# H/ z* S, N<P>    if( m_pFirstActivePlayerData == pPlayerData )  n* y9 a) f+ A3 u* L
            m_pFirstActivePlayerData = pPlayerData-&gt;pNext;</P>1 \; ]" j( I1 b' H
    <P>    // Add it to the free list$ e, Y0 i$ V. y& e8 N
        if( m_pFirstFreePlayerData )9 Z: t7 _! {! d5 k7 c
            m_pFirstFreePlayerData-&gt;pPrevious = pPlayerData;2 T0 y% O& I  n" {) Z: ]  ]0 u% M
        pPlayerData-&gt;pNext = m_pFirstFreePlayerData;" s" i8 `" L; J- ]: t7 {
        pPlayerData-&gt;pPrevious = NULL;
    7 z0 j, r  q( P' S- u6 S    m_pFirstFreePlayerData = pPlayerData;</P>9 H4 k/ T. J' u8 W* j( I
    <P>    // Update count of players3 P( a$ `& H& u  g  Y1 C
        m_dwActivePlayerDataCount--;</P>4 B1 W2 u1 O5 `2 t
    <P>    UnlockPlayerData( pPlayerData );
    ) I% {1 j; f, L* E( _( Z8 p. |    m_PlayerDataListLock.Leave();2 O, r; g; b* C5 t# p
    }</P>" J' O2 d4 \7 u. o. r% A: A

    . X" o/ {, P( |$ q, a- `6 l( ?9 x<P># f. C0 ?8 d& N# t, E0 o3 T
    //-----------------------------------------------------------------------------' Z# n2 g/ F; K: ^& P
    // Name:
      N4 ]$ Y# Z" g1 i8 W6 i  D// Desc:
    & T7 c" E/ v' C; T% p//-----------------------------------------------------------------------------
    # r0 `1 C. w( C- ~1 D9 \* gvoid CMazeServer::RemovePlayerDataFromCell( PlayerData* pPlayerData )
    ) o, e# R3 E2 e3 v+ m{
    / U' |. w% [4 X$ a- ?" A    // Lock the player
    ' M" A0 i5 `3 \, {% R; H( m    LockPlayerData( pPlayerData );</P>* z( g1 ^2 F% w, S- I
    <P>    // Lock the cell the player is in
    7 U. P' A3 K, C& [    ServerCell* pCell;% Y% T8 j' r! y+ l( x. k2 E
        if( pPlayerData-&gt;wCellX == 0xffff )0 e; U( }( w3 I; |2 d
        {, `: J* z% e) T7 i. D
            m_OffMapLock.Enter();
    ' ]+ V5 F/ F( ?, C% c, F1 p( m; }' `        pCell = &amp;m_OffMapCell;
    ) Y" w9 Q" D: H$ M2 `    }5 p9 P' u" r3 j, J: a( }$ J6 H
        else3 _+ I3 ]! E  P( ]8 S/ n- h+ `
        {* R. {: K% i8 w9 G! V. }0 Y' u. Z
            LockCell( pPlayerData-&gt;wCellX, pPlayerData-&gt;wCellY );. S+ V+ V! X  u2 a4 A0 V
            pCell = &amp;m_Cells[pPlayerData-&gt;wCellY][pPlayerData-&gt;wCellX];
    , k$ X/ o" G% Z7 T' E    }</P>2 J- c; u7 ^/ J9 m1 v- t& s! j7 W& [
    <P>    // Remove it from the cell$ v1 y  H) L9 @# E. _) V
        PlayerData* pPt = pCell-&gt;pFirstPlayerData;5 g( g: r0 O+ p8 n+ i1 W
        PlayerData* pPrev = NULL;3 e- K1 |; Y* s- w
        while ( pPt )1 O2 h! |8 ~9 P7 S  F
        {
    5 t9 H, d; T- X+ a" ]4 s" l, e        if( pPt == pPlayerData )9 r6 U0 ^  r$ a' l
            {: K* x3 ^% Z  n
                if( pPrev )6 J1 ^  M5 ?  O# l
                    pPrev-&gt;pNextInCell = pPlayerData-&gt;pNextInCell;: C: T5 R/ `5 o* V% k) p, Y0 n: o
                else! I% e- l6 i+ @$ Q  L0 |6 t; g3 J+ V
                    pCell-&gt;pFirstPlayerData = pPlayerData-&gt;pNextInCell;</P>
    0 u2 E7 W2 @) l  p<P>            pPlayerData-&gt;pNextInCell = NULL;2 y" R  J, ]- m0 E+ j8 g! C
                break;- R* j- P& ?+ @+ W$ i+ V; F
            }3 Y5 R. ^  x: s0 b/ B+ O
            pPrev = pPt;
    * u" x8 r0 t8 d8 [$ [        pPt = pPt-&gt;pNextInCell;2 I2 H8 u# z1 M1 b% p1 x
        }</P>/ c4 O4 ^8 v' ]2 @
    <P>    // Unlock the cell
    - H  P5 ]2 X, {' N4 n6 [; K    if( pPlayerData-&gt;wCellX == 0xffff )' ]2 i7 ?4 o3 Y2 e
            m_OffMapLock.Leave();4 a( S, Q4 r# W* I
        else
    % \% @' B( L+ U9 n        UnlockCell( pPlayerData-&gt;wCellX, pPlayerData-&gt;wCellY );</P>
    5 F4 J$ ^4 p( ~<P>    // Unlock the player
    ' Z, _; a$ j5 p8 Y  N0 l    UnlockPlayerData( pPlayerData );* _& L& W; A: a' Y8 x/ a3 @
    }</P>
      H) P& n7 X5 i, D) U7 R% `
    # Z7 [. q- z% ^/ M) j2 q<P>3 w. b: h: V: t( {3 g
    //-----------------------------------------------------------------------------
    : P/ Q/ L6 ^6 F- c: b// Name:
    " L% ^  T6 O. O8 F0 N// Desc: 3 y! \$ a$ m% L2 d) S0 J
    //-----------------------------------------------------------------------------
      u6 S% y* ]1 O1 k. d3 cvoid CMazeServer::UnsafeRemovePlayerDataFromCell( PlayerData* pPlayerData )
    / t7 ~8 m" Y3 y  I{+ c7 P  o& u- u- \5 \: U. k
        ServerCell* pCell = GetCell( pPlayerData );* I( c% |( s, N8 Y( o& E" [
        PlayerData* pPt  = pCell-&gt;pFirstPlayerData;4 r: q8 D+ m; O
        PlayerData* pPrev = NULL;- T7 O8 w8 b" t' {/ P# H
        while ( pPt )% p  L3 Y7 w* n8 b0 D) A( j
        {% G2 V' O9 u" w6 B# h6 `0 d! H
            if( pPt == pPlayerData )% m) E: l# ^  H. F4 e8 U0 a* k# ?
            {
    : n' F" Y0 }* c( f: k6 H            if( pPrev )
      r4 v$ P4 _8 X: V; k( H                pPrev-&gt;pNextInCell = pPlayerData-&gt;pNextInCell;  @* [! I$ ?$ n3 C( z) u. i
                else$ o/ D4 Z: h" @
                    pCell-&gt;pFirstPlayerData = pPlayerData-&gt;pNextInCell;0 u: D3 |8 ~, Q7 z# y0 U+ P
                pPlayerData-&gt;pNextInCell = NULL;
      @" w" B2 u( b* j5 n$ T; \            break;" U' M" x$ G3 s- o: o. x8 H
            }" @( x/ r. ]* I, z
            pPrev = pPt;
    ( y& N& V( A& S" m        pPt = pPt-&gt;pNextInCell;; r0 B) U/ Q9 Y5 f
        }. e9 h- Y+ v' H" r) F
    }</P>( Q2 g. a0 l9 w" @$ Z

    7 Y* E* V. A) _7 Z% C<P>
    ' {/ @! t) s4 u0 K5 ?( U1 C//-----------------------------------------------------------------------------& z0 Y; v7 v: N" |0 u, a7 E
    // Name:
    # }' h! j4 N9 ]! m! z// Desc: ; @- _( D! u; Q6 @6 W
    //-----------------------------------------------------------------------------
    3 v4 h" ]3 o4 {( c# x4 Fvoid CMazeServer::UnsafeAddPlayerDataToCell( PlayerData* pPlayerData )7 o6 A; i# B$ j" U' k! y
    {" u# s1 t3 f; F$ [. x4 S3 {; `
        ServerCell* pCell   = GetCell( pPlayerData );
    2 ]9 G2 }9 ]0 J" s! b' t; b+ {. U9 M    pPlayerData-&gt;pNextInCell = pCell-&gt;pFirstPlayerData;; T/ I* k" V1 I! k+ B+ h
        pCell-&gt;pFirstPlayerData = pPlayerData;# O) p, w2 a) y6 F6 Y6 Z
    }</P>* E7 [2 T1 O* g* Q, t* ~4 [, Z
    ( q* J; I6 K3 K5 O3 L4 }8 F- J' R
    <P>
    . x# e  }* N8 p# y9 w. T//-----------------------------------------------------------------------------
    " a& |8 V1 v7 Y// Name: % t& X. z& `  g
    // Desc: ( z3 |- t. l+ c4 g9 w
    //-----------------------------------------------------------------------------
    2 i3 }: E. w, ~( h4 e7 B7 v( u% kvoid CMazeServer::HandleClientPosPacket( DWORD dwFrom, ClientPosPacket* pClientPosPack )
    / J, N: o5 _+ h+ j{
    ' G3 d3 F3 m% l3 q( Y    // Grab player for this client and lock it
    + V. ~* d+ j. C, W! G9 M    PlayerData* pFromPlayer = GetPlayerDataForID( dwFrom );3 z2 U$ [( _' a* \( |
        if( pFromPlayer == NULL )
    " B2 e8 p3 X. ~    {+ \; C/ e2 J& T5 h/ z/ e% C
            if( m_dwLogLevel &gt; 1 )/ Y, u2 s/ j  \$ j2 K& q$ f2 R
                ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Could not find data structure for this player"), pFromPlayer-&gt;NetID );
    7 U" q, J/ G$ G        return;' j; `: I: B2 }4 N$ q
        }</P>% Z2 z+ R5 f' D' ^
    <P>    LockPlayerData( pFromPlayer );</P>( |0 j7 f" T/ l
    <P>    if( FALSE == pFromPlayer-&gt;bAllow )- t0 c9 ?2 X/ E9 J( v
        {
    9 Z- z  r) \  @6 r! y- P" u8 g        if( m_dwLogLevel &gt; 0 ); f- W% F$ X0 q" I  _, H$ [+ B& i
                ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Got position packet from bad client.  Rejecting client"), pFromPlayer-&gt;NetID );</P>
    ! I0 H# z% C% ?6 ]" o1 ]9 J<P>        m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );! u" I$ {8 Q. |- Y% \, H
            UnlockPlayerData( pFromPlayer );* w) ]4 z, z8 i, s
            return;9 p% [, r( E2 G% h% o
        }</P>; w6 G+ {$ u1 c& Q
    <P>    // Compute the cell the player should be in now( H3 A1 y0 {# N0 I
        DWORD newcellx = int(pClientPosPack-&gt;fX);+ y* N1 X) M9 z, B. {+ S
        DWORD newcelly = int(pClientPosPack-&gt;fY);
    # s# P5 c* I3 P3 x    DWORD oldcellx = pFromPlayer-&gt;wCellX;
    8 K$ ?2 _. _. _# q! A    DWORD oldcelly = pFromPlayer-&gt;wCellY;</P>
    ( I, ^* g; q% r' Y  t( u/ b3 c<P>    // Have we moved cell?& y; `7 M: o4 h! C4 Q, j& ?9 @
        if( newcellx != oldcellx || newcelly != oldcelly )6 B- q. k9 N, f. Z
        {
    - t6 d  D6 O9 g        // Yes, so lock the pair of cells in question9 d! O+ b/ m6 ?1 N' [  R% O
            LockCellPair( oldcellx, oldcelly, newcellx, newcelly );</P>
    # A5 I: @( O# t# K% F8 G1 h$ c6 d& I<P>        // Remove from old cell and add to new cell
    + T5 E  P3 v% K( M; g1 b4 m9 ?        UnsafeRemovePlayerDataFromCell( pFromPlayer );  S( T: ~' r& @- V& F: O
            pFromPlayer-&gt;wCellX = WORD(newcellx); pFromPlayer-&gt;wCellY = WORD(newcelly);8 m  s! ?2 N/ T; I( O: O1 a
            UnsafeAddPlayerDataToCell( pFromPlayer );</P>% t6 [: r( x6 ?# G' G4 r5 o5 i! u: U
    <P>        // Unlock cells
    2 `: l8 {1 P8 c" S  Z        UnlockCellPair( oldcellx, oldcelly, newcellx, newcelly );
    5 [, E6 H! H8 F% e5 V    }</P>/ d# b) a; Q; D7 {
    <P>    // Update player position
    ' b' i. G( `. }    pFromPlayer-&gt;fPosX      = pClientPosPack-&gt;fX;
    - g# J' M9 U0 w1 s    pFromPlayer-&gt;fPosY      = pClientPosPack-&gt;fY;  y- O! s  G* ]* Y( U
        pFromPlayer-&gt;aCameraYaw = pClientPosPack-&gt;aCameraYaw;</P>
    ' ?, R4 g2 z( S- r( ?/ Z* R7 t<P>    // Allocate space to build the reply packet, and fill in header 3 }7 @* ~5 I) j+ Z7 s+ N& ^5 ^
        DWORD dwAllocSize;
    5 [4 A1 p6 i! F$ B0 p7 @( R. }# [    ServerAckPacket* pSvrAckPack = NULL;</P>
    7 |; J& Q1 O! |8 C1 g5 {, B<P>    // Begin by allocating a buffer sized according to
    , e% m' a( m+ Z; b' f    // the current number of nearby players + 4.  This will give
    ) _5 i- @. l# C6 p7 i    // a little room for more players to come 'near' without resize1 z9 |7 v% R% e1 s0 x5 B& X9 w
        // the buffer.8 e' f7 V6 {# W* y
        DWORD dwMaxPlayerStatePackets = pFromPlayer-&gt;dwNumNearbyPlayers + 4;</P>
    / C1 T7 _% p1 ]4 K& f$ F<P>    dwAllocSize = sizeof(ServerAckPacket) + dwMaxPlayerStatePackets*sizeof(PlayerStatePacket);
    & y5 i, P0 q1 z    pSvrAckPack = (ServerAckPacket*) realloc( pSvrAckPack, dwAllocSize );
    ( P8 H# R+ B4 @/ O9 F' K    if( NULL == pSvrAckPack )
    ' l* @' w; E5 i    {
    4 [6 [4 c3 p5 I4 r        // Out of mem.  Cleanup and return1 C% Y8 O8 F$ B! \% X: m
            UnlockPlayerData( pFromPlayer );& J0 i# B) I/ l. x
            return;       3 m8 V+ a/ W2 n( N: a# g" d0 V4 C( q# F2 G
        }6 d: f1 h* J. A; h4 P' V! X7 n6 F
        ZeroMemory( pSvrAckPack, dwAllocSize );</P>
    7 u* o  i2 ]% N1 k+ b  T3 N<P>    *pSvrAckPack = ServerAckPacket(m_dwPlayerCount);
    4 l4 z2 Q: O% `: ]) h! K6 z    pSvrAckPack-&gt;wPlayerStatePacketCount = 0;  [+ B+ p5 W& q9 |/ O( r
        PlayerStatePacket* pChunk = (PlayerStatePacket*)(pSvrAckPack+1);</P>% f" x% C& M5 v7 J
    <P>    // Compute range of cells we're going to scan for players to send
    ; i( T# C! p# H& R, Q8 g( `    DWORD minx = (newcellx &gt; 7) ? (newcellx - 7) : 0;2 U, [( F- s8 P  ~4 y
        DWORD miny = (newcelly &gt; 7) ? (newcelly - 7) : 0;0 \7 T4 P  A/ C
        DWORD maxx = (newcellx+7 &gt;= m_dwWidth) ? m_dwWidth-1 : newcellx+7;
    $ d( u$ `0 }- L1 B4 X) z/ j2 z    DWORD maxy = (newcelly+7 &gt;= m_dwHeight) ? m_dwHeight-1 : newcelly+7;</P>* \* D' b7 f' o2 R5 J
    <P>    // Lock that range of cells% i% v# U4 R  Z  s
        LockRange( minx, miny, maxx, maxy );</P>- Z; F$ W) Y" ]5 z1 s% o- ~
    <P>    // Scan through the cells, tagging player data onto the end of
    - i1 l: l: ]6 d+ ^. q    // our pSvrAckPacket until we run out of room
      |$ s9 A9 g0 g+ I, @    for( DWORD y = miny; y &lt;= maxy; y++ )
    + T. h6 v! @. u    {- v1 C- t/ p& F* P
            for( DWORD x = minx; x &lt;= maxx; x++ )
      N0 K! L7 U- ]2 ^6 [1 A* F, H! F        {
    4 d% f/ y0 p. V2 P4 r, o5 H' `1 u            PlayerData* pCurPlayerData = m_Cells[y][x].pFirstPlayerData;/ I7 j7 G( }. V" y1 P& F
                while ( pCurPlayerData )
    1 t! w$ f) M$ w& Z5 F            {
    ' m7 Q/ f6 C& ^& {* e                if( pCurPlayerData != pFromPlayer )8 e7 K2 k, G( [1 e* E0 f6 u
                    {
    ! w4 D1 t! n7 G& t) q. |$ e- l8 d" I$ B                    if( pSvrAckPack-&gt;wPlayerStatePacketCount &gt;= dwMaxPlayerStatePackets ), |$ u% j; |# d6 c; ]$ n: `. B5 [- ?6 j
                        {) C/ L8 L8 R# E# v/ E, [! X2 j
                            // Make sure pChunk is where we think it is
    3 O; K& s% o  a) Y                        assert( (BYTE*) pChunk == (BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket)) );</P>$ w  ]' O' @1 t
    <P>                        // There are more than just 4 new nearby players, so resize the
    * ^# l" P. Q) o3 A5 V# n                        // buffer pSvrAckPack to allow 16 more PlayerStatePacket's.4 N( @$ K: g* G* U% B8 a6 S. |
                            dwMaxPlayerStatePackets += 16;
    . {( m! t4 b" b6 m. e! u& N- T                        dwAllocSize = sizeof(ServerAckPacket) + dwMaxPlayerStatePackets*sizeof(PlayerStatePacket);
      a( J0 I! w# j, p5 G                        ServerAckPacket* pNewSvrAckPack = NULL;) f0 J& [! a* C7 c
                            pNewSvrAckPack = (ServerAckPacket*) realloc( pSvrAckPack, dwAllocSize );
    / K$ i1 f% ^# n6 m+ \* ^; g* L                        if( NULL == pNewSvrAckPack )
    ( _% D- ~/ l% c& G1 ]! W# [                        {
    9 T2 k4 l8 O9 ]7 V, K; i                            // Out of mem.  Cleanup and return, X' w" ]2 Q. c# ]
                                free( pSvrAckPack );
    . l4 a/ a% ~8 U+ u  R4 y                            UnlockRange( minx, miny, maxx, maxy );# _/ K, Z: R- T1 Q+ d4 v+ w; _
                                UnlockPlayerData( pFromPlayer );# B. P+ b5 Y. {: z1 u- I: E& p# ~
                                return;      
    / B2 \, X% {( x! W; U1 Y                        }</P>
    0 ]2 P. R# x1 ?# G4 F, a( O<P>                        pSvrAckPack = pNewSvrAckPack;
    6 I$ t0 ?+ G. g" ~% N7 [' D                        pChunk = (PlayerStatePacket*) ((BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket) ) );</P>; h% `0 N- j* x" }
    <P>                        // Make sure pChunk is still where its supposed to be2 U" h. p* L8 Z4 ]
                            assert( (BYTE*) pChunk == (BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket)) );
    9 U' ~4 T: A1 ~                    }</P>
    % V0 ?9 r; J! d<P>                    pChunk-&gt;dwID       = pCurPlayerData-&gt;dwID;6 }# k6 U& n( t8 o
                        pChunk-&gt;fX         = pCurPlayerData-&gt;fPosX;
    . C) y. d: h, J( c+ u( C6 `                    pChunk-&gt;fY         = pCurPlayerData-&gt;fPosY;( k, ?/ T& A" q, ?2 n1 i$ F
                        pChunk-&gt;aCameraYaw = pCurPlayerData-&gt;aCameraYaw;2 f- a3 t8 }& g. x1 Y- h: w
                        pChunk++;6 {+ {! @7 F2 a1 z+ `: t2 {& q( \
                        pSvrAckPack-&gt;wPlayerStatePacketCount++;
    1 J# z. O* H: s& h2 r: u  M                }  h1 o, \0 M7 ]  w+ N7 H
                    pCurPlayerData = pCurPlayerData-&gt;pNextInCell;, ]! {( D% r3 \  E
                }$ f+ P$ H7 [, s' T: k
            }) Q0 _4 t0 I- a& ^. M
        }</P>- h& p2 _( d7 n& h
    <P>    // Update the dwNumNearbyPlayers for this player+ _; l6 H- w. T# t- _
        pFromPlayer-&gt;dwNumNearbyPlayers = pSvrAckPack-&gt;wPlayerStatePacketCount;</P>0 r1 t* V7 d$ b, b9 |6 p1 D
    <P>    // Unlock range of cells: b5 D5 u& I* ]6 y. `7 j
        UnlockRange( minx, miny, maxx, maxy );</P>
    * G  R% H0 K4 J  e8 |<P>    if( m_dwLogLevel &gt; 2 )
    * Z/ Z4 Z% X7 T* ^1 T3 r( ~    {
    * v: j: f% V0 `' I& `. f        ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Position is (%0.2f,%0.2f)"), pFromPlayer-&gt;NetID, pFromPlayer-&gt;fPosX, pFromPlayer-&gt;fPosY );
    , H; s7 l# y5 L; ?    }% C/ D" x- O; E1 l% Y( w7 o  }
        else if( m_dwLogLevel == 2 )' O$ o9 S+ v2 |+ ?' I( l. _4 J
        {8 s4 s; ~; e# F; [
            FLOAT fTime = DXUtil_Timer( TIMER_GETAPPTIME );
    ' o1 \3 D6 G. |; G2 d3 k: V        if( fTime - pFromPlayer-&gt;fLastDisplayTime &gt; 60.0f )
    : A! B7 h& q5 Z' D$ A        {) e5 v+ L& L  [$ L- M
                ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Position is (%0.2f,%0.2f)"), pFromPlayer-&gt;NetID, pFromPlayer-&gt;fPosX, pFromPlayer-&gt;fPosY );8 l  o/ e0 D6 b0 t; N2 N5 W  g+ C
                pFromPlayer-&gt;fLastDisplayTime = fTime;/ w: t8 J  p. t* v, S# @. A' C
            }
    , w+ d' I7 L2 }7 F3 r    }</P>
    $ D/ m5 y0 i, M, X! S( H<P>    // Unlock the playerdata/ D; W0 k  w- \" J) n" h) ]. b
        UnlockPlayerData( pFromPlayer );</P>
    & u# q/ A' W( Y6 z. f<P>    // Send acknowledgement back to client, including list of nearby players
    3 M% \2 J: f) A. P    DWORD acksize = sizeof(ServerAckPacket) + (pSvrAckPack-&gt;wPlayerStatePacketCount * sizeof(PlayerStatePacket));
    - z6 m/ ~. {6 }
      f& ^3 C; M8 J& z    // Pack the buffer with dummy data.
    % ^: N+ ?  b7 a    if(m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex] &gt; 0)
    $ ^' w( o4 a6 K3 \* F1 m    {' Q! [/ a; Q9 U
            DWORD   dwBufferSize = acksize + m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex];$ i/ g$ i8 Z$ C" Z. F. y' p( C, g. I
            VOID*   pTempBuffer = 0;</P>( \% L2 e- v; o
    <P>        pTempBuffer = malloc(dwBufferSize);
    " a7 Y+ V6 _5 G, Q' }        if( NULL == pTempBuffer )
    * y4 V4 B0 n3 O3 e2 ?) A3 d        {
    . K. z, i1 c1 _# U            //Out of memory$ s: u# t- ]  {5 l
                DXTRACE_ERR_NOMSGBOX( TEXT("System out of Memory!"), E_OUTOFMEMORY );
    + F2 J- w$ C9 ?% |! b            free( pSvrAckPack );1 }) s+ j/ n: p( M2 _
                return;0 r% k6 J  w( n6 |) y' [( P) n- T
            }</P>
    2 j+ V8 {2 r8 D, L, V<P>        FillMemory(pTempBuffer, dwBufferSize, 'Z');4 B2 j) w; q& K  `) p/ X! }3 m
            memcpy(pTempBuffer, pSvrAckPack, acksize);</P>* _' ?2 y/ p( I( x/ N9 ~5 x
    <P>        SendPacket( dwFrom, pTempBuffer, dwBufferSize, FALSE, m_dwServerTimeout );
    2 M, Q7 o! [/ c    ( ^# ~; t" a# O; k6 [
            free(pTempBuffer);
    1 p. H% ~' B* T. ?& g- a! S    }   - c3 Q( J- {: w9 E7 s2 S, R0 a& z! p
        else
    + Z# i3 e( k8 g, n: n; A7 I9 T    {
    ! o1 C& e8 p; s: |        SendPacket( dwFrom, pSvrAckPack, acksize, FALSE, m_dwServerTimeout );! |2 U/ _9 b7 @' O4 A2 M. K( D
        }</P>% Y: R  L& n7 t% `$ ]9 q- p
    <P>    free( pSvrAckPack );</P>
    . |7 u( P+ X4 I5 p+ b<P>}</P>; Q3 C/ _. P# o6 u8 L8 p
    + S* j! Q! ]* U7 |4 t
    <P>
    + Z  }; z3 W! k% g9 A//-----------------------------------------------------------------------------2 e- T* K( x0 a5 A- W" }
    // Name: ( {# @7 S' K2 U+ B# w" y
    // Desc: / H  L, H) y7 L  v! V
    //-----------------------------------------------------------------------------
    % M3 k+ q! L2 {  p% b- B+ {- @1 zvoid CMazeServer::HandleClientVersionPacket( DWORD dwFrom, ClientVersionPacket* pClientVersionPack )
    0 X+ i/ _* w: E) m{
    5 L# b: a/ X9 g6 W: o" _    // Grab playerdata for this client and lock it
    & K& d& X# _6 N    PlayerData* pPlayerData = GetPlayerDataForID( dwFrom );8 J# j" B9 Q* X: ?1 p: D' \2 J
        if( pPlayerData == NULL )
    - y# Y5 C" @7 z9 B- n1 k, ]        return;! |6 }( C9 w% t  r& y" L, ~
        LockPlayerData( pPlayerData );</P>
    . @1 D, [  z) g4 B<P>    // Record the version number ! c+ R/ o' y2 c, g
        pPlayerData-&gt;dwVersion = pClientVersionPack-&gt;dwVersion;</P>8 `: Q! U6 b* k" V, S$ K3 `
    <P>    if( m_bLocalLoopback )
    - t4 ?7 m4 G' b4 l* r7 n2 l" b        pPlayerData-&gt;bAllow = TRUE;
    % J9 [4 a( p$ p) |    else
    6 b. v9 n( i9 Z, |2 {        pPlayerData-&gt;bAllow = IsClientVersionSupported( pClientVersionPack-&gt;dwVersion );</P>
    0 k, L# b* q, i<P>    if( m_dwLogLevel &gt; 0 )& f  R" v9 G8 v! g1 ~
            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>5 N1 [: B* `% w/ [3 u
    <P>    if( FALSE == pPlayerData-&gt;bAllow ), a3 v0 f6 d' Z7 F* l6 g: A! z$ f! O
        {
    % g& a1 [3 n) P6 f% r, Z        if( m_dwLogLevel &gt; 0 )) [* n4 ~1 I; C
                ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Rejecting client"), pPlayerData-&gt;NetID );</P>
    9 a! z/ W5 \0 W6 s  n1 |. ]<P>        m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );& a! N! e  S) ^
            UnlockPlayerData( pPlayerData );
    / j2 d$ A4 b1 }        return;
    $ d' A! |0 K5 L    }</P>
    0 C/ o- H; l3 o<P>    // Unlock the playerdata
    $ @! o6 b! l7 K% r3 c+ S5 A# \    UnlockPlayerData( pPlayerData );</P>
    / a. t" M6 a6 F<P>    // Send acknowledgement to client that the client was either accepted or rejected) R2 B! n% T, I% ~
        ServerAckVersionPacket packet( pPlayerData-&gt;bAllow, dwFrom );0 B1 Z# ?/ Y* |* g
        SendPacket( dwFrom, &amp;packet, sizeof(packet), TRUE, 0 );
    8 G' K+ `. B% {6 {}</P>5 o9 N1 [( i  R0 g- y* ~& r- l3 R+ f
    9 T( _3 ~# r+ ]# q
    <P>
    9 L5 a, t, a% ?5 }6 d/ i' w//-----------------------------------------------------------------------------1 t+ O2 q% \% q
    // Name: 4 p6 q" p% ~2 k% Y
    // Desc:
      W( k% D0 a0 v//-----------------------------------------------------------------------------: Z: _. h, S/ y/ ~1 a
    BOOL CMazeServer::IsClientVersionSupported( DWORD dwClientVersion )/ f7 Z# L' C. U* p1 ], z
    {
    6 Z8 J! i' k  T% s4 I    switch( dwClientVersion )0 o3 A* L- Q5 A2 `9 F0 P
        {
    + {" @8 o5 D1 U( Y5 v        case 107: // only v107 is supported
    # {5 }0 C, M" x            return TRUE;
    8 N" F1 o. k* A! T& W7 |        default:
    8 \# X9 D- w+ T( r  ?            return FALSE;) n' H* ~8 ?5 a7 h  t/ \/ V
        }
      ^9 h7 E) {7 m/ e" \. a}</P>
    ; ?. i) X) \' V& g) {2 ^$ I5 n5 H1 C% a2 O0 H5 t6 P1 W
    <P>6 [9 x7 f. Q! [5 G% k7 ?- u' z
    //-----------------------------------------------------------------------------0 p  A! Y: C+ f. V* j
    // Name: . h1 c6 G) o3 h" F
    // Desc: ( k9 D- ~% h- R( @$ o5 r; z
    //-----------------------------------------------------------------------------
    - l4 z3 y* ]" g3 hvoid CMazeServer::HandleUnknownPacket( DWORD dwFrom, ClientPacket* pClientPack, DWORD size )
    # J* \, l  U4 Z6 s" L, T& y{
    . A; u) j( h' P1 G    if( m_dwLogLevel &gt; 1 )# w1 Y1 g7 t* \
            ConsolePrintf( SLINE_LOG, TEXT("ERROR! Unknown %d byte packet from player %0.8x"), size, dwFrom );</P>
    / S5 x2 [8 D3 |* Y# C" H" P# t# i" A<P>    m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );
    7 O2 J2 ~( Z2 z5 h' t}</P>5 @# Y; o! K& U3 u
    * I+ T% b1 {' K3 ]
    <P>
    / r1 m5 i  Y) ?//-----------------------------------------------------------------------------+ t* p* s  v; ~7 f6 C  n
    // Name: 0 p4 r, D! N% E) G: h
    // Desc: - P+ a) X" o  g- u1 L7 \
    //-----------------------------------------------------------------------------
    * X: C  m# p5 S9 o3 d5 L. WDWORD   CMazeServer::IDHash( DWORD id )3 r$ G1 k# U$ C* W% M; D
    {
    / H8 E( I0 Y3 K8 g5 n( v    DWORD   hash = ((id) + (id&gt;&gt;8) + (id&gt;&gt;16) + (id&gt;&gt;24)) &amp; (NUM_ID_HASH_BUCKETS-1);" H3 ]- o- N3 P4 V5 _! g/ R4 a/ \
        return hash;, m/ x/ C3 X! A9 a+ Q$ D( z$ k
    }</P>+ V/ h, F0 l* b

    2 g% V# K4 Y$ ^: l3 l  ]/ j' [<P>4 `2 I+ N4 K2 x& J& e+ b
    //-----------------------------------------------------------------------------
    * k9 X# {+ X/ T8 |7 t7 k" C// Name:
    # X0 G% B4 q" o- ~) w5 y" l& X3 Q// Desc:
    & |& L, _% T5 q5 b//-----------------------------------------------------------------------------& b6 `. D/ W/ X. V& k
    void CMazeServer::RemovePlayerDataID( PlayerData* pPlayerData )
    ; H% g2 g3 p$ s1 }: U{
    / p/ K$ R- a7 U& @; C0 {    // Hash the ID to a bucket number: u$ E2 ?9 u8 D" h) ~
        DWORD   bucket = IDHash( pPlayerData-&gt;NetID );</P>
    # C! ]- A' U, F8 u' [! V- E: U<P>    // Lock that hash bucket( x6 i% t  S& N9 {
        const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;
    * G  h0 i$ \9 D* B$ G; v    m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>
    9 Q9 A* d3 _4 `( g2 r8 f<P>    // Loop though players in bucket until we find the right one' W/ x& e  P1 q1 ?2 i' E* S
        PlayerData* pPt = m_pstIDHashBucket[bucket];
    ; L6 K" l7 K+ h6 L    PlayerData* pPrev = NULL;: A& j/ L; x4 F/ P% K3 f/ y
        while( pPt )
    ' N: e. x) n0 _6 w    {( W1 g7 Y* a. g# a
            if( pPt == pPlayerData )# y4 k3 M- P4 M5 d
                break;
    & y+ u2 m# m! p' W1 ]( D/ d  `- ]        pPrev = pPt;
    ( J8 G+ r# c0 c; Q  Z        pPt = pPt-&gt;pNextInIDHashBucket;
    1 K" @- P1 q9 s0 J% Q    }</P>
    , z: P% j  j+ Q6 q<P>    if( pPt )
    9 h  N4 K, B8 X" T    {
    $ O1 `, A5 T0 U, x        if( pPrev )% I( j. ]. w# _, ^6 x5 R/ r7 l
                pPrev-&gt;pNextInIDHashBucket = pPt-&gt;pNextInIDHashBucket;
    0 I# e$ n; t  w: Y. `0 n) ~" {! Q        else
      V6 {- K5 L7 z' t" C3 S            m_pstIDHashBucket[bucket] = pPt-&gt;pNextInIDHashBucket;
    : i: [% Z' {1 H" A" B        pPt-&gt;pNextInIDHashBucket = NULL;8 p9 o# b2 j6 Z% e
        }</P>7 q. s6 n7 ~9 H4 B0 j7 r$ B
    <P>    // Unlock the hash bucket
    . i; F# K( J) J5 D  a& G; K4 U, A    m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();/ _; k8 s2 v" X% _" S
    }</P>
    # O* M1 D. \, O, z. E/ v
    3 O' C7 T  b! U<P>/ H! U5 B3 }, Y6 E5 K/ w
    //-----------------------------------------------------------------------------3 j  o! v  m7 u+ \9 S
    // Name:
    ! E% Y0 T4 F2 ?) T// Desc: & x% f: |; n, s% a4 |
    //-----------------------------------------------------------------------------
    . U( Y" _( G6 t2 jvoid CMazeServer::SetPlayerDataForID( DWORD id, PlayerData* pPlayerData )' A+ i; F, i* \" O
    {0 V5 \' d& z2 e
        // Make sure this player isn't added twice to the m_pstIDHashBucket[]) u& _/ q( ]8 ~6 W" O% N* b4 @6 f
        // otherwise there will be a circular reference6 B( a& B0 L" I$ H5 @  f: |
        PlayerData* pSearch = GetPlayerDataForID( id );
    ( j8 w9 A: t- [  Z) ]2 ~- b    if( pSearch != NULL )
    6 e" ]1 Y4 {! t+ I1 k* \        return;</P>
    6 [6 H1 J1 [! g6 P<P>    // Hash the ID to a bucket number
    ! c$ j/ J4 P4 I# h) P9 p5 V    DWORD   bucket = IDHash( id );</P>' I+ j+ |3 f+ U# m9 U
    <P>    // Lock that hash bucket
    ( p& U  ]$ |7 i$ l. i% G    const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;
    7 b2 t( v' T  S; G& K! _    m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>' \* F, v- |* ]5 l. r% N) _
    <P>    // Add player onto hash bucket chain
    0 J: G, Q# ?/ u* Y* n8 @3 y    pPlayerData-&gt;pNextInIDHashBucket = m_pstIDHashBucket[bucket];
    " x! h$ v% g. b6 q5 ~    m_pstIDHashBucket[bucket] = pPlayerData;</P>- h; [; Z. P3 J- q5 e
    <P>    // Store net id in player( k0 F1 }( ?( t" M  }
        pPlayerData-&gt;NetID = id;</P>
    ( i8 T+ B9 ]( j0 l  S, V4 F. O<P>    // Unlock the hash bucket
    8 y3 q& \) E# J    m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();8 ]7 z5 }4 j. }, r
    }</P>. t0 g; e2 X1 q$ A7 r
    & }- v" L* ]/ q2 q8 q" [" H
    <P>4 ]# i" L0 M) i; P( U( P$ \
    //-----------------------------------------------------------------------------( B+ ]' W0 \/ j8 X5 a
    // Name: 5 k5 e6 D1 C8 b+ c6 G- O3 M; ?. [
    // Desc:
    " t! W2 t" l. e5 [: K; O//-----------------------------------------------------------------------------
    . K3 h8 f, T) ?3 _PlayerData* CMazeServer::GetPlayerDataForID( DWORD id ). T# @- W# E; c% `! Z
    {' |+ s) P  }8 e  N" U4 P( ~2 p
        // Hash the ID to a bucket number1 |/ `7 I1 g. f5 U
        DWORD   bucket = IDHash( id );</P>/ i; t5 U: Q( d5 \! J
    <P>    // Lock that hash bucket: L+ J$ o$ Q6 w& `
        const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;3 Y6 E4 i: f: s" E/ o0 r
        m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>1 ?& F% M9 L2 z3 K: C3 Q
    <P>    // Loop though players in bucket until we find the right one0 Q9 s1 U7 v: G2 }3 F8 \" O9 n! m7 X- d
        PlayerData* pPlayerData = m_pstIDHashBucket[bucket];: R8 b3 j! I  M4 u- c3 i$ ~& v
        while ( pPlayerData )3 I) G' @$ r& R9 S. i8 A
        {
    , `/ P/ o" ~9 s7 ?" h        if( pPlayerData-&gt;NetID == id )2 X8 ?' N' u# O3 z* H
                break;/ h/ h* Y' T- U. T
            pPlayerData = pPlayerData-&gt;pNextInIDHashBucket;/ d  a6 K: [& k" R# p, q
        }</P>' d$ o9 Q& i1 j# N7 m3 G/ j8 ~
    <P>    // Unlock the hash bucket
    ' R% [/ s# }$ b5 q3 z% _    m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();</P>: R! ^+ z2 h! z2 q. s3 K/ B' V
    <P>    // Return the player we found (will be NULL if we couldn't find it)
    ) S& Q  N) x5 `0 l2 ?. g$ h" n/ P, L    return pPlayerData;
    0 x: n- t4 f/ @6 N/ {}</P>
    0 }! |! W- \  `: _5 _
    8 \* t# d9 G  K5 l<P>6 g) m% l8 s% s; x2 Q
    //-----------------------------------------------------------------------------3 J$ \( |) u9 _9 ?
    // Name: - g2 x$ A, m. G: e0 S" _
    // Desc: calls DisplayConnectionInfo for each connection in a round-robin manner
    6 `: B! u: m: Y$ {5 m" {//-----------------------------------------------------------------------------
    % x9 x7 ^( K  ?4 tvoid CMazeServer:isplayNextConnectionInfo()
    ( Q  d# E5 {3 V; [2 Q7 E) c{8 N2 m6 A) {: n3 C8 [/ Q
        if( m_pNet )
    ( _6 j/ l  K/ u5 e) P1 n    {
    ; i0 s. j/ X& R3 N        // Find the player that was displayed the longest time ago, and display it." U- k, A+ ~- J/ |- \7 U4 e, R3 c
            FLOAT fCurTime = DXUtil_Timer( TIMER_GETAPPTIME );
    7 m4 t: c# e, v" X        PlayerData* pOldestPlayerData = NULL;) c6 Q$ o) P* o8 a( X
            FLOAT fOldestTime = 0.0f;</P>% W5 Y3 r' L! F/ g' O9 Z0 s
    <P>        m_PlayerDataListLock.Enter();</P>
    7 b) f2 M4 i, [) k: z+ W6 U<P>        PlayerData* pPlayerData = m_pFirstActivePlayerData;% `% Z& C0 _( j, a& O1 X; Q
            while ( pPlayerData )+ h# x9 `' f  {. u% d
            {
    0 z5 N2 T+ N/ E            if( fCurTime - pPlayerData-&gt;fLastCITime &gt; fOldestTime )
    % }) K. a. I9 C8 G' j( M            {
    - {/ w( Z0 m6 @' w0 z- A8 O6 Z4 G                fOldestTime  = fCurTime - pPlayerData-&gt;fLastCITime;
    8 w# k  q1 ]6 _" F9 j                pOldestPlayerData = pPlayerData;
    9 y1 r& p8 ?# r( v4 |            }</P>
      J$ g2 y3 {  m8 O<P>            pPlayerData = pPlayerData-&gt;pNext;
    ; z9 F' N- t1 D" j. B' O* F5 {& A        }</P>
    4 u5 H/ _' D- g. x: P- A<P>        // Display the player with the oldest CI field, and update its CI field.1 p% T- ~  p% a' R' ~' \
            if( pOldestPlayerData )
    * r6 D! P; G6 {& t0 D6 U        {
    1 O" _7 U0 S* t4 D/ }8 H; r; G. L            ConsolePrintf( SLINE_LOG, TEXT("Displaying connection info for next player") );$ o/ Q, g# ?& o1 l2 v
                DisplayConnectionInfo( pOldestPlayerData-&gt;NetID );, ]3 L- N8 p$ O( U* b
                pOldestPlayerData-&gt;fLastCITime = fCurTime;
    / T7 X; v1 w2 P" d* @- x* j        }7 w1 D$ |# x2 y- c
            else; O+ W. j1 I9 b# [+ b+ G- |! C. g5 K
            {
    8 E8 Z; `, k% \( u- v% T2 l            ConsolePrintf( SLINE_LOG, TEXT("No players found") );9 q! K3 D' L% ]! ~0 J) z" S
            }</P>( B- i9 ~/ ?: E; X: v) {
    <P>        m_PlayerDataListLock.Leave();
    # W/ p/ O/ N" _5 s$ h    }  F) M3 |5 ?( z$ c9 S" ~
    }</P>& I3 c+ V. c% ^) a7 s2 w

    / |6 W6 r6 f1 j( H( n<P>
    / O) o+ f1 R- {% {- ^//-----------------------------------------------------------------------------% E- g/ ?; a% e6 u. a, n
    // Name: 4 b' [# z* f0 M) i* W! a" a
    // Desc:
    ; l, R2 \% U2 f//-----------------------------------------------------------------------------
    2 l  y& g% M, V- n" ~2 yvoid CMazeServer:rintStats()
    ! ~5 O4 g: U3 D, j8 _8 e$ m{
    2 P; G4 n! g3 T. F* h" Y    ConsolePrintf( SLINE_LOG, TEXT("Thread count: Active=%d Avg=%.2f Max=%d"), 2 G* n7 W7 e3 b& y9 i
                                        m_wActiveThreadCount, m_fAvgThreadCount, m_wMaxThreadCount );5 v7 R( I: t8 _" z
        ConsolePrintf( SLINE_LOG, TEXT("Thread Time: Avg=%.4f Max=%.4f(s)"),
      I. U5 ^% \0 V: K) F                                    m_fAvgThreadTime, m_fMaxThreadTime );! D, w9 k4 b: n, n& V7 ]. x! K- G* Y
        ConsolePrintf( SLINE_LOG, TEXT("Players online (not including server player): %d"), m_dwPlayerCount );
    0 J! @. G3 B6 U; m# f9 c    ConsolePrintf( SLINE_LOG, TEXT("Peak player count: %d"), m_dwPeakPlayerCount );# z: n. R- [# d1 A
    }</P>  q- J; r) ^: l! P2 W- r8 E
    : b. U! Z- V8 M( O; G
    <P>6 f; B4 }% q% \/ J
    //-----------------------------------------------------------------------------4 d2 l% V' f4 X: V: M. E1 y
    // Name: # b0 l* S! K7 G8 R7 s1 E! e3 H
    // Desc:
    ' m: e! q3 b4 |  q, H" _- v//-----------------------------------------------------------------------------' E  Q, f* ~5 \) v$ \! S
    void CMazeServer:isplayConnectionInfo( DWORD dwID )" {4 X" f- G2 k6 l: A
    {
    - q# L: O+ _# H5 e! W6 O7 e5 M    TCHAR strInfo[5000];/ Q9 O7 u+ E0 `, ^! j
        TCHAR* strEndOfLine;# ?# ]3 O* k' W
        TCHAR* strStartOfLine;</P>
    : ?6 G8 j! S) g<P>    // Query the IOutboudNet for info about the connection to this user3 m5 w, @: y; z. w$ l( S* P! w
        m_pNet-&gt;GetConnectionInfo( dwID, strInfo );</P>/ Z" I9 X& T) p- O1 j9 _
    <P>    ConsolePrintf( SLINE_LOG, TEXT("Displaying connection info for %0.8x"), dwID );
    + B& u& K. J$ B; G* Q0 @( C    ConsolePrintf( SLINE_LOG, TEXT("(Key: G=Guaranteed NG=Non-Guaranteed B=Bytes P=Packets)") );</P>
    & ~5 T1 L* ]: S- G<P>    // Display each line seperately5 ~; G8 l+ @! c
        strStartOfLine = strInfo;
    9 z5 d, P5 m  V, a    while( TRUE )3 D9 r) |# I1 h2 d0 F6 [" A
        {' }% {9 i0 C% l8 Q
            strEndOfLine = _tcschr( strStartOfLine, '\n' );1 ~1 ^( ?* X( {' T5 |! `
            if( strEndOfLine == NULL )3 G/ ]& {0 Q# i& K, p" s- E4 ?
                break;</P>
    - r3 A7 G0 U* J/ k<P>        *strEndOfLine = 0;" R4 r6 U  k' w
            ConsolePrintf( SLINE_LOG, strStartOfLine );
    ; `& P& W9 T1 T        strStartOfLine = strEndOfLine + 1;/ H1 B+ G, M" T" j
        }
    # a$ p5 `! _! M9 o}</P>) C0 s2 P4 \& K4 `; o! X
    . y# J2 W& }6 n- u- g- B) v* c
    <P>
    # ]3 j4 g) B9 X: q+ W& m8 X//-----------------------------------------------------------------------------
    . M. \& j1 p3 N4 |// Name:
    ( W/ Z$ n& ^# M7 I5 K// Desc: , d6 Y0 i. i* @0 K
    //-----------------------------------------------------------------------------
    & r2 N) b% h9 P, x7 oHRESULT CMazeServer::SendPacket( DWORD to, void* pData,
    7 @$ E* d$ X5 @( {/ L                                 DWORD size, BOOL reliable, DWORD dwTimeout )% E( b% W2 m5 Q# k9 b) K
    {1 k7 {+ F6 y5 S
        // Chance of forcing any packet to be delivered reliably
      e" `# o3 g* A) x) P6 a    if( m_Rand.Get( 100 ) &lt; m_dwServerReliableRate )
    3 K# G+ o* M4 {' _2 q! f        reliable = TRUE;</P>
    . |6 o' q) A1 Y0 g<P>    return m_pNet-&gt;SendPacket( to, pData, size, reliable, dwTimeout );
    $ M" r+ P1 m. G* T}</P>! n) p6 \4 [& x8 W9 B. ~7 `  J

    ' C+ J0 c& `3 l- P<P>  C/ n# K: H: p( y
    //-----------------------------------------------------------------------------
    - m5 b1 g: B2 A( J+ f// Name: $ u- o: v$ P0 m/ P. f
    // Desc: 8 g& l) E: V0 h  [
    //-----------------------------------------------------------------------------, O$ W, e5 c. g: [( p* t
    void CMazeServer::SendConfigPacketToAll( ServerConfigPacket* pPacket ). Y# j9 [6 S' {9 E& b$ A5 V
    {% h( s; [4 C, |
        // If we're up and running, then send this new information to all clients, F0 O' l: g# u4 H
        if( m_pNet )! G0 y( j. m7 R( G% w0 J8 K# V
        {! q$ O# o/ l$ P/ K
            //Use the AllPlayers ID" o, r+ `$ h6 [* H1 F2 O: J- Z
            SendPacket( DPNID_ALL_PLAYERS_GROUP, pPacket, sizeof(ServerConfigPacket), TRUE, 0 );
    - u4 B; v7 I3 i4 {4 ~3 E% j    }0 s2 O$ f" o% a$ D3 G
    }</P>! e) f$ p, ?9 d* f1 t
    9 T  H$ a' M( N. v
    <P>
      ?# Q2 w- C1 _: z/ j# a//-----------------------------------------------------------------------------, e8 n' E; i3 B8 l) w
    // Name:
    9 J4 c& L. M" J, V2 i7 k// Desc: * y. D0 T6 \$ v9 F; G- N
    //-----------------------------------------------------------------------------, ~0 O* e: _* G4 X
    void CMazeServer::SetClientReliableRate( DWORD percent )
    + p" n. p* X& G: G- q& Y! `{- V! H' Z$ v" s
        // Update client config, and build packet containing that data
    ' J9 W; o) e% Z% [1 r/ z. t    m_ClientNetConfigLock.Enter();& Q$ e% R" M8 H: q5 G, @7 z$ G
        m_ClientNetConfig.ubReliableRate = BYTE(percent);
    % j9 {& c/ k/ P3 R: B    ServerConfigPacket packet( m_ClientNetConfig );
    / ]9 O5 O* ^9 Z! V    m_ClientNetConfigLock.Leave();</P>
    $ F, @; X1 `6 I2 K( n; M<P>    SendConfigPacketToAll( &amp;packet );2 h% I  O+ r; j1 B9 Q6 j# N' n
    }</P>& }* E4 {. K- G+ _
    2 [4 p! @: n* P: E5 Q- q
    <P>
    / c  [- W, k8 a7 N//-----------------------------------------------------------------------------, [$ H. ]: t( Q8 \: |
    // Name: . i3 A5 K7 K8 \+ Z; i, b# V9 `5 s& r+ p" E
    // Desc:
    4 E" ^1 \) q2 ~/ p. ~4 H# ]//-----------------------------------------------------------------------------
    " c. ?# Y1 I1 ?7 g0 x: Rvoid CMazeServer::SetClientUpdateRate( DWORD rate )
    , s6 `5 u1 d/ N9 x- c/ k4 D{
    6 W6 {- Y1 S9 d7 C, x8 s# ]    // Update client config, and build packet containing that data
    5 ]: S% {5 m4 z    m_ClientNetConfigLock.Enter();& z* {) t, t: x
        m_ClientNetConfig.wUpdateRate = WORD(rate);3 e+ b  i5 Q2 @  i# [9 D) r& ?
        ServerConfigPacket  packet( m_ClientNetConfig );
    * U6 \5 u" t, r) H; v    m_ClientNetConfigLock.Leave();</P>. I4 C" C% T  L4 O! b
    <P>    SendConfigPacketToAll( &amp;packet );
    $ V1 V) w9 ?8 n# M" ^}</P>
    % |' K( g8 q3 l5 `! v8 a6 S
    ) i; X) P9 R9 f2 `7 `<P>
    2 B- }1 c+ N* J5 T5 N' y//-----------------------------------------------------------------------------
    ! @& |# S( Y! Q# @// Name: 2 T6 ^+ x2 W; H0 w% u
    // Desc: % D- i5 t9 V+ Q6 u; s" e
    //-----------------------------------------------------------------------------0 t! x% Y# N, g/ |& b0 j' h: U" ~
    void CMazeServer::SetClientTimeout( DWORD timeout ). @4 H$ Z6 X9 W; J/ {- c
    {& u9 \% k. X3 W, l. S
        // Update client config, and build packet containing that data
    3 p; R* g/ w4 \9 `: p' j    m_ClientNetConfigLock.Enter();
    * D7 y0 u0 X0 R9 ]7 S    m_ClientNetConfig.wTimeout = WORD(timeout);% G0 ?  v( E) t+ j
        ServerConfigPacket  packet( m_ClientNetConfig );
    ; h; U# u2 e8 w3 D$ |, {; J    m_ClientNetConfigLock.Leave();</P>4 _" ]9 A$ }2 K& R" N+ J. k
    <P>    SendConfigPacketToAll( &amp;packet );
      I- v+ y8 A$ n' w}</P>
    7 c% L# G- u$ r" C* n
    3 @# F* ^+ C. L4 a  I6 G7 Z0 O: E1 \<P>+ o# G" a3 ?- X% E* M3 Y
    //-----------------------------------------------------------------------------8 c, j5 s" K  S0 e0 G
    // Name:
    0 `& F  m, U3 w; F" e. g) a9 i// Desc:
    6 g4 c5 j4 w7 T! I; R$ X- w//-----------------------------------------------------------------------------
    0 c+ i6 O8 L& v6 t- A7 Bvoid CMazeServer::SetClientPackSize( DWORD size )
    " \& l. _. G5 }{& ]/ e2 O2 k7 ?: d
        // Update client config, and build packet containing that data
    ! y: X" l) i  e    m_ClientNetConfigLock.Enter();4 F- C2 s; J4 F1 p6 r. I, b7 X
        5 ~) H( f  L. S& Z+ ]
        m_ClientNetConfig.ubClientPackIndex++; //Increase index and verify location in array./ N2 j4 s1 u& _
        if(m_ClientNetConfig.ubClientPackIndex &gt;= PACK_ARRAY_SIZE)   
      A; ~' h# _% w/ R6 V1 f        m_ClientNetConfig.ubClientPackIndex = 0;</P>
    1 n# n. O, K0 y) z* C: d<P>    m_ClientNetConfig.wClientPackSizeArray[m_ClientNetConfig.ubClientPackIndex] = WORD(size);
    6 v3 K" o. C& R4 f    ServerConfigPacket packet( m_ClientNetConfig );
    4 Y* v% H  t, a" Q    m_ClientNetConfigLock.Leave();</P>
      n6 o$ E$ c/ p) m/ F<P>    SendConfigPacketToAll( &amp;packet );
    . c4 a5 c: X9 @" r% {' T}</P>
    . ~3 l3 B. F( ?2 j$ X8 r' j- E  Q0 C8 Y4 P$ |- a& F
    <P>
    , x- E6 L! _  w: x: e9 T) O//-----------------------------------------------------------------------------; F" E7 v, j) X& R4 C: U, K
    // Name: 9 Y  V% ~  A# c- e
    // Desc:
      {0 h; R+ O  v, l0 w0 G+ M1 m//-----------------------------------------------------------------------------0 ?; [; V' a0 r# O) z# t; c3 ^
    void CMazeServer::SetServerPackSize( DWORD size )
    3 d; u9 h: g* o: j, E{8 J  O+ ^: p, Z0 N
        // Update client config, and build packet containing that data
    0 [9 T* H8 {8 I. y: z    m_ClientNetConfigLock.Enter();
    ) C& r$ J5 r& {    * f' F. s+ b0 y! z4 |
        m_ClientNetConfig.ubServerPackIndex++; //Increase index and verify location in array.$ ~3 h. J9 s* X. v: l4 t- N
        if(m_ClientNetConfig.ubServerPackIndex &gt;= PACK_ARRAY_SIZE)   . Y% V- P4 o3 [1 M* T$ \9 Q" Z
            m_ClientNetConfig.ubServerPackIndex = 0;</P># H. m. |: v5 E! ?; S7 [( S
    <P>    m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex] = WORD(size);+ @- O' P+ t* h  }& z4 L( l
        ServerConfigPacket packet( m_ClientNetConfig );% b) C7 u) v9 q
        m_ClientNetConfigLock.Leave();</P>: w3 v0 F7 {  g
    <P>    SendConfigPacketToAll( &amp;packet );. ?% X0 Z+ g3 q# k, F* \5 d9 n# o
    }</P>
    ; n$ }( ?, q0 F3 J) E<P>, H' I1 n4 z3 p: J1 a- B
    //-----------------------------------------------------------------------------
    ! R' `! ]: R8 I$ m% Q5 ~$ z// Name:
      }4 |1 m+ L& S// Desc:
    . Y( ?9 d( e% R" p8 U//-----------------------------------------------------------------------------2 i2 C5 J2 ?9 x/ a5 ^: b2 U4 @: {  d
    void CMazeServer::SetClientThreadWait( DWORD dwThreadWait )! z/ ?7 M4 U, Z- w
    {
    ! p' ~9 r  [2 ]7 V" T1 l    // Update client config, and build packet containing that data
      V$ P- V9 n! s    m_ClientNetConfigLock.Enter();
    ! _; P) S6 {/ |$ L' N% R6 q   
    / [* d* E8 I: f  a    m_ClientNetConfig.dwThreadWait = dwThreadWait;: v% p+ z$ I0 h, x" u
        ServerConfigPacket packet( m_ClientNetConfig );
    5 h# G$ d7 @) i5 ^  _    m_ClientNetConfigLock.Leave();</P>; ?& e1 o* [7 Q1 S# {
    <P>    SendConfigPacketToAll( &amp;packet );
    ! U) P) a* x$ Q( a2 F7 h3 q}</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, 2025-9-6 13:32 , Processed in 1.187877 second(s), 50 queries .

    回顶部