QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 4186|回复: 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>
    - [2 k, ^4 W6 x$ @+ K8 {<>// File: mazeserver.cpp
    3 g' \" E* P! n+ y' ^; q//
    9 o8 o0 m5 O, y6 x; b// Desc: see main.cpp
    6 z. a# _8 w1 v. W4 J! V//4 ]. l5 g! p/ q- A- Q4 c& \% h
    // Copyright (c) 1999-2001 Microsoft Corp. All rights reserved.4 c1 Z8 ?4 L- \
    //-----------------------------------------------------------------------------1 A* H1 H8 ^, i: J) C
    #define STRICT
    / w  B7 E5 |" N/ j, @3 p; V) ?#define D3D_OVERLOADS
    ' D# G3 q  l* b7 f, g/ |#include &lt;windows.h&gt;9 C0 i0 M" E: y6 [& I7 S' S1 ?
    #include &lt;d3dx.h&gt;( t& B5 N6 e1 t+ X- Y- k0 g3 U3 J
    #include &lt;stdio.h&gt;
    % L* ~$ J/ h, N/ g* w0 G0 p* B#include &lt;math.h&gt;
    ! o! r2 p* a6 w6 k4 \#include &lt;mmsystem.h&gt;
    1 Q. ?6 r9 X" h( n& k9 Q" w- G#include &lt;dplay8.h&gt;* n: @$ j0 p, n. }; V+ v
    #include &lt;dpaddr.h&gt;
    , d: N) D0 U& W7 Z, P9 F2 J* o! \#include &lt;dxerr8.h&gt;! P" v" n  v, n5 P9 b3 b
    #include "DXUtil.h"
    ; d$ s8 @# v2 z$ H( p* w2 z1 D#include "MazeServer.h"; ]/ j  }9 z* w2 V; a4 [" q# j
    #include "ackets.h"
    ; x# u. }+ p: o( I3 j3 f#include "Maze.h"
    + z& m% u3 v6 F/ u7 a0 t+ \$ Q) D#include &lt;malloc.h&gt;
    ) I# P* G1 u( p* T#include &lt;tchar.h&gt;</P>
    9 Q, J5 L" H, y* `" h
    / `: H8 R- Y# D$ N<>//-----------------------------------------------------------------------------9 Y! f0 j' \' C+ p: |' l
    // Name: 6 U1 a8 ]! |  u2 k
    // Desc:
    % @: R0 m. t% e. a& f, A& Q. u//-----------------------------------------------------------------------------7 b/ t2 _& V, J* u" Z
    CMazeServer::CMazeServer()( x( L' y* z1 ]0 m  |# |
    {
    ( i0 {4 h/ O' Y3 s* s    m_dwPlayerCount         = 0;
    0 x6 h% j# {, I6 V8 {) `5 i! n9 Z' l   
    / h7 K- i8 q# [; Q+ \    m_wActiveThreadCount   = 0;; Z5 t' r' x" G+ p5 ]3 N7 G9 l& {
        m_wMaxThreadCount      = 0;8 [" r# O5 I2 t+ i6 a  P& m
        m_fAvgThreadCount      = 0;/ D( k2 q& K: h+ G$ O" e$ k+ t) l
        m_fAvgThreadTime       = 0;
      W9 a( @" `' G% c9 c2 H. K    m_fMaxThreadTime       = 0;</P>8 ^4 Z* S, ~9 B. L
    <>    m_dwServerReliableRate  = 15;
    : I- X) _/ F" J1 P# |, H    m_dwServerTimeout       = 150;
    # ?. D0 o* t& K# c& }8 x    m_dwLogLevel            = 2;
    5 o+ [$ v/ r1 ~    m_pMaze                 = NULL;</P>
    $ J4 [; a, S$ l* D+ `# ^' m6 W<>    m_ClientNetConfig.ubReliableRate = 15;+ c5 G8 q% Z9 u1 T
        m_ClientNetConfig.wUpdateRate    = 150;
    / v' l+ t& N2 j' {    m_ClientNetConfig.wTimeout       = 150;</P>$ `2 E7 Q2 A9 H6 I; X' D) |
    <>    m_ClientNetConfig.dwThreadWait = 0;</P>) C, T  k6 ~" j) K
    <>    m_ClientNetConfig.ubClientPackIndex = 0;; j# C- ^. P/ n
        m_ClientNetConfig.ubServerPackIndex = 0;* R2 M5 ?# q- j; a
        for(WORD x = 0; x &lt; PACK_ARRAY_SIZE; x++)! c4 d( t% U4 Y
        {
    6 @2 \  H) C0 g- ~! q" G% @% K# A        m_ClientNetConfig.wClientPackSizeArray[x] = 0;
    / x8 o7 A  w6 T3 G8 O( j        m_ClientNetConfig.wServerPackSizeArray[x] = 0;
    6 ?5 Q) _+ D6 }: q( n$ Q' T) @% q* c    }  R" U4 ?" R7 N
    }</P>
    4 \6 B  Z: H2 c: D! p
    + _0 [  o, W. ?<>0 u! o" R& S6 ^# j
    //-----------------------------------------------------------------------------5 ]7 L" S1 X( ]3 B
    // Name:
    7 @4 Y" k9 \' ^0 [; j// Desc:
    ' ]; j7 X3 o" w. m//-----------------------------------------------------------------------------/ X, c5 M0 P1 e+ U7 B# l
    HRESULT CMazeServer::Init( BOOL bLocalLoopback, const CMaze* pMaze )) I: a1 J' I3 F8 X: [4 ]8 H
    {
    / c8 @2 }) }# C1 c8 _7 L    m_bLocalLoopback = bLocalLoopback;. l3 n# b: g+ D; r3 i! B
        m_pMaze = pMaze;
    ; s: }: e% _0 `+ T. s    if( m_pMaze == NULL ): z* ]* w8 ^; S* N8 f' @& r/ h
            return DXTRACE_ERR( TEXT("aram"), E_FAIL );</P>! [  Z8 D4 x5 g- {' ?$ C
    <>    // Grab height and width of maze# x5 R/ w2 k4 b3 G% T0 Y; p
        m_dwWidth = m_pMaze-&gt;GetWidth();- a* O' A) ~6 j2 p% j
        m_dwHeight = m_pMaze-&gt;GetHeight();</P>4 b; n! I. Y& s1 j/ O% i& S7 `# R- {
    <>    m_ClientNetConfig.dwMazeWidth  = m_dwWidth;
    ' K* k$ b" Z# w/ @5 i* i1 S. Q    m_ClientNetConfig.dwMazeHeight = m_dwHeight;</P>
    4 t" u. E9 ]8 W0 ]<>    // Validate size. Must be a power-of-2 times LOCK_GRID_SIZE. Compute the shifts.! w) }% D1 d) u& c9 O6 i
        if( m_dwWidth &gt; SERVER_MAX_WIDTH || m_dwHeight &gt; SERVER_MAX_HEIGHT )
    , @) [$ ^0 k; ]9 X$ Z        return DXTRACE_ERR( TEXT("Maze height and width need to be less than 128"), E_INVALIDARG );
    1 r6 n" i* s" u; f5 q& E! A    if( (m_dwWidth % LOCK_GRID_SIZE) != 0 || (m_dwHeight % LOCK_GRID_SIZE) != 0 )
    0 I2 u* v) d' X, W0 |        return DXTRACE_ERR( TEXT("Maze height and width need to be divisable by 16"), E_INVALIDARG );</P>
    ) d- Y* ~/ K% o9 V+ R5 C+ K$ n<>    DWORD scale = m_dwWidth / LOCK_GRID_SIZE;: j) x5 H  r! K1 Q' {3 ]
        m_dwMazeXShift = 0;7 y9 e/ _# N# d+ `
        while ( (scale &gt;&gt;= 1) )2 M$ x( O6 X9 O; N
            m_dwMazeXShift++;</P>* t$ A  [/ c7 |1 t
    <>    scale = m_dwHeight / LOCK_GRID_SIZE;
    3 u- _/ z* Q4 K$ Q2 G1 d    m_dwMazeYShift = 0;- u1 j6 h! Y* x$ m3 F
        while ( (scale &gt;&gt;= 1) )7 Q$ z% ~9 Y2 U" L, A5 m0 e
            m_dwMazeYShift++;</P>
    0 z$ o  J0 O$ O6 j/ [<>    if( ((DWORD(LOCK_GRID_SIZE) &lt;&lt; m_dwMazeXShift) != m_dwWidth) ||& o: ^0 }2 k- d, O. l
            ((DWORD(LOCK_GRID_SIZE) &lt;&lt; m_dwMazeYShift) != m_dwHeight) )' B1 }  w# `" F' n
            return DXTRACE_ERR( TEXT("Maze height and width need to be power of 2"), E_INVALIDARG );</P>, Z- G, J/ l! m% |5 H
    <>    // Initialise the player list
    6 X/ A3 S# T( n! G    ZeroMemory( m_PlayerDatas, sizeof(m_PlayerDatas) );
    7 N; k+ F/ T0 J$ k8 u, {' x0 g. D    m_pFirstActivePlayerData = NULL;
    & e# c. [7 s5 d9 y$ S2 i    m_pFirstFreePlayerData = m_PlayerDatas;( _: _0 H. j: d- B6 s0 b8 e
        for( DWORD i = 1; i &lt; MAX_PLAYER_OBJECTS-1; i++ )
    4 H8 y* A9 k" L; a3 c$ v# C& T5 R    {5 s/ B" \/ a/ v
            m_PlayerDatas.pNext = &amp;m_PlayerDatas[i+1];
    / o- E/ {% ?- ?1 n        m_PlayerDatas.pPrevious = &amp;m_PlayerDatas[i-1];
    & K  ]2 h6 v0 v) P4 ?1 }. U+ B2 K5 U6 ~    }</P>
    & I9 i' I8 n: N% }: U" z3 J) I( R+ N<>    m_PlayerDatas[0].pNext = &amp;m_PlayerDatas[1];
    % e+ l! `; M: s3 t6 F2 _1 W    m_PlayerDatas[MAX_PLAYER_OBJECTS-1].pPrevious = &amp;m_PlayerDatas[MAX_PLAYER_OBJECTS-2];, O% P  f. b' p% b5 ]
        m_dwActivePlayerDataCount = 0;
    : e( r  X. j! I& z+ Y    m_dwPlayerDataUniqueValue = 0;</P>
    ) T* C  y( ~( {# E% @; p<>    // Initialise the cells
    ' u" j* j$ T( z+ i* j" Z7 R    ZeroMemory( m_Cells, sizeof(m_Cells) );
    8 H6 N3 r3 m$ _5 E    ZeroMemory( &amp;m_OffMapCell, sizeof(m_OffMapCell) );</P>: A# \: ~. _" T: Z) c2 E0 m3 ~
    <>    return S_OK;7 \0 k' z1 E7 H( n
    }</P>
    1 |) x7 f2 ]5 \3 y) {( _7 z
    ; l9 i, k, I1 p; B<>
    # r+ m& X& W- y! D: M8 `//-----------------------------------------------------------------------------) W* M8 H7 G% B4 {+ T8 a
    // Name: - ~" ?# H2 o7 `7 T2 E# C5 |2 Y
    // Desc: # q; C9 c" _* \4 ~& x# `6 T7 _
    //-----------------------------------------------------------------------------
    1 P" ]2 H+ f# n- X$ _void CMazeServer::Shutdown()
    8 {8 @8 Y! y* V. l{0 {* Y7 f' F$ Z2 G  S
    }</P>
    " e7 j* `7 B  y4 U$ E5 y4 [2 h1 }$ c/ Y  n) x
    <>
    4 U- ^# d. V! I7 \* R//-----------------------------------------------------------------------------
    : ?, l5 @- Z. J// Name:
    % l" E7 i" |& F// Desc: ( }, f' b) @7 Z2 L( k1 _& W
    //-----------------------------------------------------------------------------
    ; `0 ~8 K4 s$ R( u6 Jvoid CMazeServer:ockRange( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )/ [. P6 L! K9 ~
    {
    ) l$ H# h0 `1 C& m7 b    m_LockGrid.LockRange( x1&gt;&gt;m_dwMazeXShift, y1&gt;&gt;m_dwMazeYShift ,7 z6 v3 l# b2 e/ s& o2 t) }8 \. H
                              x2&gt;&gt;m_dwMazeXShift, y2&gt;&gt;m_dwMazeYShift );4 @4 ?& z, b& R4 i
    }</P>; N7 ^- f- l0 Z( C$ b) ?
    9 T& q; q6 O8 D. {
    <>: X2 t7 ?0 F; q7 S$ _
    //-----------------------------------------------------------------------------
    5 q! g( U5 [) r" l// Name: $ \' p* \6 a$ ^1 V# E+ y
    // Desc: 1 Z. Q- u+ _; I7 p; G1 W3 Z! b" X
    //-----------------------------------------------------------------------------
    7 x6 d' V% L& C! U; vvoid CMazeServer::UnlockRange( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )
    % C7 W* B. T' b* W{
    + @* b6 d! N  {0 {" O; X    m_LockGrid.UnlockRange( x1&gt;&gt;m_dwMazeXShift, y1&gt;&gt;m_dwMazeYShift ,8 Z) m7 L( x: F! d5 N+ a7 G# _* Q
                                x2&gt;&gt;m_dwMazeXShift, y2&gt;&gt;m_dwMazeYShift );( N7 e# R) {7 f, U5 p5 b( O( {
    }</P>
    1 ^9 l, \+ V  l( i
    + [8 s0 s% c. o& S" W# h. S<>7 A$ K! \6 T" E
    //-----------------------------------------------------------------------------
    ; B7 [; @: N8 Q& u0 m5 f// Name:
    / [( K2 ^5 D7 ~) ?: p// Desc:
    * ?2 b! y: _3 K; H//-----------------------------------------------------------------------------' A  i  G7 X" O9 |: r% M
    void CMazeServer:ockCell( DWORD x, DWORD y )
    + j* [) R- }; `$ u6 a  ^, k{
    ' V7 Z0 P/ {7 o2 S1 S    if( x == 0xffff )  a1 o% _" ?" ?- a) p. W
            m_OffMapLock.Enter();
    , Z" O  g* d. t1 R* _    else6 `$ M1 n% C# @" q
            m_LockGrid.LockCell(x&gt;&gt;m_dwMazeXShift,y&gt;&gt;m_dwMazeYShift);/ [, [; p7 Z5 U$ l+ a
    }</P>
      f0 `' @7 ~5 p; h# E- Z: {+ S2 C9 s  C
    <>* f' S- Y* P2 U4 x* O% W
    //-----------------------------------------------------------------------------' @8 [% K3 @4 j. t
    // Name: ' ]0 D  p3 b7 w* |9 S
    // Desc:
    0 z  x" Q& h1 O6 d8 C# M//-----------------------------------------------------------------------------
    5 V5 K/ V2 ~& B; y& ^5 }$ zvoid CMazeServer::UnlockCell( DWORD x, DWORD y ): _. r$ ~, l- G8 V$ J
    {, h2 \  t0 v. v9 `6 R* H5 Q
        if( x == 0xffff )% k/ F# W& g: x: l; Q8 q9 y+ }
            m_OffMapLock.Leave();1 [1 p$ P* }( H
        else+ b, [" A: f% m8 c9 B, a* B
            m_LockGrid.UnlockCell(x&gt;&gt;m_dwMazeXShift,y&gt;&gt;m_dwMazeYShift);: Q/ `  n3 g& z
    }</P>
    % M# S# d( Z6 q3 _; L5 X- D2 ~/ _$ T2 ]5 [$ f) n
    <>) y; D& w: P/ }
    //-----------------------------------------------------------------------------# u2 W7 ~4 e, w  t% f
    // Name: " ^7 p+ Q' f' x2 G: f5 I. y6 a
    // Desc:
      W7 Q# X) q* S2 G. t8 J6 A//-----------------------------------------------------------------------------
    ( \9 L& P) w, }5 |5 ^void CMazeServer:ockCellPair( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )
    # D) N4 y! P7 _( m% i{
    ' H2 L& F5 Z- x4 X- e    if( x1 == x2 &amp;&amp; y1 == y2 ); ^! U+ U5 ~/ ^6 \  d9 u
        {
    " j. Y# S2 P8 z( K        if( x1 != 0xffff &amp;&amp; y2 != 0xffff )
    8 y- N" {. N5 c            LockCell( x1, y1 );
    1 h: x* l2 M0 X: L8 x        else
    * u# B/ P7 v1 l! m  W, F            m_OffMapLock.Enter();</P>: P" E4 R  u5 `0 A
    <>        return;
      V- y. s" U: c& V: N    }</P>
    ( M. S- l  ^+ S3 B<>    DWORD x1shift = x1&gt;&gt;m_dwMazeXShift;7 r. a) d- `: r% k* n' z
        DWORD x2shift = x2&gt;&gt;m_dwMazeXShift;5 d7 K% u3 m% Q- i" o* o5 f
        DWORD y1shift = y1&gt;&gt;m_dwMazeYShift;* M3 C7 \6 P# {$ o2 w* J6 @1 [
        DWORD y2shift = y2&gt;&gt;m_dwMazeYShift;</P>( p8 W  O) t& S/ f9 n, k$ l% N
    <>    if( x1 == 0xffff )9 R2 |2 C6 J; Q/ x/ n/ x7 j
        {
    3 d# c) x7 W8 B. W# ~" n: @, p        m_OffMapLock.Enter();- G4 l8 I' [) K3 y/ X
            m_LockGrid.LockCell(x2shift,y2shift);3 Y# u8 K% H: m( u  X
        }! C+ o9 T2 w# Q6 d& A8 l
        else if( x2 == 0xffff )
    * `1 q1 a3 T/ q' R    {
    - |& e/ |) @2 ^* x+ {" j* H        m_OffMapLock.Enter();& {* ?, h$ d' [& w0 o4 a
            m_LockGrid.LockCell(x1shift,y1shift);& E: }6 K8 [4 s+ d1 S
        }# b' T7 \; ^+ O/ V- ~  O( D
        else
    ; V  a6 O0 t! s, n; K; b    {
    . T. \  v% N3 {0 v; w        m_LockGrid.LockCellPair(x1shift,y1shift,x2shift,y2shift);
    / j! A1 q" d) I9 [* C    }2 Z. ^) H; a4 d
    }</P>
    5 I0 v; A' F" g5 x1 u7 a& Q% A$ D: N$ h
    2 [% j- N- }1 D8 x& p1 Z<>
    . v$ _; I  L2 @$ L# X5 p6 P5 z//-----------------------------------------------------------------------------
    7 _( {% l5 l1 o5 `" y( _1 H5 p// Name:
    " Q0 `  b  H9 b! _' f$ X! q// Desc: : O) ^5 Z6 c! L: @9 g
    //-----------------------------------------------------------------------------" j, I0 A( O5 r4 S" `: V
    void CMazeServer::UnlockCellPair( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )
    ' F$ U5 l' B* u- w3 v. k; y( i# S. y{
    : I" D0 z4 @( ^4 A3 K5 f1 d3 Y    if( x1 == x2 &amp;&amp; y1 == y2 )
    4 p$ N2 h: m9 f- R+ y- P$ q    {
    1 |1 Z& w4 ~3 A* s        if( x1 != 0xffff &amp;&amp; y2 != 0xffff )  q% g, w- c$ a1 R6 {* \7 P
                UnlockCell( x1, y1 );
    % N: J. O% c4 {* v$ W6 _        else
    0 v5 z) x5 \; ]6 A# v, X            m_OffMapLock.Leave();</P>3 N9 c6 Q- Q; {/ I) a. N8 M
    <>        return;  q& V; n3 w" \0 u" O( l/ c
        }</P>
    ' k8 q) V1 |  ?/ F4 Z<P>    DWORD x1shift = x1&gt;&gt;m_dwMazeXShift;# r6 e  g8 w, v0 @1 |
        DWORD x2shift = x2&gt;&gt;m_dwMazeXShift;
    - y% ?2 c% R2 P' p; d2 v    DWORD y1shift = y1&gt;&gt;m_dwMazeYShift;
    " a$ ~) @, n" C( P1 V9 q    DWORD y2shift = y2&gt;&gt;m_dwMazeYShift;</P>% b0 d) z3 b  \2 m$ K
    <P>    if( x1 == 0xffff )
    : e) R! u% B  O& e8 x( o9 Y4 t9 d8 z    {, p- X9 _) m3 K" _
            m_LockGrid.UnlockCell(x2shift,y2shift);
    9 O7 U, |+ T* _5 ]5 u- H        m_OffMapLock.Leave();
    * Q% ~/ P1 q9 g! G- w    }: Q; d% h2 b& t! c4 S
        else if( x2 == 0xffff )
    5 B& m* c: h$ j4 `. _    {
    # w7 m: C9 C. M. ~  P        m_LockGrid.UnlockCell(x1shift,y1shift);- j3 T0 t  X0 {
            m_OffMapLock.Leave();, q$ w5 B. y& `& |4 O9 g0 c
        }$ v7 Y: Q' B. A4 z3 \
        else
    - M: b. w8 P5 ?: e; @* O. U8 I: Y: N    {
    9 H, X" r0 W) v7 d7 I        m_LockGrid.UnlockCellPair(x1shift,y1shift,x2shift,y2shift);
    9 o4 @4 _- @6 l  F1 y, y- Y    }
    % G$ j6 ^# H3 M}</P>
    6 F" N, w( V5 K0 L
    9 u6 ^0 R% V* h<P>
    1 V( U' n, ]6 e5 J) m& S//-----------------------------------------------------------------------------
    1 o* R8 D2 f% A$ d& c  k- i, M// Name:
    ' Z1 k- A8 c9 A  Q- v1 t4 r// Desc:
    : o! ~" u) t- q) \//-----------------------------------------------------------------------------4 W: {, }5 {! n
    void CMazeServer::OnAddConnection( DWORD id )
    1 L7 O. V6 t9 P1 Q5 N, o' Y# g{/ x; E% i0 B. f& o+ L4 d4 r
        m_AddRemoveLock.Enter();</P>
    9 x! c, C% F. W5 ~$ Y0 a<P>    // Increment our count of players
    9 E3 y5 l% d2 [2 W% k5 B    m_dwPlayerCount++;
    5 `+ Y* g- `9 D1 k$ A    if( m_dwLogLevel &gt; 0 ): v: B  c7 h2 N6 s
        {
    6 `! J0 I0 H' J$ Y" |/ x, Q        ConsolePrintf( SLINE_LOG, TEXT("Adding player DPNID %0.8x"), id );2 t( ], z# q* I, D# Y& [7 P9 M2 E& W
            ConsolePrintf( SLINE_LOG, TEXT("Players connected = %d"), m_dwPlayerCount );1 G0 s$ R6 ]" y8 I1 t! U
        }</P>
    3 c3 L$ D- E: Z% |! f, Y% B& a<P>    if( m_dwPlayerCount &gt; m_dwPeakPlayerCount )
    4 a3 F( x/ [. l& s7 l6 g        m_dwPeakPlayerCount = m_dwPlayerCount;</P>' }: S$ D4 A4 G; t+ s1 y. z
    <P>    // Create a player for this client
    ) M4 O% e6 E0 _  i; O    PlayerData* pPlayerData = CreatePlayerData();
    , t& h8 [/ w' ^6 {3 i4 O- D    if( pPlayerData == NULL )
    - f9 n+ D$ g" D8 t9 s    {
    # T5 v$ a# a, I5 y, V        ConsolePrintf( SLINE_LOG, TEXT("ERROR! Unable to create new PlayerData for client!") );
    ) x4 K( ^5 s6 w4 T        DXTRACE_ERR( TEXT("CreatePlayerData"), E_FAIL );
    4 w  l, F9 m3 o+ O3 `9 r# \! h' j        m_AddRemoveLock.Leave();) p+ C4 D" H- g, }* {
            return;
    6 L3 I& K3 P  j( ^/ j/ e    }</P>
    : Q/ ?8 r; s, |' F' X& T<P>    // Store that pointer as local player data& q; d% L6 `: n# q& y2 F
        SetPlayerDataForID( id, pPlayerData );</P>1 E# c! S. r0 M5 ~
    <P>    // Grab net config into to send to client
    + X9 M  R/ {0 C" I* n8 I    m_ClientNetConfigLock.Enter();- x1 v$ z" C( K
        ServerConfigPacket packet( m_ClientNetConfig );6 i1 Z2 H  t" c5 Q) K/ _7 d
        m_ClientNetConfigLock.Leave();</P>
    - `# K6 F- H7 F1 R6 w1 U<P>    // Send it4 `8 B0 O$ q) {5 @+ J, }
        SendPacket( id, &amp;packet, sizeof(packet), TRUE, 0 );</P>
    % n$ G5 E3 U5 v<P>    m_AddRemoveLock.Leave();( h( g( }! _- S9 D
    }</P>3 w) O5 W: ^9 ^

    1 [% _+ Z# ]3 g3 y9 I0 r) a+ e# c<P>
    & m; X6 K% m& [$ ]//-----------------------------------------------------------------------------" q% J( I9 K+ A. _, \4 O
    // Name: 0 \* T- D  ?# I: k9 b- [  N
    // Desc:
    0 n1 t9 L8 c1 u% ?6 t//-----------------------------------------------------------------------------
    : L) f& V; m: p# Wvoid CMazeServer::OnRemoveConnection( DWORD id )" F1 [: K" B/ R  r
    {
    8 P( f$ Q' v; ?    m_AddRemoveLock.Enter();</P>
    & l* ]4 q5 V  H3 _+ m<P>    // Decrement count of players
    ) U$ D, @: S- s- P    m_dwPlayerCount--;</P>
    5 g1 t+ s- B  O<P>    if( m_dwLogLevel &gt; 0 )
    4 o4 X1 L+ F. u9 O9 Y: h    {
    1 j8 q; q# T5 y: a: k        ConsolePrintf( SLINE_LOG, TEXT("Removing player DPNID %0.8x"), id );
    1 ]. f/ V& M' g1 T1 k$ N        ConsolePrintf( SLINE_LOG, TEXT("Players connected = %d"), m_dwPlayerCount );
    # g. i( s/ m2 e! a+ z; K  X4 v# o    }</P>1 o( w% p" Z' X, h. o; L: i
    <P>    // Find playerdata for this client4 u5 F! V7 z4 K# F
        PlayerData* pPlayerData = GetPlayerDataForID( id );' W. W/ l1 u; ^- a, {8 e5 s
        if( pPlayerData != NULL )( i2 @% m/ k) z8 v- b; G
        {6 k$ m- y/ @7 }' q  H. @) U& u
            // Destroy it
    5 T8 M. |  \; p& f" H4 K        RemovePlayerDataID( pPlayerData );
    , f- m; e2 E; f0 ]& D3 @        DestroyPlayerData( pPlayerData );/ j0 O) h! H2 ]# F, }4 \8 V9 L/ u
        }</P>
    . ^; N- T6 ^$ k/ ?+ F<P>    m_AddRemoveLock.Leave();
    : p0 N1 e7 u' U6 a8 u1 s9 b}</P>( a" u4 M# p  k! ^: _8 A% i

    * o" Z/ Y9 X2 A<P>- U6 ^+ o# }/ L7 o4 d
    //-----------------------------------------------------------------------------
    9 b$ E1 q3 B; t// Name: # p: d! b1 }7 k4 A. h+ O
    // Desc:
    - D! H  n) u2 \3 v( C  |5 v//-----------------------------------------------------------------------------
    2 J" m, h6 Q* Y3 s& s" [2 ^HRESULT CMazeServer::OnPacket( DWORD dwFrom, void* pData, DWORD size )
    1 n# e2 K# j8 n  y{$ K) Y" P8 T1 b" L1 F( y; c
        BOOL fFoundSize = FALSE;</P>( L  H! P5 n$ d+ W
    <P>    // Increment the number of thread we have in this process.
    % B  H( [$ n( G0 J  b. s6 S/ ~    m_csThreadCountLock.Enter();</P>/ e. i: h! `" E0 L1 F
    <P>    //Get the start time of when we entered the message handler.
    & Y$ T' t" b7 q/ ?3 i    FLOAT   fStartTime = DXUtil_Timer( TIMER_GETAPPTIME );</P>2 {3 ?3 `4 Q4 `$ Q9 A5 V
    <P>    m_wActiveThreadCount++;
    4 B) A& q4 G6 V  q# ]    if(m_wActiveThreadCount &gt; m_wMaxThreadCount)3 @  ^5 {0 [2 d0 Q
            m_wMaxThreadCount = m_wActiveThreadCount;  j  z; a1 R+ w" X- N
       
    4 W9 R* V, I% t- {  ?    // Calculate and average.
    * ~: _. Y* Y% ]& ]( t# e    FLOAT fdiff = m_wActiveThreadCount - m_fAvgThreadCount;
    $ }5 C' U( M) K; [& S. C    m_fAvgThreadCount += fdiff/32;: G; A, S. z9 v; d5 U2 b
        $ w) t0 x1 m0 r
        m_csThreadCountLock.Leave();</P>( t$ W. \# g( q2 K- Z- L4 ]6 z
    <P>/ w& }; I+ a! G
        ClientPacket* pClientPack = (ClientPacket*)pData;
    & j5 E0 x; M  b( d" F    switch( pClientPack-&gt;wType )1 m! d! c" V7 K6 S# F
        {
    + S# b0 @# F) _3 ^& m$ ?        case PACKETTYPE_CLIENT_POS:
    / u2 `' M  E) D6 r* ], m9 b            . ?3 P4 i( U8 {# G* W0 l0 B
                // Check to see if the packet has a valid size. Including
    0 ^1 k/ V/ U/ n9 F/ c& w3 F            // the custom pack size.
    - U+ l/ A6 f; p+ g& W            if( size &lt; sizeof(ClientPosPacket))- c. k2 h; J) g  |% l$ V# y$ g* p4 T
                    fFoundSize = FALSE;4 {7 A0 r0 m, B
                else if( ! IsValidPackSize(size - sizeof(ClientPosPacket)))5 q+ c6 B5 h0 |0 d
                    fFoundSize = FALSE;
    , t6 x' L8 V4 J, @7 \9 f9 k            else: |% V% m, Z( i- O3 O1 c
                    fFoundSize = TRUE;</P>' q7 l" b. C# x/ L+ W6 P5 ?7 \; R
    <P>            // If valid sized packet, handle the position.+ w9 k, P+ j9 p
                if(fFoundSize)
    ; p5 `5 {* P6 s; [9 g                HandleClientPosPacket( dwFrom, (ClientPosPacket*)pClientPack );
    % d4 a, Q( \% l- N            else
    3 L: `0 [4 ?2 V% n% ^  `                m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );</P>
    ( z  D1 ^0 J: I- Y& P<P>            break;</P># b9 T6 g. p6 u
    <P>        case PACKETTYPE_CLIENT_VERSION:7 n/ M$ O3 R0 W) V# G( E- g
                if( size == sizeof(ClientVersionPacket) )4 v' Y. L: n- `& z; B" \
                    HandleClientVersionPacket( dwFrom, (ClientVersionPacket*)pClientPack );
    ' I4 M7 \8 C' B2 j9 ?% x            else
    & p& s2 g: g6 W6 @1 R& d- u/ v                m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );
    8 L  O1 t& N1 u% ~. [            break;</P>, J2 A; r: a* X0 d, Y
    <P>        case PACKETTYPE_SERVER_CONFIG:</P>/ B* `& M+ y5 z" r$ G" H7 [: ]# R
    <P>            // Server config packet sent to all users (including server). Just ignore and continue.</P>
    " \5 p9 S6 x9 K: ?7 G<P>            break;
    4 u# U  Z  T" @        default:0 ]/ a" R! `/ V4 V1 R: ^: N
                HandleUnknownPacket( dwFrom, pClientPack, size );* s' J' n: Y% x
                break;
    ; Q- u" `5 N; w: \. z$ P    }</P>' \5 U" D/ D/ W! h2 r
    <P>    //If the user wants to hold the thread, Sleep for given amount of time.( H, }1 V% O8 X
        if ( m_dwServerThreadWait &gt; 0 )) o' k+ s0 ^+ X. b# H6 v/ R
        {
    # ^, _& \8 L- _1 w3 X        Sleep( m_dwServerThreadWait );6 E7 j2 n1 B) @$ k  _  T
        }
    # d/ \: b5 S* P/ Y& \    : T4 o" k; x' c0 Z* a1 x# @
        // Retrieve thread data for this process.
    * Z8 ?( T4 A, m$ Y( P/ N, H    m_csThreadCountLock.Enter();</P>- Y: ^" w5 r* t0 A( s" l
    <P>    m_wActiveThreadCount--;</P>, D( x9 b1 q" f: U! z% c! Y
    <P>    FLOAT fDiffTime = (DXUtil_Timer( TIMER_GETAPPTIME ) - fStartTime) - m_fAvgThreadTime;5 V3 R( ?% ?0 @; F
        m_fAvgThreadTime += fDiffTime/32;</P>" z* n+ t- g' |% e0 p& R
    <P>    //Get the Max time in the thread.& J/ K0 y# c, q' g' K
        if ( fDiffTime &gt; m_fMaxThreadTime )
    : m! j( f# j8 n& S    {8 Z( c, u. d, ?
            m_fMaxThreadTime = fDiffTime;$ y! Y; H2 E( S
        }</P>3 d+ }1 G: X3 I+ b0 M6 q
    <P>    m_csThreadCountLock.Leave();</P>) T3 B& S/ {6 }. e# b7 n+ Y9 M7 ^
    <P>    return S_OK;
    # Z  d; I, k* z' O5 ~* S9 d1 N}</P>, b0 A* w1 P* l6 H. q) u3 S' P4 L8 I. W
    / V7 e/ k* ~& I" S/ q
    <P>//-----------------------------------------------------------------------------
    , x: T% R( L; ^# B1 \// Name:
    ) G8 W7 u; i, D$ e. b$ g  b) ?// Desc: 4 p, M- W" q  ^* s$ Z# {
    //-----------------------------------------------------------------------------
    % l: I  W6 V6 V8 Y; |1 wBOOL CMazeServer::IsValidPackSize( DWORD dwSize )
    * j& Q3 r- {7 r$ V9 o' _{
    & w  }  G* M5 M8 B' _    BOOL fFoundSize = FALSE;
    4 c' O; U# Z3 ^' m  ]' E3 F    BYTE ubPackLocation = m_ClientNetConfig.ubClientPackIndex;
    ) \% D. z6 L6 R   
    , H& }! L7 c! r1 o( |# w    // Check through the array of valid pack sizes.2 B9 y+ f: j- b! }2 {4 g" B+ p
        if(dwSize != m_ClientNetConfig.wClientPackSizeArray[ubPackLocation]). C$ `+ H5 J. d# r% ?% z- U
        {' ?# O8 ?& z9 j$ ~, n. O7 T
            for( --ubPackLocation; ubPackLocation != m_ClientNetConfig.ubClientPackIndex; ubPackLocation--)
      Y$ n1 u3 n1 @8 j! \        {
    + ~% g. m' X% h' C$ j; k; e            if(dwSize == m_ClientNetConfig.wClientPackSizeArray[ubPackLocation])
    ) c" Z, G- w& G/ [! Z! Z/ Z            {# }- c" D% H8 \/ v, F. _
                    // Found valid size in the array.
    5 m* H! Z4 V7 @0 _6 l                fFoundSize = TRUE;
    ! I7 Y; G0 S$ M5 B# w7 Y7 A3 C                break;0 }6 Q2 ?! |4 _3 p( `4 g1 o
                }
    - J4 j  P: [9 E8 b' y            if(ubPackLocation &gt;= PACK_ARRAY_SIZE)  ubPackLocation = PACK_ARRAY_SIZE;  //Wrap the array.
    * A/ b6 E$ c, w' e9 j, D        }
    , S( n8 ]( O2 Y    }/ S  }( M2 A. W. ?2 C0 v% [
        else
    % {: R. f: M+ S8 i8 q% {    {
    7 T0 U4 q* ~6 P& t- q" @! W/ p        fFoundSize = TRUE;
    4 G/ `( J9 X" Z% M5 W    }</P>* a/ f; x: z: n
    <P>    return fFoundSize;
    # L2 X8 x8 D! A6 ]0 S; `1 k}</P>
      `" E7 z$ `- k5 a" w( @9 H<P>
    . h5 {# Z9 \; S  o, N//-----------------------------------------------------------------------------
    ; S6 w, \) }" }0 J// Name: , P2 B1 v# W$ Q& q
    // Desc:
    ) w, v2 o9 J: B  X) I0 [& R! Q//------------------------------------------------------------------------------ u* A  G! y% `% F$ f3 w2 ~2 V2 B6 S
    void CMazeServer::OnSessionLost( DWORD dwReason ), t1 d4 U. n$ r) p3 p0 v0 j& h
    {7 c+ r3 U8 F' Z
        ConsolePrintf( SLINE_LOG, TEXT("ERROR! Session was lost") );! {( _/ l- \9 H
    }</P>
    1 S: p. b4 U; z# a* W- W+ ]" p+ p; [* m. {9 ]/ M
    <P>7 q5 p4 w$ _8 p6 z" T/ D
    //-----------------------------------------------------------------------------5 S* r% I. ~: L' K
    // Name: 2 P: C, @4 p, z2 j
    // Desc: % `$ B, k. F$ [. X1 A# Y
    //-----------------------------------------------------------------------------
    6 w9 a) P5 G' {: T0 j8 \' }: _6 bPlayerData* CMazeServer::CreatePlayerData()9 K' B5 ?/ D+ k( p. B
    {5 O8 w0 b  q/ \
        m_PlayerDataListLock.Enter();</P>
    * }# r% v  A8 A, U: s<P>    // Grab first free player in the list
    - y  W6 M- d. K1 o    PlayerData* pPlayerData = m_pFirstFreePlayerData;</P>+ Q2 g: N+ x: Y6 ^" C0 b
    <P>    if( pPlayerData )# _' p2 G5 T6 v
        {& m% G. I  q  s
            LockPlayerData( pPlayerData );</P>/ w5 \3 N" R* S) ^8 T8 E$ L$ A
    <P>        // Got one, so remove it from the free list
    + e8 b" I1 y+ h, E        if( pPlayerData-&gt;pPrevious )
    " Q: |# c1 D7 ^+ F            pPlayerData-&gt;pPrevious-&gt;pNext = pPlayerData-&gt;pNext;) m$ N7 s; \! L; ]2 _0 P& M
            if( pPlayerData-&gt;pNext )
    & u1 v7 j2 a, y            pPlayerData-&gt;pNext-&gt;pPrevious = pPlayerData-&gt;pPrevious;
    2 z) T7 l; q# w, _" o8 T        m_pFirstFreePlayerData = pPlayerData-&gt;pNext;</P>' E) A- X) d/ t0 b5 h* r8 D' |5 }
    <P>        // Add it to the active list$ k" U4 |7 U9 {
            if( m_pFirstActivePlayerData )5 {% H3 g* Y( o0 q7 P$ S! t
                m_pFirstActivePlayerData-&gt;pPrevious = pPlayerData;
    ( u. [4 L" z5 G) F& h, t3 }        pPlayerData-&gt;pNext = m_pFirstActivePlayerData;
    + R) n$ d4 c4 P6 Q. P        pPlayerData-&gt;pPrevious = NULL;* q5 U# b. |7 X& Y2 t. c; `
            m_pFirstActivePlayerData = pPlayerData;</P>
    ) D2 A9 e4 A$ @( x<P>        // Update count of players
    : O% G8 V' T5 o& Y" N4 e$ }        m_dwActivePlayerDataCount++;</P>
    " {5 ]  `+ a5 I) |/ c+ X* m<P>        // Generate the ID for this player$ r5 T4 T, E# Y+ g
            m_dwPlayerDataUniqueValue++;
    : u. k6 C1 L. s* u) @8 s( W8 S        pPlayerData-&gt;dwID = (DWORD) ((pPlayerData-m_PlayerDatas)|(m_dwPlayerDataUniqueValue&lt;&lt;PLAYER_OBJECT_SLOT_BITS));</P>
    9 Y% ~8 v) I7 M. _8 c" t% K<P>        pPlayerData-&gt;pNextInIDHashBucket = NULL;
    % v" ]& w- v. B: M' Y6 J9 u7 C        pPlayerData-&gt;NetID = 0;
    4 G- Z3 B; Z$ V. M0 u        pPlayerData-&gt;dwNumNearbyPlayers = 0;</P>2 x2 t# A6 o* e1 {. r: _
    <P>        // Insert into the "off-map" cell+ h9 `9 B, l4 x+ P3 n3 a/ w) Q" h7 a) }  E
            pPlayerData-&gt;fPosX = pPlayerData-&gt;fPosY = -1;9 f. y8 R( G9 \" D3 j8 i
            pPlayerData-&gt;wCellX = pPlayerData-&gt;wCellY = 0xffff;% u$ ~2 v& t1 l% A! ?! h+ p; i
            m_OffMapLock.Enter();* F  q5 Y" u$ B7 p' v: ~
            pPlayerData-&gt;pNextInCell = m_OffMapCell.pFirstPlayerData;
    3 B, Y+ i) o" A# F        m_OffMapCell.pFirstPlayerData = pPlayerData;8 |( {. p. x) |9 P, d0 ~  d
            m_OffMapLock.Leave();</P>
    4 R* F, \7 x0 z$ K  v<P>        // Mark as active* l/ H0 E9 H# T  H
            pPlayerData-&gt;bActive = TRUE;</P>
      w, G% v* `2 i! S<P>        UnlockPlayerData( pPlayerData );
    - R) t2 `$ `7 F4 q, @    }</P>
    ( t+ H9 o0 L/ {<P>    m_PlayerDataListLock.Leave();</P>. R; ?$ E8 V( T1 m5 [
    <P>    return pPlayerData;# L6 t& Y2 s- q/ ~8 f+ _7 A4 Z( N: E
    }</P>
    ( X5 n) x  Y" c  n% W( ]  @# I7 y5 X, q/ g' L, C6 v+ s
    <P>
    - a; u( n6 T* S//-----------------------------------------------------------------------------
    6 Q" f: C4 v1 j' Z5 |  a# W0 i! e// Name: ; N- B( V7 R7 w( z5 Z# e+ @: N/ A
    // Desc: 2 K7 ]" J! r) g; o1 w3 o% M
    //-----------------------------------------------------------------------------
    * c4 k$ V( d3 y% }) Nvoid CMazeServer:estroyPlayerData( PlayerData* pPlayerData )
    ; o+ |; c3 Y2 H% i6 k{
    6 q) n$ ?! m+ i" g- ]! f' I    m_PlayerDataListLock.Enter();
    . B) ^8 B/ W( M8 D2 I0 I6 E& O# W. D: V    LockPlayerData( pPlayerData );</P>- K2 @, l7 R) A
    <P>    // Remove the player from its cell% [- d) j% f3 V& y* h
        RemovePlayerDataFromCell( pPlayerData );</P>
    & ]8 w6 m- P/ t& G1 d<P>    // Mark as inactive
    8 |! _3 ^. [' i( Q3 ^* {0 C( d    pPlayerData-&gt;bActive = FALSE;</P>
    0 ~$ s& x% ]2 F" z3 O# j+ C) T) m<P>    // Remove player from active list
    % ]! C! G+ B" h( N: X; V# I2 G' }    if( pPlayerData-&gt;pPrevious )4 ^  E! F) H7 b/ d! x0 e, F
            pPlayerData-&gt;pPrevious-&gt;pNext = pPlayerData-&gt;pNext;5 v8 n$ m: D7 a
        if( pPlayerData-&gt;pNext )* u9 h3 H  y1 P- c' L; Q
            pPlayerData-&gt;pNext-&gt;pPrevious = pPlayerData-&gt;pPrevious;</P>
    : d+ m3 h9 }! Z. E& E& o, S<P>    if( m_pFirstActivePlayerData == pPlayerData )% z8 \# V2 }& H7 f2 s7 m
            m_pFirstActivePlayerData = pPlayerData-&gt;pNext;</P>
    , j! P4 M# h9 O4 A<P>    // Add it to the free list
    3 ]. R/ L5 s/ z4 @. o! T/ e    if( m_pFirstFreePlayerData )
    - M2 ~: N9 X' S( r; u; }        m_pFirstFreePlayerData-&gt;pPrevious = pPlayerData;
    2 b) i; H3 _; f    pPlayerData-&gt;pNext = m_pFirstFreePlayerData;5 J0 J  H* }* g
        pPlayerData-&gt;pPrevious = NULL;
    9 ]) \! L6 `3 d- k    m_pFirstFreePlayerData = pPlayerData;</P>* |2 ]/ l3 f: U0 e5 D* ?
    <P>    // Update count of players: e% Y/ p4 @8 k* c8 k" O, ~
        m_dwActivePlayerDataCount--;</P>
    6 C* g" N  C& x3 i<P>    UnlockPlayerData( pPlayerData );; ^: J; A; a/ A, F1 W
        m_PlayerDataListLock.Leave();
    / d5 o* X% f/ I+ Q}</P>
    ; G2 k& q! ^) D+ S* K$ j9 e5 C1 w" x& b
    <P>
    : H2 e7 c8 T5 ]8 `. o5 ?//-----------------------------------------------------------------------------
    9 m  r7 J' Q0 y7 T/ E// Name:
    5 P: w! e* e' o$ |+ }( w6 A+ F// Desc: 3 x, D4 \! ~# [5 c  p; O$ O  Z
    //-----------------------------------------------------------------------------: G5 z  V, D4 X- O, ]2 B% R( {+ B
    void CMazeServer::RemovePlayerDataFromCell( PlayerData* pPlayerData )
    7 b- o% Q! x6 x# L{/ [6 w) ?* r& t
        // Lock the player
    0 w/ M, z$ g7 A& l/ K    LockPlayerData( pPlayerData );</P>9 e- |( E3 l/ `) f1 ~4 N
    <P>    // Lock the cell the player is in
    1 V: x9 i  N9 e. N    ServerCell* pCell;  u2 `7 z& @# |8 d* v9 C2 ]
        if( pPlayerData-&gt;wCellX == 0xffff )
    2 ^  T' u/ N  p/ \    {
    * R. ^8 S- _6 `: C6 v" u8 T        m_OffMapLock.Enter();6 M) h2 c3 J' d( p/ c1 @
            pCell = &amp;m_OffMapCell;5 G0 K$ V* a& s4 j8 V
        }
    ! \( F( F- t7 U( h9 U    else
    + S" D5 G# x1 C2 {    {
    # B" n8 ~8 u( R5 D- w% Q        LockCell( pPlayerData-&gt;wCellX, pPlayerData-&gt;wCellY );
    + b& ~7 n. V+ A) i2 w8 l        pCell = &amp;m_Cells[pPlayerData-&gt;wCellY][pPlayerData-&gt;wCellX];
    : \: h7 W$ w4 I3 Y. c, T    }</P>* G2 d3 ]6 E& j0 V0 ?( X
    <P>    // Remove it from the cell
    $ C. ^3 A0 C5 V& z: `    PlayerData* pPt = pCell-&gt;pFirstPlayerData;
    7 R) u" o! X2 r    PlayerData* pPrev = NULL;, C# k: Q8 }  E: h
        while ( pPt )0 J" g( G% U  D. V4 O
        {% C( j& m- A! h  @. F
            if( pPt == pPlayerData )( h( J$ }" e. d; C. d' Z- }
            {
    1 c4 l7 S+ B8 J8 t# J" z2 c4 w7 @( @            if( pPrev )5 G# P! r7 t7 q0 J4 `8 D$ A
                    pPrev-&gt;pNextInCell = pPlayerData-&gt;pNextInCell;
    1 Z7 L' |" l$ U; g& s& @            else( H! q" L/ u2 t9 X) B
                    pCell-&gt;pFirstPlayerData = pPlayerData-&gt;pNextInCell;</P>
    7 B& v$ Z! f/ j+ K$ U& j$ G3 @# V<P>            pPlayerData-&gt;pNextInCell = NULL;* p- K' Z. r2 {4 ?% T. i/ I
                break;
    * Z) e+ e- J, z  h4 j        }3 t- i6 T+ j: T2 H
            pPrev = pPt;
    + i, ?" w  ?7 H" ]: k2 V) m8 D  v6 ]        pPt = pPt-&gt;pNextInCell;
    ! _' c5 f3 g$ X$ z3 F    }</P>3 w* S& ?! Y, H2 s. C; z) n
    <P>    // Unlock the cell
    ! N9 b( u9 X) z  U: }% [% ~    if( pPlayerData-&gt;wCellX == 0xffff )  |  N1 T! Q& v
            m_OffMapLock.Leave();& n( K" n% I# {% j
        else
    ' b0 A7 X) v, d        UnlockCell( pPlayerData-&gt;wCellX, pPlayerData-&gt;wCellY );</P># \5 k7 l8 Q! u5 [9 \
    <P>    // Unlock the player
    ( f( s! m, P) Y/ O    UnlockPlayerData( pPlayerData );
    3 U1 P$ P1 c! g+ g8 r( |}</P>% U2 U8 C7 d) V: l/ _" V
    % ~5 {9 ~1 m) b& ?
    <P>& q, C9 U, d$ @" s" q2 l
    //-----------------------------------------------------------------------------
    ( O1 O- d" C1 v" ?+ U- H3 M; `* \// Name:
    - S/ b* b9 {5 W// Desc:
    " H/ s7 C" Z# u; O; Q1 L. g//-----------------------------------------------------------------------------, }2 z3 O6 V4 r# q; }9 W
    void CMazeServer::UnsafeRemovePlayerDataFromCell( PlayerData* pPlayerData )& @; H7 d/ Q* w# [
    {
    , a9 K3 Z- ^% }2 t' K( ~8 }    ServerCell* pCell = GetCell( pPlayerData );# w; w1 L; s5 X2 e: S" `5 D
        PlayerData* pPt  = pCell-&gt;pFirstPlayerData;) l. H8 P4 K5 |) t- @$ K8 q/ e
        PlayerData* pPrev = NULL;; l7 j) I% V/ o/ G
        while ( pPt )
    " Q9 t2 s1 s% R: a. G) ?) E    {
    : R3 O* L1 L. C- f        if( pPt == pPlayerData )
    ) F2 l4 C9 u' y$ o+ L        {8 C$ G6 E( _7 O6 o
                if( pPrev ): g- [, ^% l* f1 V. r9 T1 A: F
                    pPrev-&gt;pNextInCell = pPlayerData-&gt;pNextInCell;
    8 `  {: V0 g& |9 l' d0 O+ n            else- V2 N  j, J! F) F
                    pCell-&gt;pFirstPlayerData = pPlayerData-&gt;pNextInCell;( _- _. D8 r6 s
                pPlayerData-&gt;pNextInCell = NULL;
    : K  U8 S6 ^' [3 D            break;
    9 e3 Q$ a, g0 U- f3 _5 m) M        }3 Y" g4 T/ S/ s/ }
            pPrev = pPt;
    / i/ R9 y; R- C! R: [        pPt = pPt-&gt;pNextInCell;
    % g' {6 r# ^# u. h* }) g: ^    }: }6 N( {7 y# {( o2 k) F
    }</P>
      S9 p4 B1 u# b5 R# m! |9 ^  x0 Z# v. h8 }, L! R# M8 }/ n& `" p
    <P>% ^$ u9 ~* j" R; S
    //-----------------------------------------------------------------------------; {# W$ R0 q* }0 y% c
    // Name:
    5 A$ t2 E7 `3 H$ C// Desc:
    9 N7 Y- K$ g/ {2 G//-----------------------------------------------------------------------------
    - R+ b/ i+ M4 K- [+ qvoid CMazeServer::UnsafeAddPlayerDataToCell( PlayerData* pPlayerData )
    6 L9 J; i* H* a, P1 L{
    # I7 c/ k/ J8 Z: c" z    ServerCell* pCell   = GetCell( pPlayerData );, m5 U  s3 N6 O; O; @
        pPlayerData-&gt;pNextInCell = pCell-&gt;pFirstPlayerData;$ Z, R9 S9 k  A: f) O6 O1 {; z( _5 k
        pCell-&gt;pFirstPlayerData = pPlayerData;
    + r! I; E, z% R" t; n! V. H4 D' p}</P>3 F" H( \: T; J# |3 M

    ( A" j( C, j1 m) x<P>4 \  U# e# _. {  a" V, N0 N; m
    //-----------------------------------------------------------------------------! ]7 x  V) ?! Y* `. H# H
    // Name: 9 a9 J( {2 Z" T& \( f
    // Desc: , x2 a: l9 s1 M2 X" }2 M5 j, C
    //-----------------------------------------------------------------------------9 s3 [3 x5 z# |# c* B9 U! h  B
    void CMazeServer::HandleClientPosPacket( DWORD dwFrom, ClientPosPacket* pClientPosPack )
    . G8 Y6 B1 j- {- f- f/ ~* o3 x9 [7 S{
    9 c* }6 y( F4 d. {) l# p+ H# \- Z* E    // Grab player for this client and lock it
    7 y- h' P8 n( E/ Y) i  Q    PlayerData* pFromPlayer = GetPlayerDataForID( dwFrom );' B2 W: a0 n: e
        if( pFromPlayer == NULL ): ^* C4 t' C3 B0 Q" K# s8 Q
        {. Q5 g8 v' a0 C
            if( m_dwLogLevel &gt; 1 )
    ( h' |4 d0 ?+ T            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Could not find data structure for this player"), pFromPlayer-&gt;NetID );: u, E3 g: K( O" F0 \
            return;
    7 S* D" s/ x2 }    }</P>
    8 m+ j  w  i, q2 W) h<P>    LockPlayerData( pFromPlayer );</P>
    / ~4 q( @! ^  i<P>    if( FALSE == pFromPlayer-&gt;bAllow )4 @' z5 T9 u7 H& b+ d" X
        {" m' p* Q9 m7 B' w" J
            if( m_dwLogLevel &gt; 0 )
    ; j5 [4 h( C% ]0 g  ?. p3 a            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Got position packet from bad client.  Rejecting client"), pFromPlayer-&gt;NetID );</P>
    4 g! \! M4 U9 _<P>        m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );
    3 n- Z, e+ {% D2 _! F        UnlockPlayerData( pFromPlayer );
    6 b7 z( `/ L9 @/ a        return;
    8 Q  C  D( k6 B! j0 ]    }</P>
    : Q) p$ }5 k) ^: \4 v4 u<P>    // Compute the cell the player should be in now& c& s* ?% `$ W/ N3 K, w' n6 S
        DWORD newcellx = int(pClientPosPack-&gt;fX);& p, [7 M, }% r
        DWORD newcelly = int(pClientPosPack-&gt;fY);4 J  T  Z* E4 D8 t- i$ A
        DWORD oldcellx = pFromPlayer-&gt;wCellX;  K5 Z( Q; M, h% U9 \
        DWORD oldcelly = pFromPlayer-&gt;wCellY;</P>
    2 j) X! Y1 D3 k! x: W<P>    // Have we moved cell?
    2 h: }* m: H% q1 j    if( newcellx != oldcellx || newcelly != oldcelly )
    7 b! I! L% ^% W0 J    {
    " O3 p$ D) T0 o0 b8 m        // Yes, so lock the pair of cells in question
    . V) S: Z! ^0 I' s+ c        LockCellPair( oldcellx, oldcelly, newcellx, newcelly );</P>3 v+ G: g( o  |8 q5 M  t! N( v; g
    <P>        // Remove from old cell and add to new cell
    ! n0 u& |8 a3 |4 L- D        UnsafeRemovePlayerDataFromCell( pFromPlayer );$ G* c, C) ], J' k4 U
            pFromPlayer-&gt;wCellX = WORD(newcellx); pFromPlayer-&gt;wCellY = WORD(newcelly);1 o1 {, P  I  o, o$ w
            UnsafeAddPlayerDataToCell( pFromPlayer );</P>
    8 E& u2 O8 a% {$ w" l( p<P>        // Unlock cells# x3 u4 x1 D- c: V' r
            UnlockCellPair( oldcellx, oldcelly, newcellx, newcelly );
    ! f/ G2 C# X' P- q9 u; l    }</P>. S# G4 J3 F2 G% F" O0 @: @$ a" h- `
    <P>    // Update player position
    & B3 t. N" i3 d7 E    pFromPlayer-&gt;fPosX      = pClientPosPack-&gt;fX;
    0 R( f4 E+ r% J& P    pFromPlayer-&gt;fPosY      = pClientPosPack-&gt;fY;8 Z* L! i9 U! f3 {$ r
        pFromPlayer-&gt;aCameraYaw = pClientPosPack-&gt;aCameraYaw;</P>
    * ^5 O5 Z( E6 C% ]<P>    // Allocate space to build the reply packet, and fill in header
    + K" E! ~5 b3 A3 U& l! E* M1 j( R    DWORD dwAllocSize;
    - y* k" d1 s* r# B( y    ServerAckPacket* pSvrAckPack = NULL;</P>
    * ]: Q# w+ P; Q<P>    // Begin by allocating a buffer sized according to
    + ~: V* K5 r$ w- [' P; {# C+ [2 J    // the current number of nearby players + 4.  This will give
    & B- C$ u( [3 `5 T! Z    // a little room for more players to come 'near' without resize
    ! g1 O2 X; O9 o; x/ ]    // the buffer.
    . J9 C. ~3 ~5 q4 A: ?6 D+ ]    DWORD dwMaxPlayerStatePackets = pFromPlayer-&gt;dwNumNearbyPlayers + 4;</P>: @: h# ~* S5 }  [0 w
    <P>    dwAllocSize = sizeof(ServerAckPacket) + dwMaxPlayerStatePackets*sizeof(PlayerStatePacket);
    , r! A' B+ j& Q  `7 w) d    pSvrAckPack = (ServerAckPacket*) realloc( pSvrAckPack, dwAllocSize );7 F3 q+ R' p( h% ^3 [3 x
        if( NULL == pSvrAckPack )
    ) S+ I/ [- g+ @5 W& }. k    {
    ( r; Y2 u% d( q4 K( \        // Out of mem.  Cleanup and return' C8 W# I& i  `3 m7 }& N' l
            UnlockPlayerData( pFromPlayer );
    2 l' K, t( J! O5 ~0 g3 \& W: V        return;       . d4 v. ?6 X- {/ H/ Z, P7 ~
        }1 \( x4 T0 d2 f$ O4 O3 g
        ZeroMemory( pSvrAckPack, dwAllocSize );</P>
    0 i3 w# N  [0 }- V<P>    *pSvrAckPack = ServerAckPacket(m_dwPlayerCount);( J" d1 |% z7 |
        pSvrAckPack-&gt;wPlayerStatePacketCount = 0;, l3 J1 \& ?9 J+ I. i/ V
        PlayerStatePacket* pChunk = (PlayerStatePacket*)(pSvrAckPack+1);</P>4 Q0 _! p+ a; d: i
    <P>    // Compute range of cells we're going to scan for players to send
    ) z9 U' t. B- j9 \    DWORD minx = (newcellx &gt; 7) ? (newcellx - 7) : 0;1 a) E$ O5 p  p4 _" M6 t7 O7 q' u
        DWORD miny = (newcelly &gt; 7) ? (newcelly - 7) : 0;* g5 X% l6 ]  ?* B
        DWORD maxx = (newcellx+7 &gt;= m_dwWidth) ? m_dwWidth-1 : newcellx+7;) Q8 l; _* [+ b: M/ c2 M
        DWORD maxy = (newcelly+7 &gt;= m_dwHeight) ? m_dwHeight-1 : newcelly+7;</P>/ V% z! B2 Q9 [
    <P>    // Lock that range of cells5 R* j$ `6 d* K9 i* f
        LockRange( minx, miny, maxx, maxy );</P>
    7 |) I# ^5 ]! N! d8 X6 Z<P>    // Scan through the cells, tagging player data onto the end of
    6 l$ ]2 l* v( y3 `    // our pSvrAckPacket until we run out of room
    ! y; ?  P8 ^9 H, Q9 o- z- P2 g" \# O% V; _    for( DWORD y = miny; y &lt;= maxy; y++ )
    . ~$ C: ?, J, J1 b& n    {! O3 Y9 j* `! l$ h
            for( DWORD x = minx; x &lt;= maxx; x++ )7 i( e$ S8 f0 X1 Q, i& F# q5 w
            {2 x7 n) E" t" @! u  C3 Y: f5 P
                PlayerData* pCurPlayerData = m_Cells[y][x].pFirstPlayerData;% Y2 v9 c0 g4 S
                while ( pCurPlayerData )
    $ g+ Y" v, ?* u  z4 |            {
    ' }& s& r, I3 Y. n0 u8 P2 z0 \                if( pCurPlayerData != pFromPlayer )1 X3 Q- M3 ^: K- ~+ S) P
                    {* E8 D& B# T5 v, c7 f  L. D
                        if( pSvrAckPack-&gt;wPlayerStatePacketCount &gt;= dwMaxPlayerStatePackets )
    ( B) D. p( a' @/ m                    {8 C) X  E5 N4 ^  P$ L+ e: h
                            // Make sure pChunk is where we think it is! l) e8 l9 O# H$ i7 Y
                            assert( (BYTE*) pChunk == (BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket)) );</P>
    $ j/ ]8 r: x+ J9 C7 l<P>                        // There are more than just 4 new nearby players, so resize the
    . u# m( r( b. }6 u) \0 T                        // buffer pSvrAckPack to allow 16 more PlayerStatePacket's.
    " [9 c) n- w) B# x7 z                        dwMaxPlayerStatePackets += 16;
      X6 e" }1 C7 O4 Q, k8 k                        dwAllocSize = sizeof(ServerAckPacket) + dwMaxPlayerStatePackets*sizeof(PlayerStatePacket);8 E& [6 ]. @7 {7 W
                            ServerAckPacket* pNewSvrAckPack = NULL;0 m; n' r; T% t+ ?  J) i+ }
                            pNewSvrAckPack = (ServerAckPacket*) realloc( pSvrAckPack, dwAllocSize );+ p4 i. I+ U+ m
                            if( NULL == pNewSvrAckPack )0 E) C5 b, l  r2 [
                            {
    $ A( [& i, y8 q$ _                            // Out of mem.  Cleanup and return# l: V3 \0 i/ [0 d
                                free( pSvrAckPack );* M, @2 b# U- `! }% b, P9 P6 O4 I
                                UnlockRange( minx, miny, maxx, maxy );
    + F, c5 p# A3 D6 L5 `/ T                            UnlockPlayerData( pFromPlayer );
    $ H6 ]9 y  I8 G6 S                            return;       * X& U$ v6 ?: ~$ e' Z
                            }</P>$ Q8 H% t0 y! D$ z; o( p( t
    <P>                        pSvrAckPack = pNewSvrAckPack;
    ( Z" D. y8 K3 @# f0 Z                        pChunk = (PlayerStatePacket*) ((BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket) ) );</P>8 x0 P+ `" I+ P! D6 d
    <P>                        // Make sure pChunk is still where its supposed to be
    5 z/ w% k/ G: L7 B                        assert( (BYTE*) pChunk == (BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket)) );
    ; B8 A5 K& g1 q+ R* I                    }</P>
    8 U0 i1 o# o/ V1 W! F<P>                    pChunk-&gt;dwID       = pCurPlayerData-&gt;dwID;
    + v& }) Z: W+ \& K  [                    pChunk-&gt;fX         = pCurPlayerData-&gt;fPosX;/ S* r/ ~, u# C$ |$ C. E; B
                        pChunk-&gt;fY         = pCurPlayerData-&gt;fPosY;/ [& [2 q5 R  u4 ]
                        pChunk-&gt;aCameraYaw = pCurPlayerData-&gt;aCameraYaw;, ]4 f; j( V% F) f4 T5 R
                        pChunk++;, {& ]( |1 ^) P0 l! l6 d  j; @
                        pSvrAckPack-&gt;wPlayerStatePacketCount++;, j/ W2 ^: E' F8 U$ _
                    }
    ( s2 L/ N4 Y8 m  ?) G% q. o                pCurPlayerData = pCurPlayerData-&gt;pNextInCell;) g% D$ R/ h' I0 W7 g" }
                }
    # Y# O, g  k1 [5 d2 ^& Q# [        }8 y$ C4 l5 [6 _1 O8 K* q0 ]" ^
        }</P>, b1 b, `7 v8 o: p
    <P>    // Update the dwNumNearbyPlayers for this player
    ; b1 C% U) j8 B' H6 |    pFromPlayer-&gt;dwNumNearbyPlayers = pSvrAckPack-&gt;wPlayerStatePacketCount;</P>
    6 X( s. M. b% U& C4 \<P>    // Unlock range of cells& U' ^+ q$ i$ @, m4 q+ h' u
        UnlockRange( minx, miny, maxx, maxy );</P>
    1 H, W0 _& a8 q+ Y<P>    if( m_dwLogLevel &gt; 2 ), ?, w$ q  ?( z" l1 n! j' T
        {
    : o" {! J- {+ i7 x( P) o        ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Position is (%0.2f,%0.2f)"), pFromPlayer-&gt;NetID, pFromPlayer-&gt;fPosX, pFromPlayer-&gt;fPosY );- y7 Q& I2 v$ u8 y  U% ~. L' }
        }& N4 G7 z; B9 u: L! O
        else if( m_dwLogLevel == 2 )" @+ M. T: @2 p7 _
        {
    " ]# c) V4 E- o6 l        FLOAT fTime = DXUtil_Timer( TIMER_GETAPPTIME );$ c1 S4 g2 K% M# \, N" r: M5 K! s
            if( fTime - pFromPlayer-&gt;fLastDisplayTime &gt; 60.0f )
    3 F' `- G- q4 k        {  k3 w  r: Y7 \7 N3 ?# ]
                ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Position is (%0.2f,%0.2f)"), pFromPlayer-&gt;NetID, pFromPlayer-&gt;fPosX, pFromPlayer-&gt;fPosY );+ E( G) X% t6 Z
                pFromPlayer-&gt;fLastDisplayTime = fTime;4 V/ F/ R6 ^: w' K; F% Q+ K
            }
    . G5 c: C- P1 W2 @! q5 j/ e    }</P>
    1 R! l$ U$ k- k& G. M1 |; T/ d<P>    // Unlock the playerdata
    : e0 H9 A- D, o" z  z) i; i    UnlockPlayerData( pFromPlayer );</P>
    " w/ O) l8 D9 }2 |: |/ V<P>    // Send acknowledgement back to client, including list of nearby players / R. I& S6 X  a. V5 P! q! [! Y9 R+ h0 ?; e
        DWORD acksize = sizeof(ServerAckPacket) + (pSvrAckPack-&gt;wPlayerStatePacketCount * sizeof(PlayerStatePacket));$ u5 h2 T, g, e. ^: D% N. h

    * G4 W# ?6 P) i6 I: D    // Pack the buffer with dummy data./ X9 i# h) F  f. E7 i) f
        if(m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex] &gt; 0)
    8 X  w- T: Y; R. c9 y9 g* N; O) X: p+ d    {' Y- O6 s8 n) n1 M+ n$ P, q5 K
            DWORD   dwBufferSize = acksize + m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex];  T0 r* b2 P0 x$ d9 b
            VOID*   pTempBuffer = 0;</P>
    7 q* E% g$ g: K+ r% j% W7 }<P>        pTempBuffer = malloc(dwBufferSize);
    6 ^7 q& f0 L! b2 ~2 W- F        if( NULL == pTempBuffer ). ]* N" c6 t6 L3 D7 l1 E
            {! ?! M; J6 g. O' j6 t/ w1 v  n
                //Out of memory
    5 j( M  B, W) q$ Z$ T# L: Z            DXTRACE_ERR_NOMSGBOX( TEXT("System out of Memory!"), E_OUTOFMEMORY );; z; g! v  W& m6 l* k
                free( pSvrAckPack );
      g. Z0 T# E1 U2 y, E; B' ~            return;) Q, X( R/ {+ f( u! [# `
            }</P>
    / P1 ?2 b/ ]: \/ Q! i& D$ B/ F<P>        FillMemory(pTempBuffer, dwBufferSize, 'Z');+ w8 B8 i1 `; D, H8 t
            memcpy(pTempBuffer, pSvrAckPack, acksize);</P>; J) _6 x  z# v) k  P
    <P>        SendPacket( dwFrom, pTempBuffer, dwBufferSize, FALSE, m_dwServerTimeout );4 ^7 j, U% J- I1 x" k% K+ N# L
        & \# }* g- H8 L" S0 m: Z
            free(pTempBuffer);
      @) t3 E* d" ~, m5 Q" G    }   4 X8 d+ }' Y" R2 a9 c/ r, S
        else) F7 [( Z# u  M' J/ s
        {
    # z+ w' }0 v# `7 w# U        SendPacket( dwFrom, pSvrAckPack, acksize, FALSE, m_dwServerTimeout );" l/ G* f  {( C, |7 u' v# Z( @
        }</P>
    * J+ I8 G1 n, @# y: ?<P>    free( pSvrAckPack );</P>
    : S+ M% O" Q* J! D8 E<P>}</P>
    7 w2 T0 s8 e* ?' t" J1 x8 J" N7 d' J. W- }% s& c' {# W
    <P>
      x; {: V2 q3 v9 Z//-----------------------------------------------------------------------------
    2 U; L  S3 X: u// Name:
    ( m; |% N& `$ s4 C& {; z* S9 a% h0 d) R! ~// Desc: 2 P( h- x3 w+ q' t/ U% ^
    //-----------------------------------------------------------------------------" A& ~+ {6 ?, `" E6 o
    void CMazeServer::HandleClientVersionPacket( DWORD dwFrom, ClientVersionPacket* pClientVersionPack )
    ! E$ j0 R, o/ Z) S$ W& e: Q{1 \: |, v$ B& t( j, c# f0 f, F7 f
        // Grab playerdata for this client and lock it4 ]7 y- X  c& ^0 g' K- L3 w
        PlayerData* pPlayerData = GetPlayerDataForID( dwFrom );
    , C1 V9 n! X1 ~    if( pPlayerData == NULL )
    6 \* K7 F* w# m% Q' I        return;8 v3 h: B& P$ K3 `: k
        LockPlayerData( pPlayerData );</P>
    & b1 `( r9 i8 A! z<P>    // Record the version number
    3 b$ s9 e2 t; u" d) }    pPlayerData-&gt;dwVersion = pClientVersionPack-&gt;dwVersion;</P>
    & K* t+ h7 w" g! g5 t<P>    if( m_bLocalLoopback )% g0 a! `" h  O
            pPlayerData-&gt;bAllow = TRUE;, s4 i+ L6 {' q. w2 W7 X/ M
        else- ^6 R% s# I# b3 ^$ s; B, f
            pPlayerData-&gt;bAllow = IsClientVersionSupported( pClientVersionPack-&gt;dwVersion );</P>- }$ r$ p, O7 w- }, x8 Z8 D
    <P>    if( m_dwLogLevel &gt; 0 ), r2 \. n! i8 I- g7 h
            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>
    2 X: |3 U# [, H9 D" }* W3 J# o) L<P>    if( FALSE == pPlayerData-&gt;bAllow )
    7 M% |7 T: f6 F    {( M3 `5 b# e2 V  `! v: q4 g
            if( m_dwLogLevel &gt; 0 )
    ( d0 X+ r7 X8 @' ^$ g1 U            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Rejecting client"), pPlayerData-&gt;NetID );</P>" n8 }5 |0 z- E) S- I' Q
    <P>        m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );. J; k' n) s# w# b8 w% p/ a# u+ W! Q
            UnlockPlayerData( pPlayerData );( Z+ Y7 A1 f1 s* N) D
            return;: `: Y9 p6 Y0 V, _# `' W
        }</P>
    9 ^" D, N% h) T; |$ u' z0 v$ [<P>    // Unlock the playerdata( c" ~; p5 N- A) a2 M+ f: U
        UnlockPlayerData( pPlayerData );</P># [8 S6 ~6 Z; y
    <P>    // Send acknowledgement to client that the client was either accepted or rejected3 G% C& S" V5 A
        ServerAckVersionPacket packet( pPlayerData-&gt;bAllow, dwFrom );% o' l8 c( j; k6 T
        SendPacket( dwFrom, &amp;packet, sizeof(packet), TRUE, 0 );( Z5 l! g- ~3 W" `% B
    }</P>
    5 M. \1 k- A" G
    : O1 ~4 d. I2 H0 s<P>9 r$ X1 {0 h  H( L; ?
    //-----------------------------------------------------------------------------3 e. Z# m0 |, N  q) }! ?$ c3 w9 M3 l1 R
    // Name:
    : Q4 ?6 E4 q7 E; G& Y// Desc: + {4 l4 V4 j3 S4 F) w, P3 M
    //-----------------------------------------------------------------------------
    * d3 E/ l; S6 M9 P0 ^6 IBOOL CMazeServer::IsClientVersionSupported( DWORD dwClientVersion )% M4 c& m# Y/ h% E* ~  W( {
    {" R' e) ?! }; y0 P* t/ f. r
        switch( dwClientVersion )
    % u0 U0 a! k% l, K; X# z    {" g! b1 L' i' L# _
            case 107: // only v107 is supported6 y9 Y6 u; d+ @, I
                return TRUE;+ q  d" a, x9 t! Y2 ]
            default:' R  y) r& Z& F# o- ?  A2 h2 d. Q
                return FALSE;( f9 H& ]* q$ g( y* _; ?5 O$ `
        }
    5 M# v4 ?$ m* w7 V. ]  h7 I}</P>9 J7 p6 x; t7 U6 u' r! p8 U
    $ d# T! A4 I& v' z4 ]! E1 A
    <P>% c6 ^8 y" A+ @/ C, d
    //-----------------------------------------------------------------------------& B: f% h; s6 T  T& \9 g; ~
    // Name:
    & ?0 e. w- C  U( M  \) {// Desc:
    # k- v8 ?! ^$ o" u//-----------------------------------------------------------------------------
    " D: |- m" G4 e$ Y1 i3 t0 W9 zvoid CMazeServer::HandleUnknownPacket( DWORD dwFrom, ClientPacket* pClientPack, DWORD size )
    % g6 X/ {( k3 f9 S{& E6 m" Y: R& w
        if( m_dwLogLevel &gt; 1 )
    * T- B+ x  E, Q9 N* e3 W6 r+ S- N        ConsolePrintf( SLINE_LOG, TEXT("ERROR! Unknown %d byte packet from player %0.8x"), size, dwFrom );</P>
      s9 X6 Z- A1 q$ u4 `; w- c<P>    m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );; r& \9 Z4 g- ?/ c6 p4 n+ J
    }</P>& s2 N) q% y+ W3 i2 n
    * W& |& W6 l7 e& v1 {# }. c4 I
    <P>
    + Q+ p6 ?) P; K+ m+ [//-----------------------------------------------------------------------------
    1 y7 r0 Z" g$ D% D// Name: 0 ]0 B# m0 B: v
    // Desc:
      Z* y2 C( l4 h0 K" @+ p//-----------------------------------------------------------------------------6 B) o7 h, R1 i
    DWORD   CMazeServer::IDHash( DWORD id )4 U) D8 q+ ?" C) c8 r# w% `
    {
    4 j7 [8 d1 ~+ m, `    DWORD   hash = ((id) + (id&gt;&gt;8) + (id&gt;&gt;16) + (id&gt;&gt;24)) &amp; (NUM_ID_HASH_BUCKETS-1);
    * i0 s; o! j2 X  A% M) C; G. [    return hash;
    : i/ \" [' n& D: [* @}</P>
    4 {( U" j- x3 Z8 q: `/ U* ?8 i) Z5 [2 U: [
    <P>  u$ n: ?9 b4 H- Y9 @% H& N
    //-----------------------------------------------------------------------------
    ) n7 [+ @. A3 g+ e. {8 n// Name:   o' {  O$ K" G* f( ~8 P* N
    // Desc:
    9 t" W7 k/ G: Y' Y//-----------------------------------------------------------------------------" l+ N0 M) L2 V: C$ E7 Q! {( z* f
    void CMazeServer::RemovePlayerDataID( PlayerData* pPlayerData )- K2 T/ R* E4 X! X
    {
    ; b* {0 _; }3 ^! l2 a; q: [4 }$ V2 H    // Hash the ID to a bucket number
    6 |$ A: H% P( G: X; O    DWORD   bucket = IDHash( pPlayerData-&gt;NetID );</P>0 z+ s# I# p1 P3 c
    <P>    // Lock that hash bucket9 ]7 a: E5 m/ [/ o4 z, @
        const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;) V# t8 K  }9 f: Y, Y- T' V
        m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>/ H5 y$ i3 n- ]0 q) x  f
    <P>    // Loop though players in bucket until we find the right one+ r2 n, S: R: x- _4 o. Z; ~
        PlayerData* pPt = m_pstIDHashBucket[bucket];* M5 {1 p  H. a- Z3 ^+ I9 [5 S5 x
        PlayerData* pPrev = NULL;. R1 l2 d+ O- Y8 i' r3 ^
        while( pPt )
    ' x, b$ G: ?+ H" L0 q9 f    {
    0 P+ m+ m# P0 c: V" o5 J+ {5 k        if( pPt == pPlayerData )
      g7 j/ J3 F3 B7 g4 ]; d( F            break;7 y0 w7 f4 g9 @( h; }' w) P  A0 G) L
            pPrev = pPt;
    : G( _" [) N% ?/ O        pPt = pPt-&gt;pNextInIDHashBucket;. ^5 b$ l0 k, R2 j
        }</P>
    5 C& G# _/ A, `, P<P>    if( pPt )  c: ^% z4 g. O0 O* }
        {. V0 o9 @. y9 }/ _: j
            if( pPrev )6 N. E* s0 o/ d) `$ i
                pPrev-&gt;pNextInIDHashBucket = pPt-&gt;pNextInIDHashBucket;; O3 X$ H- H% c
            else$ j9 A+ ~5 W" T. u
                m_pstIDHashBucket[bucket] = pPt-&gt;pNextInIDHashBucket;
    $ M1 m9 Z1 D1 J. M  i3 R  r        pPt-&gt;pNextInIDHashBucket = NULL;
    $ U# t2 b1 i$ ~+ K    }</P>
    0 e' X5 d8 O9 J: v' J<P>    // Unlock the hash bucket
    , {4 |1 ~) I8 b    m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();5 p9 h8 v% t7 b9 [: i
    }</P>9 S4 [% g. u* u& M8 h7 ?2 ]
    $ {! \! N: p6 d0 \
    <P>
    " ]- c, m+ P9 p2 X8 I6 ]//-----------------------------------------------------------------------------
    - D" k# v. [' v3 R! i5 [// Name: 1 H( L6 I! Q0 h8 A5 o, G
    // Desc:
    ) o* {& V/ w+ Z9 a//-----------------------------------------------------------------------------% V/ C2 q" U: D% ]5 H
    void CMazeServer::SetPlayerDataForID( DWORD id, PlayerData* pPlayerData )! s) c0 \3 Q& }& V/ O! h- A
    {
    ; K6 J$ D2 s9 y% N& U    // Make sure this player isn't added twice to the m_pstIDHashBucket[]3 C9 b' ~, L  i$ X! C+ n. v; Q
        // otherwise there will be a circular reference7 y* S" A. n5 j8 w5 o3 C7 \
        PlayerData* pSearch = GetPlayerDataForID( id );
    ' H% p) m  C' z! V' ~/ p' @    if( pSearch != NULL )
    6 P; p' C! z7 R        return;</P>
    . v, e8 f: J( s: f, Z4 _( x<P>    // Hash the ID to a bucket number
    % f$ U2 i. W, V. n$ f    DWORD   bucket = IDHash( id );</P>
    7 Y) p$ m  T% I' Q$ ?5 b, ^" e<P>    // Lock that hash bucket# V9 X2 L, s+ \' X
        const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;" i# l: R& Q7 Q, i2 `" g6 p) X& {
        m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>
    % H# J) ]; d* N& J# `9 Y- f7 d* E<P>    // Add player onto hash bucket chain
    ( Z4 f  e: O  H    pPlayerData-&gt;pNextInIDHashBucket = m_pstIDHashBucket[bucket];# ^# c6 P( h/ R: R1 \, ?  c
        m_pstIDHashBucket[bucket] = pPlayerData;</P>
    , e' D% v3 r% M, ~8 n, ^<P>    // Store net id in player! q9 F1 g7 t# T) x
        pPlayerData-&gt;NetID = id;</P>& R# A2 C# }+ x. _/ R% x
    <P>    // Unlock the hash bucket% `6 S: ^9 `6 d( H4 [- @6 E% G
        m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();
    + {' Y; F+ m2 e* O& U0 J}</P>
    0 t" Y5 Z6 |9 d8 z, Q" J3 S/ O% H, T$ y$ U+ d$ ?9 a. A  P9 p1 f
    <P>  W5 o& S4 O% K3 K' P7 q$ C
    //-----------------------------------------------------------------------------& d, S# ?  ]! {1 t  p( d$ @
    // Name: 6 \: Q- Q1 k' K/ \# }' W( I
    // Desc: 7 ]; m( F% A; \8 e) G: q2 n
    //-----------------------------------------------------------------------------
    % v$ _' |. {& c) RPlayerData* CMazeServer::GetPlayerDataForID( DWORD id )8 |9 T- h1 S  H) S
    {+ y+ |! \0 ^5 L- V) H) ]
        // Hash the ID to a bucket number
    . `/ x% f! P. u    DWORD   bucket = IDHash( id );</P>
    1 J# m- [) b- B<P>    // Lock that hash bucket  Z" _! e, A* {7 K8 Y' t0 P
        const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;& p  P9 S7 \  H1 t
        m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>4 ^8 s* x* \5 P0 x- b( w
    <P>    // Loop though players in bucket until we find the right one
    " G2 v# W$ ~; ?1 _; Q: c( H    PlayerData* pPlayerData = m_pstIDHashBucket[bucket];" O9 q! G/ ?' t2 F/ c2 L
        while ( pPlayerData )
    - a7 e$ d* ?0 L. m1 [  S2 F- ~    {5 l+ U7 N5 p3 v! @. X
            if( pPlayerData-&gt;NetID == id )+ Z# S  R, s9 M/ [/ P5 r7 x
                break;6 L! ^; k2 P3 f
            pPlayerData = pPlayerData-&gt;pNextInIDHashBucket;' C  {1 B  u' ?5 D, p
        }</P>6 R2 N. J; A' K" b% {
    <P>    // Unlock the hash bucket
    ! d5 o) T; |- T0 r; |/ C    m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();</P>: R5 a0 P/ {1 X
    <P>    // Return the player we found (will be NULL if we couldn't find it)4 \; f4 a5 _: C# K: j* N
        return pPlayerData;
    ) b( ]; ?7 n9 |. \! u}</P>) _  I* F  n; w! n
    % `5 Q9 {$ R4 V. w
    <P>! \" T8 Z6 t  z. `3 z- Q
    //-----------------------------------------------------------------------------' N7 A+ k9 H, Y- ]
    // Name: 8 d$ m4 O; V9 q. J
    // Desc: calls DisplayConnectionInfo for each connection in a round-robin manner+ H4 C2 [0 }/ `4 I% ?
    //-----------------------------------------------------------------------------
    1 F  c, b- _6 z: lvoid CMazeServer:isplayNextConnectionInfo()( L- }+ [+ Q1 q( ~9 R, }
    {" {+ L* Y8 H# Q) r. U# e" n
        if( m_pNet )
    7 ^/ W# `  v" [    {0 }6 n/ P' M9 b
            // Find the player that was displayed the longest time ago, and display it." J+ j& N  L# B# V8 u
            FLOAT fCurTime = DXUtil_Timer( TIMER_GETAPPTIME );
    + \; _0 a/ m$ B7 [        PlayerData* pOldestPlayerData = NULL;* r/ \! n  g8 u; \
            FLOAT fOldestTime = 0.0f;</P>
    $ V' L$ o/ F- M0 h& V. z" s$ G+ K<P>        m_PlayerDataListLock.Enter();</P>% z/ U* z! m4 I* t2 t/ I! ~1 H
    <P>        PlayerData* pPlayerData = m_pFirstActivePlayerData;5 m" @0 m$ J9 @3 r
            while ( pPlayerData )
    " h+ z9 V0 K; j, _1 _: V6 G7 h0 }" P% D        {
    " W* T' I  }' P6 B6 h            if( fCurTime - pPlayerData-&gt;fLastCITime &gt; fOldestTime )8 F! n$ ^+ a) v0 v
                {& I" P: }  [$ K- _- B$ Z8 v
                    fOldestTime  = fCurTime - pPlayerData-&gt;fLastCITime;0 J+ B. E8 N$ S2 w
                    pOldestPlayerData = pPlayerData;
    6 c* c* _% @7 S- D            }</P>
    ) K) u8 l, o7 m, B<P>            pPlayerData = pPlayerData-&gt;pNext;; ?6 s4 T; a# m$ f; `
            }</P>* ^+ W0 h( e8 |0 E/ u. C9 {
    <P>        // Display the player with the oldest CI field, and update its CI field.
    2 {+ V: y9 E. q, r5 G! a- l7 C        if( pOldestPlayerData )
    ; t  L! q7 S- T+ T1 |        {- J4 W7 q/ q! {& r0 N7 S+ }6 v3 l2 j
                ConsolePrintf( SLINE_LOG, TEXT("Displaying connection info for next player") );
    " T9 |( b, v0 i8 X. ~* @            DisplayConnectionInfo( pOldestPlayerData-&gt;NetID );
    2 C) n  ~. B7 e7 i. ~+ [2 i            pOldestPlayerData-&gt;fLastCITime = fCurTime;: ?/ e0 L% z: w$ u# B1 ]# V
            }
    . S7 @1 |, R! _/ a& Q0 u        else& R$ g. i1 u) I. i/ h
            {
    . }4 w' j* c+ {6 G% t3 p            ConsolePrintf( SLINE_LOG, TEXT("No players found") );% G3 o; r- }7 ~& l
            }</P>! C. w+ c: [7 Q& A: B
    <P>        m_PlayerDataListLock.Leave();
    ; }% S8 \5 a) I! D3 b4 b    }
    ) s+ U  T9 T8 `8 ^8 h* ?0 t}</P>/ n9 C3 j( U9 O6 j

    : L. W# N: E. ?( I<P>* k8 g8 `  [5 b) @) k( E
    //-----------------------------------------------------------------------------
    # y( f; z: v9 Y2 y  s1 v/ @. p// Name:
    ( ?3 h+ U0 t8 M; g0 I. C' u/ P// Desc:
    & a% O2 @' P% z0 y) Q//-----------------------------------------------------------------------------1 {8 C7 a1 n' O! B* ~1 N
    void CMazeServer:rintStats()4 H, q/ Q9 S# V, u2 Z
    {8 j  R2 \7 A6 G' y% E
        ConsolePrintf( SLINE_LOG, TEXT("Thread count: Active=%d Avg=%.2f Max=%d"),
    ' y9 R( w. I. E  x/ p" E8 a7 W                                    m_wActiveThreadCount, m_fAvgThreadCount, m_wMaxThreadCount );
    9 Q2 W0 j1 [+ J* j) y, K8 A( N+ y    ConsolePrintf( SLINE_LOG, TEXT("Thread Time: Avg=%.4f Max=%.4f(s)"),% |3 _% o( t; A2 x' l: O/ L
                                        m_fAvgThreadTime, m_fMaxThreadTime );+ \: r) s6 G) u9 b2 ?6 o. o8 r' [7 r2 C
        ConsolePrintf( SLINE_LOG, TEXT("Players online (not including server player): %d"), m_dwPlayerCount );7 b0 b  B% `# H" R. r
        ConsolePrintf( SLINE_LOG, TEXT("Peak player count: %d"), m_dwPeakPlayerCount );. q3 Q  z5 N) h. I
    }</P>
    # P! @, q1 @2 d5 ]) x
    ; s- P4 D, ~5 n, M<P>
    . {" c- W) Q9 Y//-----------------------------------------------------------------------------2 Z- d$ n+ D. u$ h; Y+ N* i
    // Name:
    # R6 W! M' }: g4 J, W// Desc:
    : Y6 w- a( a3 j4 L5 B. ]1 T9 Z//-----------------------------------------------------------------------------
    - ~  H# f4 j6 M/ ~- d# Xvoid CMazeServer:isplayConnectionInfo( DWORD dwID )
    ) o  N) v: H5 a8 O{* y! M$ ?2 D1 F, _
        TCHAR strInfo[5000];" V7 F1 R0 h7 {
        TCHAR* strEndOfLine;6 P: h) ~: W/ D4 v: b
        TCHAR* strStartOfLine;</P>1 w9 m" Y& l2 b1 E7 C5 L* k
    <P>    // Query the IOutboudNet for info about the connection to this user- i- i0 t7 E& e  Z$ L
        m_pNet-&gt;GetConnectionInfo( dwID, strInfo );</P>; i+ [2 r9 V/ y: O1 \9 A; B* S7 M* N
    <P>    ConsolePrintf( SLINE_LOG, TEXT("Displaying connection info for %0.8x"), dwID );- ~, W. Z- q( f3 l
        ConsolePrintf( SLINE_LOG, TEXT("(Key: G=Guaranteed NG=Non-Guaranteed B=Bytes P=Packets)") );</P>
    # d* q# [' t8 k) B: Y<P>    // Display each line seperately
    : O  o2 i. n& P7 s9 d6 V    strStartOfLine = strInfo;- i1 G4 ?: }0 P( A; F
        while( TRUE )  p& v* T3 G& L) w" [4 A6 |
        {' [+ B: {, M; @" d# S
            strEndOfLine = _tcschr( strStartOfLine, '\n' );
    5 Z# d# l' n9 w  u        if( strEndOfLine == NULL )
    ) B! {5 ?* J8 J            break;</P>' L7 j8 Z. h8 n! U! U1 A
    <P>        *strEndOfLine = 0;' s$ t2 S. m0 u
            ConsolePrintf( SLINE_LOG, strStartOfLine );3 y3 K7 Q" g" |1 F9 n# s
            strStartOfLine = strEndOfLine + 1;4 a. r7 [8 \, t1 z/ p
        }
    ) X; o$ `" E4 M0 P, d}</P>
    - w* U) D2 h, r/ |7 C5 N7 x) `
    ) p& x8 W* ~2 j5 Z' z! W& ~<P>; A* ]6 o6 _. R& n6 U
    //-----------------------------------------------------------------------------
    0 C! s1 H' @1 Y1 B7 C4 O, w# o# @// Name: + q" d6 E2 ?$ L6 t/ W. o
    // Desc:
    , G9 S7 n- Z2 H9 ?  X7 c//------------------------------------------------------------------------------ s' q; C. z, P' ^
    HRESULT CMazeServer::SendPacket( DWORD to, void* pData,
    4 N" [$ P$ m# O! `. ?                                 DWORD size, BOOL reliable, DWORD dwTimeout )
    # @$ ?0 Y6 y, B, s! K6 I{, x' ~7 P. m8 F) u) `* n
        // Chance of forcing any packet to be delivered reliably( {# ~+ F, q  C! _" H
        if( m_Rand.Get( 100 ) &lt; m_dwServerReliableRate )8 M) A6 t9 g" |% X5 d5 H1 c
            reliable = TRUE;</P>/ m+ @7 M: c# h1 S- R0 Y. \
    <P>    return m_pNet-&gt;SendPacket( to, pData, size, reliable, dwTimeout );! I( T9 f+ u; z9 m! Q# s
    }</P>! A, E3 A2 \. r" n) n. p! ^

    3 L" n( t) P5 P& Z2 c1 V<P>
    ( e0 X; L; ~: z. U5 m; [! k" l3 Z//-----------------------------------------------------------------------------
    , \2 U; }+ n) s% R: o* J// Name: : t* M- Y2 t/ e6 a( B
    // Desc: % d/ ?; I) m9 L) e1 |& V: [! d
    //-----------------------------------------------------------------------------) E% h& I) S2 ?- |+ m5 c
    void CMazeServer::SendConfigPacketToAll( ServerConfigPacket* pPacket )+ @- {- r9 Z- A$ r0 {; {
    {
    7 [2 ^. w) J* f2 \- C  A1 @( J    // If we're up and running, then send this new information to all clients
    ' O9 @6 V6 u- x+ Z    if( m_pNet )
    # V; v; N/ U- U4 }    {1 ]1 m! E) ~5 Q- V/ x. X+ a6 U* f( f4 y
            //Use the AllPlayers ID
    + v2 ^# p) v' ?5 e! Q* B        SendPacket( DPNID_ALL_PLAYERS_GROUP, pPacket, sizeof(ServerConfigPacket), TRUE, 0 );
    3 x9 T- x9 q9 O) r- ]    }
    / T* ~* Z) Y. [7 y5 }}</P>
    6 k; N: N# }& R& O9 r, C* A) R+ p! y' N9 m* f9 N& Y% r- O
    <P>
    . [9 v; g0 P0 S1 B. T//-----------------------------------------------------------------------------$ e7 Q; S+ D* A" E
    // Name:
    % G- s/ F# ?1 x. v) j8 x// Desc: 7 D7 ~& u+ a7 w* }8 z
    //-----------------------------------------------------------------------------
    - P9 i6 z" r9 e& _: g  W8 pvoid CMazeServer::SetClientReliableRate( DWORD percent )- i4 ^% x9 R8 p; T
    {
    7 `( I0 m0 w$ p0 d( Q/ ?    // Update client config, and build packet containing that data+ `) G7 o8 t  E' e; L8 [* {7 E# A8 @
        m_ClientNetConfigLock.Enter();
    3 S5 L: ~$ f# c( _9 g5 H    m_ClientNetConfig.ubReliableRate = BYTE(percent);
    ) _7 P, [0 k0 E% Z" m    ServerConfigPacket packet( m_ClientNetConfig );6 @8 o& x/ w" ^3 E2 o( w
        m_ClientNetConfigLock.Leave();</P>
    ' U* \$ w7 l' x" L<P>    SendConfigPacketToAll( &amp;packet );
    ; e. D9 c) R9 z. X) @. @}</P>
    : S- w8 H/ x+ `5 i6 K1 {2 m, h( }) `
    7 ^+ m3 Z" _. V" i<P>' Z; D  b- z. [# ^: t% Y
    //-----------------------------------------------------------------------------
    ) V- ?3 f* p% A; U// Name: 0 h7 R" }! N8 o+ Y
    // Desc:
    ' s' ]  [' A4 @& o& |) V" n; s; s1 k  y//-----------------------------------------------------------------------------3 Q9 Q" j: |9 Q# }+ _7 a
    void CMazeServer::SetClientUpdateRate( DWORD rate )
    & ^; K" v0 d2 k* `* L{
      d1 {5 q' t7 Z$ Z8 d& ^2 U    // Update client config, and build packet containing that data+ Z5 f# W. q* c7 u/ i( b8 P
        m_ClientNetConfigLock.Enter();! E% _9 W; c9 @7 d" E& l
        m_ClientNetConfig.wUpdateRate = WORD(rate);8 S. L7 g/ f7 _  G, R
        ServerConfigPacket  packet( m_ClientNetConfig );
    ) k1 n/ W! I5 n6 y! i    m_ClientNetConfigLock.Leave();</P>! K+ w# W5 q/ d) Z$ P! c
    <P>    SendConfigPacketToAll( &amp;packet );
    $ J& _' R. T/ }6 V& q9 G6 c1 C}</P>
      |# {2 V/ l; u' a4 ?4 m& x4 `9 V. t. v* |  {1 s7 ?# F
    <P>5 ^, S/ g3 @. [4 H
    //-----------------------------------------------------------------------------
    # ~  m, Z! j; a* m) L// Name:
    7 e* \0 i6 k8 i+ V! s" @// Desc: 9 W% t/ ]+ J) _
    //-----------------------------------------------------------------------------0 r& K  V0 {2 D1 p9 k5 y4 D* I
    void CMazeServer::SetClientTimeout( DWORD timeout )/ c8 _" U1 D( q. D
    {& j0 t* m/ z' n% H/ h3 w. P  m
        // Update client config, and build packet containing that data" a; ?' I* g8 ]) r9 y- ^
        m_ClientNetConfigLock.Enter();
    0 g, T1 n1 N  _) L    m_ClientNetConfig.wTimeout = WORD(timeout);1 q! n3 Q' `! v) Q* k, ~% j
        ServerConfigPacket  packet( m_ClientNetConfig );1 y: y; R) U3 p- n- t( u
        m_ClientNetConfigLock.Leave();</P>
    9 Q* Z( y2 E4 f1 k5 k% B<P>    SendConfigPacketToAll( &amp;packet );: g9 A% ~# \9 [
    }</P>
    4 \9 ]! U; l; P/ H) m9 \; n/ ^; ~  @) ]5 G* ^7 j
    <P>
    3 F4 o' \1 C. o9 B# i& s//-----------------------------------------------------------------------------
    7 D: _6 P+ N8 o3 _5 [" `// Name:
    2 E# [4 N: @9 C% v& W4 x. V" {" p// Desc:
    ' }" J% L) I3 Z2 O//-----------------------------------------------------------------------------
    , r8 Y6 f" d1 R/ X- E7 r$ Ovoid CMazeServer::SetClientPackSize( DWORD size )# B2 |( w$ b( Z. X
    {! m* \- H$ ~$ w% W2 S% H
        // Update client config, and build packet containing that data
    2 D& K+ y- e! ~  g' w. C: C    m_ClientNetConfigLock.Enter();
    ' S. L, O1 a2 H" U/ A# T   
      F3 R3 E8 w* E( h1 p    m_ClientNetConfig.ubClientPackIndex++; //Increase index and verify location in array.6 a( R  [; g& g- Y
        if(m_ClientNetConfig.ubClientPackIndex &gt;= PACK_ARRAY_SIZE)   ! ~7 l8 C7 _6 J+ _
            m_ClientNetConfig.ubClientPackIndex = 0;</P>+ c6 @3 s/ G2 o$ b) h2 i
    <P>    m_ClientNetConfig.wClientPackSizeArray[m_ClientNetConfig.ubClientPackIndex] = WORD(size);
    ' [, ~0 q; Z/ L8 T3 f4 Y    ServerConfigPacket packet( m_ClientNetConfig );
    " {2 Y6 x2 [2 K. ]  p    m_ClientNetConfigLock.Leave();</P>
    - ^" \: G/ Z, M3 w. Z7 l7 T1 l<P>    SendConfigPacketToAll( &amp;packet );
    " ?4 i2 {; y, G, d' w1 C- r}</P>
    3 f& V8 I/ J- }+ x7 R' J
    ) \' V) u5 X7 [5 X' `/ W<P>8 M: {" B" A0 h; b6 ?: G2 D; }
    //-----------------------------------------------------------------------------
    " s/ i# d7 D+ N. n- c. K// Name:
    2 _" o+ J+ I# Q1 H) i& T2 a3 N  v// Desc: $ \) F+ A9 Y0 |" V& D
    //-----------------------------------------------------------------------------3 r$ {2 y5 t$ Q( K( n6 c5 U
    void CMazeServer::SetServerPackSize( DWORD size )
    4 v( ^' s8 Q# _* g3 T{) t* \4 C! s$ ]/ P, K) f
        // Update client config, and build packet containing that data7 N0 B8 [7 o% w# B0 S
        m_ClientNetConfigLock.Enter();
    + _0 ?$ W7 c/ e- T. D/ U% A   
    5 T9 Y  v8 M% u    m_ClientNetConfig.ubServerPackIndex++; //Increase index and verify location in array.
    3 h; F% A5 L% x    if(m_ClientNetConfig.ubServerPackIndex &gt;= PACK_ARRAY_SIZE)   
    ; T8 A0 I. Z3 ^6 x! d        m_ClientNetConfig.ubServerPackIndex = 0;</P>1 A1 y# M( L+ n' f% V. j% e
    <P>    m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex] = WORD(size);
    3 o+ D. t$ x; v" A! a' d    ServerConfigPacket packet( m_ClientNetConfig );4 A2 c' X0 h! a$ x) ?
        m_ClientNetConfigLock.Leave();</P>
    9 z$ p5 i! q  b& t3 g) }7 ?<P>    SendConfigPacketToAll( &amp;packet );' x2 i  _0 N6 ]' C6 R
    }</P>
    9 ?8 N1 B  {& O7 K+ l  m( _. |; L<P>  S! I* x$ \) n4 V: A. F8 K& `1 b) ?
    //-----------------------------------------------------------------------------1 N; r: Y; k/ t( n& l
    // Name:
    9 Z) V5 g' b  A: \  D/ d// Desc:
    3 U9 |( y0 G9 J//-----------------------------------------------------------------------------/ B9 w9 {+ g( _$ j1 ~. b) O
    void CMazeServer::SetClientThreadWait( DWORD dwThreadWait )7 e9 L7 e7 f, M; [3 h
    {
    + o  V: ?6 F. P5 w7 y    // Update client config, and build packet containing that data, S. m+ O; m5 o4 B' p% [3 E& s4 R
        m_ClientNetConfigLock.Enter();
    % u( Q. u# c/ L4 v/ B   
    7 _; Q3 V* k$ \: q' }& e    m_ClientNetConfig.dwThreadWait = dwThreadWait;3 ^0 z, \9 T5 e. i% `2 I  f
        ServerConfigPacket packet( m_ClientNetConfig );/ |! M) s8 Y. v$ n5 Z" x
        m_ClientNetConfigLock.Leave();</P>% v: k0 D/ M9 v: S1 S: Q
    <P>    SendConfigPacketToAll( &amp;packet );
    5 T" I- c/ Y. j0 x2 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, 2026-6-15 14:06 , Processed in 0.459079 second(s), 51 queries .

    回顶部