QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 4198|回复: 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>
    : o/ h) c8 m. o2 w; s' o<>// File: mazeserver.cpp
    & c9 G9 V9 F' ?* I# L6 ~, T$ O) b//
      \4 K2 p$ K  b. F) b$ a& H// Desc: see main.cpp
    9 c. Q& c( c+ t//: k; Y& z6 c) c& f/ O+ H2 G
    // Copyright (c) 1999-2001 Microsoft Corp. All rights reserved.
    $ t. L4 ^1 m- f( p# s//-----------------------------------------------------------------------------
    / {) [% c; n) L8 O; n#define STRICT8 K& G# ]' [; y6 h
    #define D3D_OVERLOADS
    ' o8 o2 f8 U" p( r/ i4 R#include &lt;windows.h&gt;( V- E8 }4 Z! b, K% N  P
    #include &lt;d3dx.h&gt;
    * ]0 e& ?  O5 ?. V#include &lt;stdio.h&gt;
    ) \# O* c( v% l) m% r9 h" N#include &lt;math.h&gt;9 J; O* l( x8 d, |8 s% r) U4 i1 Q+ k
    #include &lt;mmsystem.h&gt;4 D4 Z: |3 N3 c! R' B4 Z6 J
    #include &lt;dplay8.h&gt;
    ' E. [* C" A/ }$ w/ W* {#include &lt;dpaddr.h&gt;
    2 ~& c0 Y6 `9 l8 _' i! G0 s$ n#include &lt;dxerr8.h&gt;
    " X' P- d; I3 U( W3 Y. _+ S#include "DXUtil.h"
      q3 |1 V5 ^* H: |5 {+ p#include "MazeServer.h"
    . c$ U( M  R' o+ Y' q#include "ackets.h"5 ?, j% k$ R. L6 ]
    #include "Maze.h"
    % h; @  [6 W( s  |9 h#include &lt;malloc.h&gt;! X4 |, h' k6 {/ v$ j5 h
    #include &lt;tchar.h&gt;</P>
    5 K# \3 K* W' r. n, u. k3 M- T, t% M" V, l/ w; A5 N
    <>//-----------------------------------------------------------------------------
    2 ?* z( K9 B7 Q6 ]9 S8 y0 Q# E6 J// Name: . C8 t) b& Q" I& Q
    // Desc: 1 O6 G7 O; @  U% {4 l6 J
    //-----------------------------------------------------------------------------; [5 r" w9 X9 @0 o* \4 x
    CMazeServer::CMazeServer()
    . \) B' Y3 k! @7 u4 w" A& Y3 @{7 \: g0 b8 F( I% U! }1 v0 B
        m_dwPlayerCount         = 0;! m8 y/ J- u8 ~! `
        ; \$ \7 V# r6 u: d
        m_wActiveThreadCount   = 0;$ R' y; D/ I" W, n# U) q' ^! E
        m_wMaxThreadCount      = 0;- |& _2 f6 |: T# i$ ~  N. m1 M
        m_fAvgThreadCount      = 0;0 e* H0 W# s6 L( I
        m_fAvgThreadTime       = 0;
    ( [8 S* i7 D0 r- n4 c" n4 B) G) h    m_fMaxThreadTime       = 0;</P>, l4 Z8 }, {1 r/ }- }
    <>    m_dwServerReliableRate  = 15;
    ; J0 }9 g1 z, f! d    m_dwServerTimeout       = 150;( u  v% @, a) Q7 l' o' ?
        m_dwLogLevel            = 2;
    6 `" d5 E/ B7 x% d& |    m_pMaze                 = NULL;</P>
    & e. S# K, }5 D  _! t<>    m_ClientNetConfig.ubReliableRate = 15;4 Z7 N9 L8 y1 z* c
        m_ClientNetConfig.wUpdateRate    = 150;3 ]2 q% z" K& L/ v
        m_ClientNetConfig.wTimeout       = 150;</P>
    # h( x' n2 G, c& L* x9 q2 h- {% N2 m<>    m_ClientNetConfig.dwThreadWait = 0;</P>/ f9 e. P9 I3 p3 J- T
    <>    m_ClientNetConfig.ubClientPackIndex = 0;+ C1 q' c8 ?/ p% _) }
        m_ClientNetConfig.ubServerPackIndex = 0;
    # D; `9 i: L* B, a$ z% p9 P    for(WORD x = 0; x &lt; PACK_ARRAY_SIZE; x++)- }" m) W- s1 e
        {$ f: Q2 @2 n/ I3 r0 ~
            m_ClientNetConfig.wClientPackSizeArray[x] = 0;' \9 ^4 _+ M, x) B1 L
            m_ClientNetConfig.wServerPackSizeArray[x] = 0;
    0 b8 K9 W5 z$ m# Q. ]$ l    }) p3 W! y" ~; S) V
    }</P>
    3 q/ l% X0 E$ O8 J0 l  }3 S
    % d, f- n4 v4 `; \+ B  |; Z5 f<>9 m7 ?0 f. I5 o, V% b/ C
    //-----------------------------------------------------------------------------
    + c- N, M( s6 s  M. J# e// Name: & G* l1 [; s2 j8 M
    // Desc: : M+ \; K2 t8 J
    //-----------------------------------------------------------------------------9 @; J. O# r  u
    HRESULT CMazeServer::Init( BOOL bLocalLoopback, const CMaze* pMaze )) u* a0 A( C! E5 W( r- L! y3 _% p
    {5 ^/ B7 a2 F! A, Z! k
        m_bLocalLoopback = bLocalLoopback;7 z+ p1 V. P/ k6 ^$ c( M
        m_pMaze = pMaze;
    ! r  ?& @8 @  w9 I7 |) X0 `    if( m_pMaze == NULL )
    ) W4 F. G& F: O        return DXTRACE_ERR( TEXT("aram"), E_FAIL );</P>* Q) l3 _  {8 R4 H. m% K" f
    <>    // Grab height and width of maze. O( [3 {+ N& D- f! H, p6 A- o/ o5 e
        m_dwWidth = m_pMaze-&gt;GetWidth();" Z; n! M+ k* Y' h; X
        m_dwHeight = m_pMaze-&gt;GetHeight();</P>
    8 Z' N4 F$ }* Q4 P0 V  z<>    m_ClientNetConfig.dwMazeWidth  = m_dwWidth;
    8 C# z8 b! N5 G/ k# _6 U    m_ClientNetConfig.dwMazeHeight = m_dwHeight;</P>0 \) [2 ]/ T, J+ s6 b
    <>    // Validate size. Must be a power-of-2 times LOCK_GRID_SIZE. Compute the shifts.* d* a8 [1 p2 C( y4 p& m+ m% S: \
        if( m_dwWidth &gt; SERVER_MAX_WIDTH || m_dwHeight &gt; SERVER_MAX_HEIGHT )
    6 a9 u6 R" q* s) p2 b        return DXTRACE_ERR( TEXT("Maze height and width need to be less than 128"), E_INVALIDARG );
    # {9 _' r9 c' n6 u    if( (m_dwWidth % LOCK_GRID_SIZE) != 0 || (m_dwHeight % LOCK_GRID_SIZE) != 0 )' Y8 t, x' \( S- t" d" \8 T. l
            return DXTRACE_ERR( TEXT("Maze height and width need to be divisable by 16"), E_INVALIDARG );</P>
    # h# o3 R4 B. ^( F<>    DWORD scale = m_dwWidth / LOCK_GRID_SIZE;
    2 ?. B7 G. b3 M5 x8 c    m_dwMazeXShift = 0;
    1 U* z! o/ L5 K    while ( (scale &gt;&gt;= 1) )
    / c5 p" n6 {, w  r, ]        m_dwMazeXShift++;</P>- p5 U) R: o9 @) {. a0 H
    <>    scale = m_dwHeight / LOCK_GRID_SIZE;# |" f" e5 U% L3 C6 _$ G3 j$ j
        m_dwMazeYShift = 0;. a6 C4 u0 T! c0 t; i! S
        while ( (scale &gt;&gt;= 1) )8 d5 C3 {9 B" l6 d+ O1 u
            m_dwMazeYShift++;</P>+ G8 H7 y" q# E$ W+ _/ X
    <>    if( ((DWORD(LOCK_GRID_SIZE) &lt;&lt; m_dwMazeXShift) != m_dwWidth) ||* I# Y/ l3 y! m2 _2 l: V: R( m
            ((DWORD(LOCK_GRID_SIZE) &lt;&lt; m_dwMazeYShift) != m_dwHeight) )
    , b! q8 Z% e1 C: L/ t! o4 {; L5 y        return DXTRACE_ERR( TEXT("Maze height and width need to be power of 2"), E_INVALIDARG );</P>! ~6 \* g/ T+ J" i- k5 z
    <>    // Initialise the player list/ I0 u, r5 J$ X9 J1 k
        ZeroMemory( m_PlayerDatas, sizeof(m_PlayerDatas) );
    $ n8 a, s5 C# |0 D    m_pFirstActivePlayerData = NULL;" i5 W3 r, k& }8 Y) i9 w
        m_pFirstFreePlayerData = m_PlayerDatas;
    5 u& G$ ~1 v8 W. |    for( DWORD i = 1; i &lt; MAX_PLAYER_OBJECTS-1; i++ ): U5 c: u& s  @! s4 Y  I
        {
    / G, |3 `6 t: O- V! ?8 u        m_PlayerDatas.pNext = &amp;m_PlayerDatas[i+1];$ l1 J) u% j1 w
            m_PlayerDatas.pPrevious = &amp;m_PlayerDatas[i-1];
    ; \; }3 }! p0 m+ S. q. c! `    }</P>
    7 |6 [3 U: S. F<>    m_PlayerDatas[0].pNext = &amp;m_PlayerDatas[1];. r+ ]* T% p! E6 d$ g" e) X1 B
        m_PlayerDatas[MAX_PLAYER_OBJECTS-1].pPrevious = &amp;m_PlayerDatas[MAX_PLAYER_OBJECTS-2];6 X" I, ^9 R/ X- Z6 X
        m_dwActivePlayerDataCount = 0;- I+ Z# ~6 n: ~& ]
        m_dwPlayerDataUniqueValue = 0;</P>
    / B( w5 G0 P! b: d<>    // Initialise the cells% S; r9 @3 ^7 G; Z* p9 S; D
        ZeroMemory( m_Cells, sizeof(m_Cells) );# a" g2 Q! U4 k+ s) }) V
        ZeroMemory( &amp;m_OffMapCell, sizeof(m_OffMapCell) );</P>
    ) t8 W0 J. O3 p* o: z5 f<>    return S_OK;
    4 P' c0 O% W1 I1 }% t  j}</P>
    3 C# b( ^9 L0 c' Y5 a+ F, \/ g; H2 _& }$ K
    <>
    $ b; o2 t1 [6 l; Q: x+ h//-----------------------------------------------------------------------------0 Z& B% S% ?4 x: a
    // Name: 2 Q5 t& Q" d$ K0 j& {& w& L
    // Desc:
    : @) l0 x4 D* w% N  T//-----------------------------------------------------------------------------5 ]. p, M1 |+ f0 a7 V7 [  O! ?
    void CMazeServer::Shutdown()
    5 k! B* k  e5 S" c& {/ N{% U/ K) ]5 y0 X$ a3 W' |( y
    }</P>
    2 Q! O) l4 A$ X/ M& n, n
    ; b6 K) r; i9 Q# }<>
    " h( c2 I0 h7 }' w: b. [; U//-----------------------------------------------------------------------------
    * T2 s/ Y' y  w/ j  C% j// Name:
    % A: N- v" t4 }5 d- J' |// Desc:
    7 b/ E6 _9 K- h) v//-----------------------------------------------------------------------------" P0 }3 M1 ?; V
    void CMazeServer:ockRange( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )
      b: s; |! g4 N& h* q: s& [- u6 U{
    8 |6 I3 Z/ \2 J  k; |    m_LockGrid.LockRange( x1&gt;&gt;m_dwMazeXShift, y1&gt;&gt;m_dwMazeYShift ,
    6 S( S3 i& a% l" w5 K* \( F                          x2&gt;&gt;m_dwMazeXShift, y2&gt;&gt;m_dwMazeYShift );
    ; B0 u7 [$ i! d2 p/ }# H}</P>: e) t* P: V2 }7 c7 H9 C2 K# G
    1 D7 V7 ^- u- \
    <>5 x, V( k* P0 A! P5 V) E9 y
    //-----------------------------------------------------------------------------
    ; h  [$ v! Z1 o// Name: ; v! Q( f$ V" Z$ l; t
    // Desc:
    , u% j- U1 O7 p: Y- ]//-----------------------------------------------------------------------------
    ; U/ p2 W6 p( Q# L* M( Q# }! Jvoid CMazeServer::UnlockRange( DWORD x1, DWORD y1, DWORD x2, DWORD y2 ); V" J) K2 r6 d' X
    {
      T  p3 B) G1 H9 F3 o" y1 I    m_LockGrid.UnlockRange( x1&gt;&gt;m_dwMazeXShift, y1&gt;&gt;m_dwMazeYShift ,  F5 f1 {+ R* x$ J1 l$ ~! \# d) q1 I0 p
                                x2&gt;&gt;m_dwMazeXShift, y2&gt;&gt;m_dwMazeYShift );0 p4 _! f3 v# M" _) Y( l
    }</P>9 |3 u" ]' k0 C% h6 o
    * {; K( s( v/ e" R$ ^: h
    <>
    / W# v, P) k" F; N- I) N! ~- d//-----------------------------------------------------------------------------
    # t3 I4 l; ^, N( l( M- R+ ]! f// Name:
    + E$ ~* ]- g% v* o+ d: i7 m. i  H// Desc: 3 F2 L8 p0 c4 d0 J
    //-----------------------------------------------------------------------------
    ; ~3 [  M4 R: |& T$ z6 u0 f% Fvoid CMazeServer:ockCell( DWORD x, DWORD y )
    0 K% |& R2 Q& U, S6 y{. D/ F5 r! G% [4 i
        if( x == 0xffff )) E: b8 O- i6 A  ^
            m_OffMapLock.Enter();) U! n9 G4 O1 R' C* [1 _
        else6 p4 P0 T6 `' \* }
            m_LockGrid.LockCell(x&gt;&gt;m_dwMazeXShift,y&gt;&gt;m_dwMazeYShift);
    2 \( h0 O! k# N  J" {0 `0 ?}</P>
    6 u, w- L2 o$ U3 B7 ~( P5 W' {' w. H9 s; w* W9 I2 f
    <>9 a+ n7 k$ }5 ]
    //-----------------------------------------------------------------------------
    # j8 ]' ~/ H* ]( I! i1 d0 a8 b7 ~// Name: 3 {) t3 q" N5 j7 v
    // Desc: 1 c" B  c) w" P2 I- q
    //-----------------------------------------------------------------------------
    & }4 L, j' k& D3 J( C/ Bvoid CMazeServer::UnlockCell( DWORD x, DWORD y )8 A9 k( w( H. \0 G
    {! s* Y8 D1 ]4 T' l, p# }$ c
        if( x == 0xffff )! x, W% t. ?; r9 g0 `
            m_OffMapLock.Leave();' U: W1 b$ v8 S; q. w
        else- y5 O# ]  e. I* ~
            m_LockGrid.UnlockCell(x&gt;&gt;m_dwMazeXShift,y&gt;&gt;m_dwMazeYShift);
    " O" T8 O. p. n0 I9 S2 t* d8 U}</P>( `0 n' o3 z: B$ T0 U" h5 Z

    / e; ]& x& l4 Y7 p: `<>
    : q. z  e# o& ?8 i//-----------------------------------------------------------------------------
    / b( D5 `: i2 ?// Name:
    5 f; T/ K# }& l3 `// Desc: 9 o) L2 R8 j8 R$ T
    //-----------------------------------------------------------------------------$ T2 d, _& C2 U$ Z4 R) D
    void CMazeServer:ockCellPair( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )) _; J: w. ?+ i( i1 D/ k
    {
    ( \/ [% i7 R: ~. F; j, F    if( x1 == x2 &amp;&amp; y1 == y2 )
    ' S' ^( N6 n+ a# g# Y    {# T9 x2 T0 v3 ]  b" i% K
            if( x1 != 0xffff &amp;&amp; y2 != 0xffff )) p9 P7 v5 ]0 R
                LockCell( x1, y1 );5 h4 Z% v4 J4 X' p& _0 H" `. _6 k
            else9 z, ^: H7 J( p( k0 x. x1 d' K
                m_OffMapLock.Enter();</P>
    7 ?. [( o) E# C4 B# r<>        return;
    , G5 N) X5 m+ B* Q5 E! x! d    }</P>* C! r0 ^7 v+ t9 O7 G) o4 O
    <>    DWORD x1shift = x1&gt;&gt;m_dwMazeXShift;* @" g3 Q% B% r# A
        DWORD x2shift = x2&gt;&gt;m_dwMazeXShift;9 C# s6 s+ [/ q* Y  f
        DWORD y1shift = y1&gt;&gt;m_dwMazeYShift;# l  E! W% @0 V
        DWORD y2shift = y2&gt;&gt;m_dwMazeYShift;</P>
    1 I  [( q7 d& b+ H<>    if( x1 == 0xffff )7 E7 |) t% r) {8 G/ l0 Z2 P
        {% k) o/ |) F) p/ G
            m_OffMapLock.Enter();. U! Z# t# U2 c1 F6 Y
            m_LockGrid.LockCell(x2shift,y2shift);
    2 q2 T" {2 a" l# b0 W+ s    }& G9 W- F) O1 a7 s: M
        else if( x2 == 0xffff )0 e/ y( H* P' h% d$ F
        {
    2 C9 A8 q( e' t. |* [/ q        m_OffMapLock.Enter();
    ( l1 w; T: h3 p8 V8 {        m_LockGrid.LockCell(x1shift,y1shift);
    * m4 w5 }4 ~; ?    }
    # A$ O% a; s8 X4 I$ Y- Q    else $ ?4 |5 q2 E7 g% j& ]
        {% G, {5 k4 U, B* r' O
            m_LockGrid.LockCellPair(x1shift,y1shift,x2shift,y2shift);
    3 o& w3 c' G. g/ f    }4 [8 z' F3 C6 a9 L
    }</P>
    ' @6 ~& }! ~0 f: S: e9 F+ o; G. B) q& P9 M7 q
    <>$ z% e  t# f; l* [, _
    //-----------------------------------------------------------------------------
    1 E' V! @' n  H( @// Name:
    7 \* o7 ^0 y: W$ M8 j% b// Desc: 2 o# h5 y$ X1 y9 w
    //-----------------------------------------------------------------------------  Y+ A5 A2 B3 _) F4 U
    void CMazeServer::UnlockCellPair( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )
    ' B/ O5 a- {; C9 {8 j! v{
    ( z5 u5 Y( m+ M    if( x1 == x2 &amp;&amp; y1 == y2 )
    $ G; i7 G7 e. p! ]0 h$ P    {7 Q2 _# F) @; [( V* R
            if( x1 != 0xffff &amp;&amp; y2 != 0xffff )
    3 h5 I1 p4 K% C4 j* X2 K# J3 R            UnlockCell( x1, y1 );
    2 s( _1 Z+ ?5 n) i: X! l        else5 D9 c: O: T0 R; Q
                m_OffMapLock.Leave();</P>
    9 O/ N0 b6 P0 J, {6 P5 ?+ ~<>        return;
    * J3 b; ^8 m# V- W& `    }</P>
    4 N: m: ?. v/ O, W<P>    DWORD x1shift = x1&gt;&gt;m_dwMazeXShift;
    4 \$ O, g# `7 c- a: g    DWORD x2shift = x2&gt;&gt;m_dwMazeXShift;
    , _, v) e7 F' j" n5 H( E8 Q; p    DWORD y1shift = y1&gt;&gt;m_dwMazeYShift;9 ?6 Q3 r) b7 H$ [9 Y3 Q" _! A
        DWORD y2shift = y2&gt;&gt;m_dwMazeYShift;</P>
    ( F/ I  x! C; Z% H: z<P>    if( x1 == 0xffff )/ P( \0 Z& d4 X' e6 b/ ^  l) ~
        {
    ) s. x, r0 M: i/ Z7 Y* x        m_LockGrid.UnlockCell(x2shift,y2shift);
    * O% R8 L# {. n5 @+ T2 @, H. j# j        m_OffMapLock.Leave();& V' B5 {% }$ W3 Z0 ^( T
        }: l4 @! L2 Q* S! T8 J6 ?# t( f# Q$ r
        else if( x2 == 0xffff )' ~% H' I: Z9 ?1 e( n* z! X/ M
        {
    ; i0 q3 O6 Q3 a9 H$ R0 J        m_LockGrid.UnlockCell(x1shift,y1shift);
    ; s, a$ ?" ~. R1 p0 h+ ?2 z* v        m_OffMapLock.Leave();
    0 y9 ]8 a2 _4 ?' b- D3 n    }" N: F% P0 r0 N3 D. w: M
        else
    / F3 K% r+ k1 I- a, g# V- x% f    {
    % E  m7 G9 [* l  |0 K3 o        m_LockGrid.UnlockCellPair(x1shift,y1shift,x2shift,y2shift);
    ' K* U5 g' l0 Q2 G$ |    }
    . R' H4 {# o6 t# L}</P>
    ) x6 X: h) K9 q& _
    ( J4 ^( i$ p4 K2 S2 d6 o  n<P>
    4 c3 H9 S7 @$ y//-----------------------------------------------------------------------------
    : L0 f+ ]/ _% M( D0 ~// Name:
    ( v) r: k9 u3 w  g- h& N- |# v// Desc: ; s, p! R' j& ?9 N8 I
    //-----------------------------------------------------------------------------
    3 g  l. N7 D, X# A2 m/ Uvoid CMazeServer::OnAddConnection( DWORD id )% k$ G5 O" m% D8 s$ `3 K: y
    {
    8 ]. G& j% |$ k  d    m_AddRemoveLock.Enter();</P>
    ! y$ C5 \7 Y0 _$ B1 }0 G<P>    // Increment our count of players3 J' i" T4 i) B5 b+ a$ m; p
        m_dwPlayerCount++;7 f5 ~. v/ H7 S* W5 ]7 L
        if( m_dwLogLevel &gt; 0 )  }7 @7 k0 e9 Q& z# n
        {
    3 f5 U- m5 e- o( \; M        ConsolePrintf( SLINE_LOG, TEXT("Adding player DPNID %0.8x"), id );
    , T3 `. Y" p7 D1 c  n        ConsolePrintf( SLINE_LOG, TEXT("Players connected = %d"), m_dwPlayerCount );
    1 r0 d4 k; H: F& _) Q5 a    }</P>
    . p6 g/ k3 q7 F9 M7 }' B) w# H<P>    if( m_dwPlayerCount &gt; m_dwPeakPlayerCount )! F8 _8 N2 n1 x5 s2 h* y: M& x
            m_dwPeakPlayerCount = m_dwPlayerCount;</P>
    ! v; E) l+ {( \  f5 [<P>    // Create a player for this client: v2 u; A# U# X+ L$ m' y6 Q
        PlayerData* pPlayerData = CreatePlayerData();# A9 @# m7 S& V/ ^2 p! E
        if( pPlayerData == NULL ). {9 X1 N  b) ~  }( q6 V
        {' T- ^. Q4 r. G! Y& L
            ConsolePrintf( SLINE_LOG, TEXT("ERROR! Unable to create new PlayerData for client!") );
    ' L. W% S1 `, J1 b        DXTRACE_ERR( TEXT("CreatePlayerData"), E_FAIL );9 P7 w0 o+ t7 a" I
            m_AddRemoveLock.Leave();
    + }* S# `( E" o8 N' j+ r        return;% j  ?- h; b; S. U6 O3 ^4 M
        }</P>. y; X- Z6 ?5 B5 K
    <P>    // Store that pointer as local player data
    0 M- y* C3 L; [  B; q% l    SetPlayerDataForID( id, pPlayerData );</P>
    " u  j+ I' ~5 q' R! N" G; k  U<P>    // Grab net config into to send to client3 \/ m1 [$ q1 ]
        m_ClientNetConfigLock.Enter();0 D: L6 O3 b6 i' {! h$ D1 o7 p6 C
        ServerConfigPacket packet( m_ClientNetConfig );
    ' W( A- `: m6 F! a    m_ClientNetConfigLock.Leave();</P>
    5 \/ x8 G! M* j0 G% ]5 X: b) w% y<P>    // Send it
    5 Q* _$ t! \  k7 g* I+ I( ]    SendPacket( id, &amp;packet, sizeof(packet), TRUE, 0 );</P>
    1 d# v. o& r1 d; a# ]5 _<P>    m_AddRemoveLock.Leave();
    ( L$ q# F* }7 a- P}</P>
    + h2 a4 k; t: f# _$ f& Z% ]* U" H* b- z3 i/ {4 f9 l' [4 I
    <P>, x& b" k0 h  P
    //-----------------------------------------------------------------------------: V; M  A+ d9 t8 F9 J4 U: e
    // Name:
    2 Q8 ~9 K; I0 L4 E// Desc:
    " `6 |1 @6 m* M7 o7 s//-----------------------------------------------------------------------------% \- I+ F- g( z, {0 p% P5 V7 h2 l
    void CMazeServer::OnRemoveConnection( DWORD id )
    $ D- a6 U% x! S' {; i7 r{. C; [$ n' j1 O$ S
        m_AddRemoveLock.Enter();</P>: p7 M% W- ]+ @5 V* Y5 A1 N
    <P>    // Decrement count of players
    4 |& W7 _% k/ a/ \6 r' ^    m_dwPlayerCount--;</P>
    $ T8 A) w1 @) i! }<P>    if( m_dwLogLevel &gt; 0 )
    ( |% T3 O- q$ f2 t( T# H    {
    8 c/ o( c2 v; M5 u& ?9 o5 ]' ^        ConsolePrintf( SLINE_LOG, TEXT("Removing player DPNID %0.8x"), id );( K5 u/ V& O; S4 u6 {( U4 i, J* a0 `& Q
            ConsolePrintf( SLINE_LOG, TEXT("Players connected = %d"), m_dwPlayerCount );
    1 c5 o" n& g# ~& U    }</P>
    - [- {0 E# G/ C8 A% i& O3 f$ d<P>    // Find playerdata for this client2 A  ^0 S1 S* k2 m, E: t
        PlayerData* pPlayerData = GetPlayerDataForID( id );
    ; A( A' ]3 _0 p) X+ u    if( pPlayerData != NULL ), x( ~# g9 t; L5 G/ v0 O
        {( a+ o+ o/ d1 V! L) w! B8 s: S
            // Destroy it
    , h  Z6 Y4 c/ _) q        RemovePlayerDataID( pPlayerData );( k& t) v+ G+ u5 }& T+ k% g
            DestroyPlayerData( pPlayerData );
    8 M3 V+ J' `8 F' z# M' ^. U% o    }</P>/ ]# e3 k& I, H9 E( M7 `
    <P>    m_AddRemoveLock.Leave();
    ) T* u7 A4 d, V% {' k}</P>
    - }9 `. H  n$ z; p& ~4 M7 a5 h5 p/ U+ W& w  T
    <P>. x4 x2 r* p0 @# x# a/ _; ]
    //-----------------------------------------------------------------------------
    $ o- f# s( y: U! x9 L! E) u// Name: ! Z9 h  E8 D# E, S  G# J0 j: U
    // Desc: ( `- O$ z& y+ N9 ?8 @, v
    //-----------------------------------------------------------------------------
    1 C; G0 U7 \. j( g8 K6 K# GHRESULT CMazeServer::OnPacket( DWORD dwFrom, void* pData, DWORD size )
    5 G; ]/ A; _: D, v. P% v{
    . U& v7 [, D! ?! ~# e    BOOL fFoundSize = FALSE;</P>
    . P" H) L  U1 v, S9 l, y<P>    // Increment the number of thread we have in this process.) e' p2 O' U/ h7 p! q! v
        m_csThreadCountLock.Enter();</P>* Z3 h" n$ |- a- M! i
    <P>    //Get the start time of when we entered the message handler.
    : c- p, `& E( B0 {  T    FLOAT   fStartTime = DXUtil_Timer( TIMER_GETAPPTIME );</P>  W& y' O+ t! e' U
    <P>    m_wActiveThreadCount++;
    7 Y! C0 q  n; g- Q- O( E# Z1 K    if(m_wActiveThreadCount &gt; m_wMaxThreadCount)$ c& C' F# `1 ]2 n/ u1 u
            m_wMaxThreadCount = m_wActiveThreadCount;7 y( I* @0 F/ f2 [; _
       
    : U7 j0 w3 K4 r+ B2 |# ^$ W    // Calculate and average.
    5 A; ^' g8 W$ K5 d/ C8 W; S& {6 ~; \& q    FLOAT fdiff = m_wActiveThreadCount - m_fAvgThreadCount;# ^8 H, T9 `  P, H& b5 p
        m_fAvgThreadCount += fdiff/32;
    % x) }; S( r. a' A    3 O2 u7 k7 x- n8 l& T2 J
        m_csThreadCountLock.Leave();</P>
    3 h% K: h/ z% l  _5 u- N3 F  |8 D<P>( ^' H! s, U* I2 D2 s4 F: j$ B. ^
        ClientPacket* pClientPack = (ClientPacket*)pData;
    ' f+ D$ [% h+ B' C8 H5 c    switch( pClientPack-&gt;wType )
    ( r, N5 W% l. v( W    {
    " A- d) o! V: e4 b; [3 ~        case PACKETTYPE_CLIENT_POS:" ~3 {9 n  s9 _" u2 r0 _
                ( z6 ?2 c4 o, M, M# F
                // Check to see if the packet has a valid size. Including % t7 n( N; a# U5 V, _
                // the custom pack size.
    # T0 r# o: X8 h  n1 E            if( size &lt; sizeof(ClientPosPacket))' s6 Z* I4 j3 ^- S( |0 {
                    fFoundSize = FALSE;
    * [9 W0 x, b. S' c            else if( ! IsValidPackSize(size - sizeof(ClientPosPacket)))
    * X+ y2 i8 q, z; r2 J                fFoundSize = FALSE;
    1 s9 z2 A. Z+ O; d1 `- O# P            else
    2 X; f; X1 L0 P" H! S) e                fFoundSize = TRUE;</P>
    % S$ q) i, G& |' a- s5 c0 c<P>            // If valid sized packet, handle the position.9 L  B5 ?. ~* s- m# D$ ]- G% S
                if(fFoundSize)
    % z' G9 x& V$ b9 w% ^  Q, I                HandleClientPosPacket( dwFrom, (ClientPosPacket*)pClientPack );
    ) A) k: C; y7 M# e# R7 x            else
    + N1 T/ u4 e1 g8 X+ N8 x/ W; s                m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );</P>
    9 `4 X& R/ m! K( |# R<P>            break;</P>+ H9 N7 e- G6 c& G6 l+ _3 I
    <P>        case PACKETTYPE_CLIENT_VERSION:
    / n8 ]2 W' h# S            if( size == sizeof(ClientVersionPacket) )
    4 [3 v* L7 f6 y% q1 Z2 p, J                HandleClientVersionPacket( dwFrom, (ClientVersionPacket*)pClientPack );& i+ T6 g% y& K2 h( S( ~4 U
                else
    , H9 _, P, H  |" [                m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );0 @0 B- I8 P% x  `0 }% K
                break;</P>) n6 C- z" G, a3 y' s  m/ e. `6 I
    <P>        case PACKETTYPE_SERVER_CONFIG:</P>$ P$ m- y/ w/ j( W- {/ S4 C
    <P>            // Server config packet sent to all users (including server). Just ignore and continue.</P>. y4 b# L% G, m& `
    <P>            break;7 O- U  r4 F/ ]
            default:6 x2 J; v4 {- Q4 O& @( x' J" o
                HandleUnknownPacket( dwFrom, pClientPack, size );. B/ v4 d3 Y/ ~5 S% r3 q
                break;
    # a+ }" V4 A) K    }</P>8 R7 G# E7 {- D
    <P>    //If the user wants to hold the thread, Sleep for given amount of time.. G4 h' x9 w. ]" z" @
        if ( m_dwServerThreadWait &gt; 0 )7 j+ u* L4 P4 B2 R
        {. q8 a' `8 h! t' [9 ]
            Sleep( m_dwServerThreadWait );2 f7 X& R% p7 }& F
        }# S( _. N, }4 @& M. g0 @
       
    + g$ ]5 L  E; W. z    // Retrieve thread data for this process.
    5 m2 o" b% j5 L: f8 i4 e    m_csThreadCountLock.Enter();</P>
    # w1 k% H- M7 Q0 N) @. q<P>    m_wActiveThreadCount--;</P>8 E) N; y3 U3 ^
    <P>    FLOAT fDiffTime = (DXUtil_Timer( TIMER_GETAPPTIME ) - fStartTime) - m_fAvgThreadTime;
    ( s3 H4 F1 z* P" I    m_fAvgThreadTime += fDiffTime/32;</P>' I, ~8 X' Y% M+ I8 N
    <P>    //Get the Max time in the thread.
    3 a, C  ^# q7 b5 u( Z+ ^6 ?& l    if ( fDiffTime &gt; m_fMaxThreadTime )3 W5 r! [1 Y0 q3 u5 x% \( K& C
        {
    8 H6 C2 d8 u) y9 C& b* U5 E        m_fMaxThreadTime = fDiffTime;" h8 U4 {3 X$ [3 I/ e7 m
        }</P>
    * F: G" k3 U( ^8 X! o) }+ K, @<P>    m_csThreadCountLock.Leave();</P>
    * j) q0 S) x7 M0 Q/ m* O, Q% {' F<P>    return S_OK;
    " ]- @9 Q: Q( ?# N  u}</P>! Y# i; f% ^2 Y+ i3 `# p
    " p$ g; n$ ?' M
    <P>//-----------------------------------------------------------------------------/ X( a; j5 k7 b
    // Name:
    $ h( |' L) G/ g' Q1 `: z. Y// Desc: % U4 e# W5 K$ z+ x% w
    //-----------------------------------------------------------------------------/ S. R! _! ^# y9 z% O. ^* A
    BOOL CMazeServer::IsValidPackSize( DWORD dwSize )
    " l8 t( j; c9 f, G5 M" l{
    8 B0 f5 e' g* _; q8 T3 r) R    BOOL fFoundSize = FALSE;
    ! ~" f# ~6 g- g    BYTE ubPackLocation = m_ClientNetConfig.ubClientPackIndex;* K/ l6 ~" C7 d3 f8 y8 t
        5 x$ e3 j5 \: Y3 l: L, x1 G
        // Check through the array of valid pack sizes.+ A8 }* Y) u: M% b5 D) \
        if(dwSize != m_ClientNetConfig.wClientPackSizeArray[ubPackLocation])# H3 d" {" i2 G" W9 W
        {
      C) h1 Z  p' C' [4 Q        for( --ubPackLocation; ubPackLocation != m_ClientNetConfig.ubClientPackIndex; ubPackLocation--)0 V2 A' O' _" H' [
            {
    " \+ }. U& r) U4 @7 H6 ]            if(dwSize == m_ClientNetConfig.wClientPackSizeArray[ubPackLocation])! ]2 h8 T! O, y. e
                {4 I6 U) M) g; U9 X, r( X) H
                    // Found valid size in the array.
    2 x% F. G( D& I' z9 c                fFoundSize = TRUE;; B8 ]* X4 F8 h
                    break;# r3 R, O, E! L5 @5 q
                }  B7 Y9 _2 n9 k1 K  e  ?$ ~
                if(ubPackLocation &gt;= PACK_ARRAY_SIZE)  ubPackLocation = PACK_ARRAY_SIZE;  //Wrap the array.
    . Y3 L6 `% P  `( b2 ?1 b7 ~        }
    ( P6 p# ^: g- V" T( w    }
    ; [/ |; j  U5 t: j- Z    else
    7 O1 F  s1 Q4 H3 y6 v, b    {
    * P: i# R1 {' T2 Z' H( q        fFoundSize = TRUE;
    + s2 e1 \5 L  ]2 N    }</P>1 s- f0 B( K/ Q
    <P>    return fFoundSize;9 `6 m( K, M2 ~1 ]) y1 [. [
    }</P>) _% b* @. z: U( V) ~. U8 h. c
    <P>
    9 D" L5 G& ?2 S7 G//-----------------------------------------------------------------------------
      ^. r8 k- u! B3 Y- W( _6 g: W// Name:
    8 g8 I, o8 D6 j6 }6 Z// Desc: / X5 q  a' n- \! |( @6 m
    //-----------------------------------------------------------------------------/ X1 {; |. q( {, z2 `! `
    void CMazeServer::OnSessionLost( DWORD dwReason )
    7 d! J1 M+ s  {' _: C# ^& P# {{
      p/ ?: V) V5 M& t    ConsolePrintf( SLINE_LOG, TEXT("ERROR! Session was lost") );
    & S* L- v' Y8 s& G1 K}</P>4 [- p9 _* q$ U# \: U

    - E$ g; |  X) M1 p# V0 d3 q<P>. H, {% D- m2 D
    //-----------------------------------------------------------------------------
    5 j/ w* [; s/ ^2 {/ |% i6 Z, L3 O// Name:
    * t( V/ f1 ^7 {9 O; i! V# s" V- `// Desc: 4 |5 y0 B1 x1 l, u% u
    //-----------------------------------------------------------------------------2 u( v* @* [2 F' S
    PlayerData* CMazeServer::CreatePlayerData()
    3 w( y1 B  R% @4 y9 y" v{
    - @6 l4 Z5 L) ?: [2 Z8 o    m_PlayerDataListLock.Enter();</P>  `! r5 o) Q3 u6 F' [0 F- \. w
    <P>    // Grab first free player in the list
    8 f" R) n- l; p6 I' K5 d3 p    PlayerData* pPlayerData = m_pFirstFreePlayerData;</P>, C$ M; ?. }# y4 {0 Y& ]
    <P>    if( pPlayerData )7 {) i1 A+ U8 ~% F1 C6 n
        {( T1 ?) V3 B: q" V4 g
            LockPlayerData( pPlayerData );</P>
    ( ]8 H) ]1 r7 \0 M2 }<P>        // Got one, so remove it from the free list& @7 P/ _8 V' I6 {2 ]
            if( pPlayerData-&gt;pPrevious )" F. g0 W8 o/ U6 Z4 E3 z: @
                pPlayerData-&gt;pPrevious-&gt;pNext = pPlayerData-&gt;pNext;3 E3 i6 v( u9 o* J& t
            if( pPlayerData-&gt;pNext )
    + h2 F/ V6 _6 i' E5 w            pPlayerData-&gt;pNext-&gt;pPrevious = pPlayerData-&gt;pPrevious;
    ' c: Y/ R: L" I! y( u7 |. Y& ^" B        m_pFirstFreePlayerData = pPlayerData-&gt;pNext;</P>* R' n2 Q7 R& {% P4 i" K
    <P>        // Add it to the active list
    # v2 T5 ]: b, Z8 X        if( m_pFirstActivePlayerData )0 a8 d; C# F& v8 C6 {$ G) \
                m_pFirstActivePlayerData-&gt;pPrevious = pPlayerData;# \% c, h6 l! I' @& u
            pPlayerData-&gt;pNext = m_pFirstActivePlayerData;
    ! M* y2 v( ~  j  h6 @+ d        pPlayerData-&gt;pPrevious = NULL;8 v$ x' z" G% Y7 y1 `0 Y1 I) c1 P, ^- \9 Z
            m_pFirstActivePlayerData = pPlayerData;</P>
    & p5 }3 @( d' q/ y<P>        // Update count of players) k" d/ @/ F% ^$ }3 B3 C4 t; D# g
            m_dwActivePlayerDataCount++;</P>
    ' ~) a# z2 T8 o2 F1 P* T<P>        // Generate the ID for this player
    : _* A1 |$ s$ r& s: N        m_dwPlayerDataUniqueValue++;
    / V  ?4 L% }, k1 Y        pPlayerData-&gt;dwID = (DWORD) ((pPlayerData-m_PlayerDatas)|(m_dwPlayerDataUniqueValue&lt;&lt;PLAYER_OBJECT_SLOT_BITS));</P>
    % }8 @& G# f& g) A7 i+ d<P>        pPlayerData-&gt;pNextInIDHashBucket = NULL;8 o. Y% W; l* n2 H4 M
            pPlayerData-&gt;NetID = 0;* p# n* N4 s/ c* N! c5 B  @& I
            pPlayerData-&gt;dwNumNearbyPlayers = 0;</P>
    % A" Y' H: `# I0 H<P>        // Insert into the "off-map" cell" g1 f  j: F! M0 x2 I" x5 P
            pPlayerData-&gt;fPosX = pPlayerData-&gt;fPosY = -1;. Q( G& D( ~8 X: U
            pPlayerData-&gt;wCellX = pPlayerData-&gt;wCellY = 0xffff;. x- h* Z. T: r5 v# ?2 U1 W
            m_OffMapLock.Enter();2 n, O2 f9 J" e8 t
            pPlayerData-&gt;pNextInCell = m_OffMapCell.pFirstPlayerData;+ ~3 B! i- Z; d5 V+ i; V
            m_OffMapCell.pFirstPlayerData = pPlayerData;8 f$ P& M  n+ V$ U- [5 T( W
            m_OffMapLock.Leave();</P>
    : B  ^  V& E( ]8 k! c<P>        // Mark as active, E1 T. i) s/ p7 s
            pPlayerData-&gt;bActive = TRUE;</P># [, Z  ~/ b* N+ e2 `0 O
    <P>        UnlockPlayerData( pPlayerData );
    ( l7 i+ T1 x( x1 b) c+ t    }</P>  p: f, _4 k  V. x1 r/ O" _
    <P>    m_PlayerDataListLock.Leave();</P>' _( o" P: }9 L  N: v
    <P>    return pPlayerData;
    , d% ?) J9 W" N: K) I}</P>
    " k$ _7 t# \' h# @6 g4 b' j7 \, ]: B3 s+ O( z1 a; o  y; u
    <P>& c! ]- \5 u1 Q6 s
    //-----------------------------------------------------------------------------
    9 X) I5 N: m/ z, S0 T4 T// Name:
    . A- j8 ~4 L) `2 @* \// Desc:
    8 T* X  L- w3 a//-----------------------------------------------------------------------------+ R8 J! H% f& R  _
    void CMazeServer:estroyPlayerData( PlayerData* pPlayerData )
    $ r" r2 F; m! C# L6 r' A{
    6 o# _: t8 `' ^. j7 C4 }    m_PlayerDataListLock.Enter();- J; P0 }2 a) O$ m1 v& b
        LockPlayerData( pPlayerData );</P>4 B$ X- M. F; V$ z& r" G
    <P>    // Remove the player from its cell
    - q6 o# _+ w9 X; O2 X    RemovePlayerDataFromCell( pPlayerData );</P>2 J$ c/ h9 @3 c: T& G" r  H
    <P>    // Mark as inactive1 u! P# h# ^9 \9 Q
        pPlayerData-&gt;bActive = FALSE;</P>
    # `  g1 }; x2 |" k) g+ `+ u<P>    // Remove player from active list
    ' ~- |, A) w) C' N& P; w    if( pPlayerData-&gt;pPrevious )7 O0 c* t/ r1 {! G" u! D6 m6 a
            pPlayerData-&gt;pPrevious-&gt;pNext = pPlayerData-&gt;pNext;
    4 E6 s; [- m5 N3 i    if( pPlayerData-&gt;pNext ); L) T: f8 p2 t: b0 y$ E( |# R
            pPlayerData-&gt;pNext-&gt;pPrevious = pPlayerData-&gt;pPrevious;</P>
    5 Q5 M6 s1 X- g1 A  N, P<P>    if( m_pFirstActivePlayerData == pPlayerData ), L3 c( d* h  P9 P6 D2 O
            m_pFirstActivePlayerData = pPlayerData-&gt;pNext;</P>" K6 W2 i- T6 M4 G
    <P>    // Add it to the free list
    ( Q2 F& s) g! z+ I( m# T    if( m_pFirstFreePlayerData )! ~. `% S3 M; k$ Q% Q2 f) t" \* F
            m_pFirstFreePlayerData-&gt;pPrevious = pPlayerData;
    " J7 Z' E8 I7 S$ Y    pPlayerData-&gt;pNext = m_pFirstFreePlayerData;
    ( P5 @% K! v6 Z  Z' y6 M( j    pPlayerData-&gt;pPrevious = NULL;+ Z# M2 I# q9 A9 x( f0 h/ Z
        m_pFirstFreePlayerData = pPlayerData;</P>
    & s/ z/ T) T+ I, `- j. }/ j; d<P>    // Update count of players
    / P1 ~& `, M/ t9 ^7 I$ F6 |! x; c    m_dwActivePlayerDataCount--;</P>
    1 ^5 }# N& X5 b0 B3 W% h: c; j<P>    UnlockPlayerData( pPlayerData );
    7 h, Y" F( @  M, Q# W; x' J    m_PlayerDataListLock.Leave();' U  F# C% F% g
    }</P>
    " c! J& \: l: p: S' L4 G- R8 X, _+ B9 v6 L' s" Y& q: k: ]% S
    <P>1 z, m( V, f1 J, ]$ R
    //-----------------------------------------------------------------------------
    6 s3 k- _5 _0 W1 d* [- V// Name:
    6 n0 @8 ^* V; S( D) Q9 x0 _) M// Desc:
    9 \+ B: u, U9 v8 y' A//-----------------------------------------------------------------------------
    ! K! p. B0 y( vvoid CMazeServer::RemovePlayerDataFromCell( PlayerData* pPlayerData )4 i# ~- @$ R* n: [' O5 f2 w3 f$ L
    {' J3 x& m) V" r" s8 M8 p
        // Lock the player
    1 Q, B; f" n, U  l$ l    LockPlayerData( pPlayerData );</P>6 M( E& Y! Y6 ?& `% I
    <P>    // Lock the cell the player is in# m9 {& v: N0 h" n" V4 o/ A8 M7 d. }
        ServerCell* pCell;
    # _+ |- |* r. H) d5 U! ~    if( pPlayerData-&gt;wCellX == 0xffff )8 C# N& j5 B* \
        {% q8 W1 s3 I, @  J
            m_OffMapLock.Enter();
    7 t# n9 A( [2 ^: @5 S        pCell = &amp;m_OffMapCell;
    8 |0 |/ d! ]! H2 }0 Y& n    }: r2 u( @! N7 d9 {0 R1 k4 c
        else
    * e4 M3 N9 [/ \$ ~    {5 M$ @- O% Q8 ?
            LockCell( pPlayerData-&gt;wCellX, pPlayerData-&gt;wCellY );
    9 [' n$ X4 w2 m( ~4 R        pCell = &amp;m_Cells[pPlayerData-&gt;wCellY][pPlayerData-&gt;wCellX];6 B$ E/ N3 Q9 h/ r4 c( c3 z; z
        }</P>
    - q8 P, R& c5 U<P>    // Remove it from the cell
    + N8 J3 m3 y" C, ~3 Y! _    PlayerData* pPt = pCell-&gt;pFirstPlayerData;
    / }) o! r3 y3 x' g% X+ ^    PlayerData* pPrev = NULL;
    1 H2 ]8 Q: g5 P1 L; \. L" M1 Q0 W    while ( pPt )0 Y) U( F5 l$ T/ J% @0 \
        {
    . J. v, g; l' o: y        if( pPt == pPlayerData ): }3 |# `0 M1 s4 {' ^
            {
    : H  T3 T+ V! ]' E; _4 a! f            if( pPrev )
    / F! v+ d, o4 b4 H2 ?+ i5 S2 c+ r                pPrev-&gt;pNextInCell = pPlayerData-&gt;pNextInCell;4 R- V) t/ a( C, X7 ~  S5 C! n! \  H
                else
    0 w; Z  c; w! S6 ^0 m" g8 a                pCell-&gt;pFirstPlayerData = pPlayerData-&gt;pNextInCell;</P>: M) r3 I. {! @; l. @
    <P>            pPlayerData-&gt;pNextInCell = NULL;2 Y6 [+ U* A6 W2 v# r' T$ I
                break;
    2 x( i3 e4 ]  P2 T3 x        }# Z' C: m3 Z9 o) _
            pPrev = pPt;
    2 p  u, {5 g6 @% |- }6 K1 T  h9 ~        pPt = pPt-&gt;pNextInCell;( r. {7 \( p- j$ L
        }</P>
    0 L7 \9 d' q! i* s: x<P>    // Unlock the cell
    ' B, H" X( K, x    if( pPlayerData-&gt;wCellX == 0xffff )) t+ p' x" \5 N9 j5 @4 g; k
            m_OffMapLock.Leave();
    . `: \0 K* Z  d' a. x- O    else
    8 ]+ m8 H" J) Z: k# A- F8 F% _7 G        UnlockCell( pPlayerData-&gt;wCellX, pPlayerData-&gt;wCellY );</P>
    1 B) |  q; U5 w<P>    // Unlock the player+ E: s5 p1 j: p% s3 o
        UnlockPlayerData( pPlayerData );2 I! m* l& v  a9 J2 g+ z/ y
    }</P>
    6 A9 E' c. b6 @2 n  P- k6 K2 g0 J! D
    5 a. s$ C8 d8 s! b& P<P>3 ~7 m. F. s- M. z3 z
    //-----------------------------------------------------------------------------
    2 y6 c4 T5 ^" X5 _% c# Z3 z// Name: 1 I' D* u; r; P# J. B1 x9 ?, x0 M
    // Desc:
    8 x' a! {5 v1 V% Z$ o//-----------------------------------------------------------------------------: Z$ M1 ~: ]% E! d* w6 p
    void CMazeServer::UnsafeRemovePlayerDataFromCell( PlayerData* pPlayerData )) x( q6 j$ c; Q' U$ D9 d* g0 l  Q1 |
    {# m6 `) o6 a2 O& g1 i* ~
        ServerCell* pCell = GetCell( pPlayerData );3 r9 m: W4 ^% C* o# `* d4 V
        PlayerData* pPt  = pCell-&gt;pFirstPlayerData;- I" m2 O6 [3 W. d2 N
        PlayerData* pPrev = NULL;% |0 s& G5 G, k% t# ^; |
        while ( pPt )& I/ z: M& S/ I0 D# U) N, u( I
        {
    & c, T5 }' B/ w- i$ t6 @3 [9 y0 ~        if( pPt == pPlayerData )$ R" \! b1 I4 X/ W3 n8 k: N
            {
    6 Q1 K2 L9 {; b/ g1 ~& ?            if( pPrev )
    # R, ]! p$ b7 k+ V& I                pPrev-&gt;pNextInCell = pPlayerData-&gt;pNextInCell;
    4 n& l3 Y8 ?  u1 f            else
    ; G+ X% s- X# J( ?, R+ Z2 n                pCell-&gt;pFirstPlayerData = pPlayerData-&gt;pNextInCell;! \% z" B3 X3 a! W' S7 E! F
                pPlayerData-&gt;pNextInCell = NULL;  V1 |2 E! s+ {8 [9 G# H
                break;; ?: P3 O& t/ p) T' t* v
            }* b* H4 w! a  E% R" I( z2 r
            pPrev = pPt;( Q8 L+ G9 s4 g/ [3 R0 O
            pPt = pPt-&gt;pNextInCell;, b  i1 L! I( P+ J! R3 N9 M* _
        }5 D# F) n; `5 e% {( i  C) H' x
    }</P>9 I: Q) `, [6 [) V/ v  f( s
    ' p3 q/ b* [1 _
    <P>3 K( y! s6 _: }" k
    //-----------------------------------------------------------------------------9 N6 X1 N5 Z: J" r% F4 M5 ^
    // Name:
    " w. C9 p9 v% b+ W! ^// Desc:
    " O0 A* O9 R4 d1 `//-----------------------------------------------------------------------------5 S+ y$ D1 u# M. T' J
    void CMazeServer::UnsafeAddPlayerDataToCell( PlayerData* pPlayerData )
    8 U5 l. g! E% ~5 O4 |{& L7 p, P+ N. y& {
        ServerCell* pCell   = GetCell( pPlayerData );; \" N. X* y% t; j  s/ W
        pPlayerData-&gt;pNextInCell = pCell-&gt;pFirstPlayerData;
    9 e& Z% a. D+ u4 u    pCell-&gt;pFirstPlayerData = pPlayerData;
    7 L- x( P! G- O- o' j4 j" ?# E( t}</P>
    - E3 `+ [8 U# i9 M
    ' A9 v4 E0 u  X$ C. \<P>
    $ i% f0 ~2 j' _+ w# H+ L//-----------------------------------------------------------------------------
    9 P. \/ u2 a1 C2 b7 w0 x) w7 r// Name: : t; N6 M8 q1 q7 b* Y% Q% Y4 ?4 g
    // Desc: 9 o: [, T. y% z6 w
    //-----------------------------------------------------------------------------$ k+ E8 @. \4 i9 P; P0 u: E! q
    void CMazeServer::HandleClientPosPacket( DWORD dwFrom, ClientPosPacket* pClientPosPack )' N$ R) M  k. ^; ?( V& s( v6 g
    {! x" W, V# E$ Z& N& B6 g$ F
        // Grab player for this client and lock it
    , z/ e5 F5 r% K7 X% J    PlayerData* pFromPlayer = GetPlayerDataForID( dwFrom );. m! S$ {- P$ X
        if( pFromPlayer == NULL )' l, k0 y  o: s% V. q+ f, z
        {
    $ W6 ^% W# K/ {- `# j7 w& p$ F) f        if( m_dwLogLevel &gt; 1 )$ s8 g7 x0 a9 x
                ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Could not find data structure for this player"), pFromPlayer-&gt;NetID );
    4 O% A" \# N6 ^        return;8 o  g  \  O: f: D
        }</P>  `0 Q' T( J$ _' M( t& a& ^# X
    <P>    LockPlayerData( pFromPlayer );</P>9 V+ o6 ~- u; T- `7 n1 Y8 M) F" z; z0 F3 }
    <P>    if( FALSE == pFromPlayer-&gt;bAllow ), p6 Y2 j# _* ~/ C
        {" l9 D4 Z# }  M: v  e! E5 d3 j
            if( m_dwLogLevel &gt; 0 )
    ) |, F* P+ d9 j# W* K3 P6 }            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Got position packet from bad client.  Rejecting client"), pFromPlayer-&gt;NetID );</P>5 w% H) D3 \: N" x  p+ B) _' e
    <P>        m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );& q- f6 U6 r5 H# \* r0 v! H
            UnlockPlayerData( pFromPlayer );6 m# k; ~8 B* F# J$ `, s
            return;: I' j8 z3 [( \  Y
        }</P>
    * j) r) P1 s0 b4 A5 \! K<P>    // Compute the cell the player should be in now
    8 @8 Y5 [- ^  p! W3 x- `! d& a    DWORD newcellx = int(pClientPosPack-&gt;fX);
    5 A* _! p4 z, ^    DWORD newcelly = int(pClientPosPack-&gt;fY);
    ' V1 [4 I& [' M* b    DWORD oldcellx = pFromPlayer-&gt;wCellX;
    . R5 E7 J& Z" @7 a8 p: S    DWORD oldcelly = pFromPlayer-&gt;wCellY;</P>8 Z7 Z0 n, A. ~
    <P>    // Have we moved cell?
    : P% R2 g3 o- r( w0 p- G    if( newcellx != oldcellx || newcelly != oldcelly )" }( p, D  q/ F2 _3 I  s1 ~
        {; l0 H2 j2 R, W& g. B4 q
            // Yes, so lock the pair of cells in question
    ; s$ u1 I& e6 L& s6 @+ T        LockCellPair( oldcellx, oldcelly, newcellx, newcelly );</P>
    0 w: @; U3 t3 S% s. D7 G( ~<P>        // Remove from old cell and add to new cell
    4 }1 a7 o* ]1 j- i; M! R4 p        UnsafeRemovePlayerDataFromCell( pFromPlayer );0 W0 j% [) z4 f7 p& ?
            pFromPlayer-&gt;wCellX = WORD(newcellx); pFromPlayer-&gt;wCellY = WORD(newcelly);
    7 L! r- I' y" A- v% h$ m6 n. P/ {        UnsafeAddPlayerDataToCell( pFromPlayer );</P>
    0 B! o+ B9 E# C8 ?<P>        // Unlock cells' x5 M- k+ @7 ^7 k2 I
            UnlockCellPair( oldcellx, oldcelly, newcellx, newcelly );4 H7 S: o: k* w7 i5 X
        }</P>5 ]2 E8 E5 r! \; t
    <P>    // Update player position
    6 n% t) ?/ q# Z! h; S    pFromPlayer-&gt;fPosX      = pClientPosPack-&gt;fX;5 B1 Q7 C8 l: p! i) R- W
        pFromPlayer-&gt;fPosY      = pClientPosPack-&gt;fY;
    8 ]; b! [  S6 }    pFromPlayer-&gt;aCameraYaw = pClientPosPack-&gt;aCameraYaw;</P>
    9 L' U, b0 Y' O  K9 E<P>    // Allocate space to build the reply packet, and fill in header
    2 C" }" Q: S* d; v: t8 I    DWORD dwAllocSize;
    7 D, [6 \! J9 L0 H, S6 V, M) T4 h    ServerAckPacket* pSvrAckPack = NULL;</P>
    7 D# h8 E6 r* [- W0 l<P>    // Begin by allocating a buffer sized according to
      ?3 S( w! B1 N% }$ D    // the current number of nearby players + 4.  This will give ( S" R4 l" \3 z' R9 [; x
        // a little room for more players to come 'near' without resize
    $ K8 N% R" S$ ^+ k    // the buffer.
    ; a) K0 }: |% A* Q    DWORD dwMaxPlayerStatePackets = pFromPlayer-&gt;dwNumNearbyPlayers + 4;</P>" ?* i5 ]$ R$ h
    <P>    dwAllocSize = sizeof(ServerAckPacket) + dwMaxPlayerStatePackets*sizeof(PlayerStatePacket);- b7 O- w/ \$ o8 r) U3 p9 t% E. a
        pSvrAckPack = (ServerAckPacket*) realloc( pSvrAckPack, dwAllocSize );  {' S% p7 C# x
        if( NULL == pSvrAckPack )
    " }& [  l- w& C1 z# `: T    {# r$ A2 `# D& ~) S8 L
            // Out of mem.  Cleanup and return2 }$ p* n# T9 T% w2 ]: ?
            UnlockPlayerData( pFromPlayer );  M  X" e2 C9 }( B! [; T
            return;       / K+ j& C; v9 w+ n0 Q; i
        }' _$ z: q2 U1 h6 w4 b4 P
        ZeroMemory( pSvrAckPack, dwAllocSize );</P>
    4 Q% S" e; }9 v% i<P>    *pSvrAckPack = ServerAckPacket(m_dwPlayerCount);
    , ^4 ?* n' g- _# W% V    pSvrAckPack-&gt;wPlayerStatePacketCount = 0;
    1 I* B  y, o0 ^% z7 q! v4 {    PlayerStatePacket* pChunk = (PlayerStatePacket*)(pSvrAckPack+1);</P># ~2 N" [* O; z7 T3 P9 K- i
    <P>    // Compute range of cells we're going to scan for players to send, D- m; B1 U2 ?8 I# n$ M
        DWORD minx = (newcellx &gt; 7) ? (newcellx - 7) : 0;8 I& r! c" T4 K, l( F0 E% b
        DWORD miny = (newcelly &gt; 7) ? (newcelly - 7) : 0;; |  x( X5 q! a
        DWORD maxx = (newcellx+7 &gt;= m_dwWidth) ? m_dwWidth-1 : newcellx+7;
    - h5 G3 Q$ X+ r% Q    DWORD maxy = (newcelly+7 &gt;= m_dwHeight) ? m_dwHeight-1 : newcelly+7;</P>4 G+ w, {* m2 n  T" s
    <P>    // Lock that range of cells
    ( l8 p; Z9 T) P# y: k& H  e    LockRange( minx, miny, maxx, maxy );</P>
    ; B- h6 m* s8 s  D<P>    // Scan through the cells, tagging player data onto the end of
    5 |( F, S* @7 E    // our pSvrAckPacket until we run out of room& }0 N/ r/ A5 R$ G
        for( DWORD y = miny; y &lt;= maxy; y++ )
    4 q8 z2 p) ]! R    {
    6 C0 u" e& g8 E9 l7 a7 F        for( DWORD x = minx; x &lt;= maxx; x++ )  Y' j+ s% q& ~
            {8 ~! [# z1 [) J' T+ Y- _' w
                PlayerData* pCurPlayerData = m_Cells[y][x].pFirstPlayerData;
    0 O# x+ g. n/ C% w' K            while ( pCurPlayerData )+ R4 N. H- z) |* F
                {2 w! [6 L1 ]8 q6 X+ B
                    if( pCurPlayerData != pFromPlayer )
    % @. Y# }* B: x. X1 N. p/ O                {4 A: c) S5 f( K
                        if( pSvrAckPack-&gt;wPlayerStatePacketCount &gt;= dwMaxPlayerStatePackets )
    $ D1 r# [- [2 T7 m                    {
    ; G7 V7 G7 X6 H                        // Make sure pChunk is where we think it is
    7 x) j$ E3 Q/ N) ^0 O                        assert( (BYTE*) pChunk == (BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket)) );</P>7 H+ [4 x1 \4 q: w0 [2 o1 B
    <P>                        // There are more than just 4 new nearby players, so resize the 2 O) V) h  T# p* b& e7 m
                            // buffer pSvrAckPack to allow 16 more PlayerStatePacket's.% n4 f$ y+ K# E1 J/ ~5 G0 {
                            dwMaxPlayerStatePackets += 16;7 \% b- [9 |9 _$ c  T& G% d* ~* k# J
                            dwAllocSize = sizeof(ServerAckPacket) + dwMaxPlayerStatePackets*sizeof(PlayerStatePacket);
    ' r6 u! N, v" d  n7 \7 _6 Y  X9 w                        ServerAckPacket* pNewSvrAckPack = NULL;: z. `: w' p$ l) v. g
                            pNewSvrAckPack = (ServerAckPacket*) realloc( pSvrAckPack, dwAllocSize );2 Q$ t5 n* e* S
                            if( NULL == pNewSvrAckPack )7 \: l2 K6 p- L1 [9 [& m( R( g
                            {
    : c  `$ x7 ^9 u; E8 V                            // Out of mem.  Cleanup and return( b9 Y; L5 V5 I" O% ~/ q
                                free( pSvrAckPack );, P4 n8 L2 c) @7 K2 T# a; U4 |/ G
                                UnlockRange( minx, miny, maxx, maxy );
    1 T; A& j% i0 @8 _0 }                            UnlockPlayerData( pFromPlayer );
    * ?3 L, O+ G+ Z' Z% E* |, {                            return;      
    ; e2 L9 l) \0 w& e+ T                        }</P>, A, {. a7 c1 E* d
    <P>                        pSvrAckPack = pNewSvrAckPack;
    7 A; w" P' d4 h4 n' _                        pChunk = (PlayerStatePacket*) ((BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket) ) );</P>
    1 E' \8 Z6 ?7 K<P>                        // Make sure pChunk is still where its supposed to be6 Q) d5 i, S+ `+ a
                            assert( (BYTE*) pChunk == (BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket)) );3 E6 I) Q5 [/ D& v, x: E
                        }</P>% s. E0 R, U2 t" F4 E
    <P>                    pChunk-&gt;dwID       = pCurPlayerData-&gt;dwID;- }2 V: ]- l7 R" X# @1 ]
                        pChunk-&gt;fX         = pCurPlayerData-&gt;fPosX;
    2 N* _2 ^* }) b# w                    pChunk-&gt;fY         = pCurPlayerData-&gt;fPosY;
    6 C0 J  T4 a& u9 [' Y2 B7 s2 l                    pChunk-&gt;aCameraYaw = pCurPlayerData-&gt;aCameraYaw;* M6 z* i- ?( R0 z: c
                        pChunk++;% h6 o; U# [' H6 A1 w$ H
                        pSvrAckPack-&gt;wPlayerStatePacketCount++;
    6 x" K! |+ c, X% g: p& o* ?! @                }
    ) j* l! _* d6 C: z& F* w8 \4 x* }                pCurPlayerData = pCurPlayerData-&gt;pNextInCell;$ b0 a4 J; `) u* E# _
                }$ I3 f8 H/ t" I( L+ A3 V( j4 g! B
            }
    3 F1 p4 x- M+ Y    }</P>/ A! Z! _  ^9 V$ z
    <P>    // Update the dwNumNearbyPlayers for this player
    8 }. F4 Y3 U( S' L5 P    pFromPlayer-&gt;dwNumNearbyPlayers = pSvrAckPack-&gt;wPlayerStatePacketCount;</P>
    , s8 O+ _3 y" X" l, W1 ^" u3 }<P>    // Unlock range of cells9 Y/ f8 i$ \0 u9 A4 u& }( {
        UnlockRange( minx, miny, maxx, maxy );</P>
    ( a' P+ o, m/ J( R  t$ B0 g1 w<P>    if( m_dwLogLevel &gt; 2 )
    ; N3 r- ~1 g) r. _) L4 ^7 s    {
    4 G8 T0 |. ~0 j9 Y" @        ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Position is (%0.2f,%0.2f)"), pFromPlayer-&gt;NetID, pFromPlayer-&gt;fPosX, pFromPlayer-&gt;fPosY );; C$ s7 x7 ^, m. `1 O# N
        }( G$ ]5 n9 ~1 M1 x& K
        else if( m_dwLogLevel == 2 )
    0 k4 _% ]. I- b( {& ~, [- J    {% L5 U! w4 m3 A, N* Q" ?& @
            FLOAT fTime = DXUtil_Timer( TIMER_GETAPPTIME );
    ' X# b7 F2 n& h8 ~3 j! b        if( fTime - pFromPlayer-&gt;fLastDisplayTime &gt; 60.0f )
    : t4 p4 v% }2 i5 N        {8 r/ D; l0 y; p
                ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Position is (%0.2f,%0.2f)"), pFromPlayer-&gt;NetID, pFromPlayer-&gt;fPosX, pFromPlayer-&gt;fPosY );5 T3 L( J/ g# x$ U; R6 {, X
                pFromPlayer-&gt;fLastDisplayTime = fTime;
    % x" s5 {! M! V3 L4 I        }+ I  |9 `. q2 Y+ X
        }</P>
    8 R+ K$ u8 n! S9 R, O' E<P>    // Unlock the playerdata
      ?0 y, L9 m1 o  U5 D8 g    UnlockPlayerData( pFromPlayer );</P>9 f! |$ s; F) a, L9 a, C
    <P>    // Send acknowledgement back to client, including list of nearby players 9 v2 T# |  N/ k2 @7 W
        DWORD acksize = sizeof(ServerAckPacket) + (pSvrAckPack-&gt;wPlayerStatePacketCount * sizeof(PlayerStatePacket));5 r$ q2 i6 V) v- S! b

    2 u$ n! Y- M; y6 c0 t) W    // Pack the buffer with dummy data.2 o  k* T2 p; y* W7 t
        if(m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex] &gt; 0)0 K) {4 \( i8 Z& b+ p7 u
        {2 K5 {! T; }" C3 ?. Y1 Z
            DWORD   dwBufferSize = acksize + m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex];
    + `  L5 f; B# Z4 o" H. j: G        VOID*   pTempBuffer = 0;</P>/ d3 o# Q) D9 o+ L: O
    <P>        pTempBuffer = malloc(dwBufferSize);  x9 I3 F0 Z+ b7 C
            if( NULL == pTempBuffer )% J% E0 l% C  p: A0 J# l
            {
    " c/ u. Y3 z# d! t            //Out of memory
      S( g/ A' c; z* Z6 k. l            DXTRACE_ERR_NOMSGBOX( TEXT("System out of Memory!"), E_OUTOFMEMORY );3 ?/ c) K0 J! W
                free( pSvrAckPack );
    / |/ z0 L  U; x) R9 W! n: F: P            return;
    $ F$ n! g4 F8 n5 {7 r9 J        }</P>
    , M3 p& X- `7 P6 ?<P>        FillMemory(pTempBuffer, dwBufferSize, 'Z');
    ' e7 l% q; d7 C& z: E) C  J  e* s        memcpy(pTempBuffer, pSvrAckPack, acksize);</P>, J& s9 E5 O* Y! ~9 j
    <P>        SendPacket( dwFrom, pTempBuffer, dwBufferSize, FALSE, m_dwServerTimeout );! K2 J9 t  o  g  p! R* J- m3 D- j, Y
        1 R2 C* k2 i/ x1 k* ~) w
            free(pTempBuffer);
    % _- Y0 o& {7 A5 u    }   
    # K, T- v: \8 }1 t5 U  c  W) D    else
    / r5 x& r- m. g2 C    {6 {8 F/ y, U8 z# F
            SendPacket( dwFrom, pSvrAckPack, acksize, FALSE, m_dwServerTimeout );7 X4 p7 M  S2 l0 |
        }</P>0 i5 w3 B$ y; Z+ \
    <P>    free( pSvrAckPack );</P>
    . @+ {2 F' N$ e1 \- y<P>}</P>3 O7 d% g; j8 S, `
    # W' n6 M/ T- b5 i8 }- ?" K0 K, B# c
    <P>
    * A3 C1 {5 K' c0 C//-----------------------------------------------------------------------------
    + f4 \: X; f: `, p+ ?+ |// Name:
    6 |; p0 Z3 x% C// Desc:
    . d6 p! d) S% m' j//-----------------------------------------------------------------------------( L1 O1 z* k5 ?; F3 }6 p0 ]
    void CMazeServer::HandleClientVersionPacket( DWORD dwFrom, ClientVersionPacket* pClientVersionPack )
    3 z$ m) E8 y& \' u) z' ]{
    * N" X8 @, \7 a2 E5 ]: P    // Grab playerdata for this client and lock it* c) [( A( F7 S& @0 U
        PlayerData* pPlayerData = GetPlayerDataForID( dwFrom );
    # t, R6 ~" W2 V6 ?. M+ b    if( pPlayerData == NULL )* ?- [. d  d' R: R0 S' {
            return;/ h4 f/ W( A. l
        LockPlayerData( pPlayerData );</P>* k: e9 R# [: X5 k: g9 ^" Z
    <P>    // Record the version number ) R+ T+ U9 q0 n# e7 \. j) C" h* E! F; a
        pPlayerData-&gt;dwVersion = pClientVersionPack-&gt;dwVersion;</P>
    $ x" l8 ?% i8 s- ?) o<P>    if( m_bLocalLoopback )* b% Q& p* B- O6 T
            pPlayerData-&gt;bAllow = TRUE;; M# w$ ], j4 y4 Y; k& C1 U5 _
        else, U* i& K( h$ s
            pPlayerData-&gt;bAllow = IsClientVersionSupported( pClientVersionPack-&gt;dwVersion );</P>
    ) D3 J9 l! @1 C<P>    if( m_dwLogLevel &gt; 0 ): \: c5 M+ T* ~
            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>+ O. G4 }8 E( M9 U: ^
    <P>    if( FALSE == pPlayerData-&gt;bAllow )1 I# c5 L: [4 |; X
        {
    4 O8 S  C7 [- c8 L1 ?! m        if( m_dwLogLevel &gt; 0 ); R4 m) X0 o& l. E9 b, [
                ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Rejecting client"), pPlayerData-&gt;NetID );</P>/ X6 m  E: F" v3 t
    <P>        m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );- @& d! X- M( H( }& K5 @0 j
            UnlockPlayerData( pPlayerData );
    + [, U2 v( e% v  w3 W        return;
    " U1 `+ h7 q1 B# x2 j9 T    }</P>
    " I& n3 [& m4 o# ^9 P; x" C: o* H<P>    // Unlock the playerdata. T' k# C& R0 t  S% a
        UnlockPlayerData( pPlayerData );</P>
    * N! d+ o$ q0 j- _3 M<P>    // Send acknowledgement to client that the client was either accepted or rejected! B8 z- V! y. w5 F7 \$ O  A* S, {! ?5 L
        ServerAckVersionPacket packet( pPlayerData-&gt;bAllow, dwFrom );/ u0 F: E; M, K% }
        SendPacket( dwFrom, &amp;packet, sizeof(packet), TRUE, 0 );' M2 K" e% r! S1 M' B
    }</P>
    5 w: E! e, D) T' H+ `( `; e" {, I! _$ X: a
    <P>/ M( T% i% F1 w8 E; T
    //-----------------------------------------------------------------------------
    6 d0 C6 g$ m% Z. E: H2 x% H// Name:
    1 O: B; b3 ^8 p- R0 s! E- z// Desc: " ^, y% V% U6 ]3 C4 R
    //-----------------------------------------------------------------------------) ~! @4 G  t! R( F" n
    BOOL CMazeServer::IsClientVersionSupported( DWORD dwClientVersion )
    $ L$ b# Q" G! n{' @1 ]9 L7 N0 ~& o/ K
        switch( dwClientVersion )
    2 o. O+ B# N8 Y* }% n9 m    {8 f7 w2 n6 k1 k* P( }- p$ [6 J$ U; P
            case 107: // only v107 is supported
    " z9 a8 j( E; E( W4 N1 D' K            return TRUE;
    6 R: l( o: ]3 W+ a8 D. X9 ~+ j        default:
    ' s% s: v8 `# M2 O4 Y            return FALSE;) n% ]3 b/ J# b1 A
        }6 I8 e$ Z  z2 A& k. d- ]
    }</P>8 L$ d  N) ?% W: l+ r, i

    6 J) D" T( U4 D- @& b' a. i1 w<P>  ]* S) j6 Y- c% E: K( x. L  ^
    //-----------------------------------------------------------------------------* F  J" o1 ~5 P7 P
    // Name:
    + W* V' N3 w. w! _7 @! E- Y// Desc:
    ! Q# S% F& f/ ?' {$ D, ^- K//-----------------------------------------------------------------------------3 b  L( [1 {0 A
    void CMazeServer::HandleUnknownPacket( DWORD dwFrom, ClientPacket* pClientPack, DWORD size )
    ! g  N5 ^6 @% X" g{
    5 k! Y: \  C6 J8 T. _- {    if( m_dwLogLevel &gt; 1 )
    + D7 Z. ?/ Z$ X9 i, X# V; h        ConsolePrintf( SLINE_LOG, TEXT("ERROR! Unknown %d byte packet from player %0.8x"), size, dwFrom );</P>8 v3 @3 @. a; R, s" ]
    <P>    m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );2 t7 c4 O+ J' ]$ b
    }</P>- Y$ A9 e; ~* j& P& R$ |8 g
    ( T- p: r- }  C# A
    <P>
    , r1 R. X9 T9 F- S6 X//-----------------------------------------------------------------------------
    : m7 z2 t0 D8 x% q" S// Name: & y! R* X) A) e* M" h& a, d3 ^
    // Desc: 8 h0 X9 A9 k" b/ ^! h& H
    //-----------------------------------------------------------------------------
    1 N6 g4 q6 U- T( r( Q8 q, KDWORD   CMazeServer::IDHash( DWORD id )
    # }- g! G# B' S{
    , V6 Y' }( I" {    DWORD   hash = ((id) + (id&gt;&gt;8) + (id&gt;&gt;16) + (id&gt;&gt;24)) &amp; (NUM_ID_HASH_BUCKETS-1);
    " g: o5 Z9 [0 ~! J) A9 N& f+ P    return hash;$ v! G/ a1 Y4 h
    }</P>
    % D# n/ V& g  Z* d7 y% `3 B0 A# B( ]( T2 q( y& j
    <P>* ^: C5 p2 E" a: _2 N# Q6 l
    //------------------------------------------------------------------------------ h8 k, E+ ]+ N5 j
    // Name:
    / V1 l& q: ^* a! ]/ q. `// Desc:
    ' |5 m4 ], g9 G' n- n- Z$ o//-----------------------------------------------------------------------------; k# T3 K* M! ?4 b3 [" [/ n
    void CMazeServer::RemovePlayerDataID( PlayerData* pPlayerData )
    3 A. ?& E6 Z! ~2 F{
    3 M) e7 x1 N3 i    // Hash the ID to a bucket number0 o! W, D1 H& N( I% j" h
        DWORD   bucket = IDHash( pPlayerData-&gt;NetID );</P>
    1 @7 S; Z6 @/ X+ ^8 t<P>    // Lock that hash bucket
    2 J( A% C- l. m' }; H    const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;/ k+ }  ?& }( w/ I/ ~) o2 t
        m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>& F* z/ k; A6 @, I3 ^
    <P>    // Loop though players in bucket until we find the right one
    # ^$ x+ r( d! T6 C0 F    PlayerData* pPt = m_pstIDHashBucket[bucket];; r0 u& h; [  S/ Y# J% Q: U0 M
        PlayerData* pPrev = NULL;& R9 R  Z; m+ H! p" Z, |# f
        while( pPt )+ Q- ?7 X$ A2 [8 d; C: Z, m
        {( k9 v: s" q5 \/ Q; O3 z0 _
            if( pPt == pPlayerData )
    4 @3 _% V" }: @2 g( x/ |& |( g            break;
    $ U3 G% |6 b! `8 q" v- o        pPrev = pPt;
    9 K0 m0 m+ o! \5 R5 K: }        pPt = pPt-&gt;pNextInIDHashBucket;
    . V% g( D! t) z    }</P>% Z. t% Y0 v1 \) L1 A8 k
    <P>    if( pPt )
    5 Y& ]' |9 w6 J! R* v' ]7 X! `    {
    4 a* J8 s: v  I        if( pPrev )# {% b' i+ L4 `
                pPrev-&gt;pNextInIDHashBucket = pPt-&gt;pNextInIDHashBucket;
    $ ^9 r# N& l2 C7 \$ X- `        else5 `7 J8 `& i/ H  P# q* I9 P+ k" k
                m_pstIDHashBucket[bucket] = pPt-&gt;pNextInIDHashBucket;% ~$ x; Z3 I( A2 D3 H' H! f# b5 y  C
            pPt-&gt;pNextInIDHashBucket = NULL;7 J3 c; [) R) |% J: ?) g
        }</P>
    , y, l4 j7 x, e. Y1 {: Z6 q1 V<P>    // Unlock the hash bucket$ k2 b, L) r/ `7 K0 [: p
        m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();5 n0 [+ e. Q3 ?' V
    }</P>
    & m4 Q5 g  I% n: m( C. i/ `2 `6 I7 i: v1 [) a; E2 i4 j$ J7 Z6 ^
    <P>
    5 Z4 @, W4 @( _" ~//-----------------------------------------------------------------------------7 `  |6 ?' s9 L) S; R7 p
    // Name: ) ~/ x  \3 J& T4 U8 P' {( b
    // Desc:
    ' d0 s! H$ D  ]9 \//-----------------------------------------------------------------------------
    # z1 U6 Q, N! @- Vvoid CMazeServer::SetPlayerDataForID( DWORD id, PlayerData* pPlayerData )
    , p- r# A6 Q1 F: ~8 S. m{3 }( _9 R1 `  B" i
        // Make sure this player isn't added twice to the m_pstIDHashBucket[]
    5 B& t6 Q* ?% L' F# T5 r  k    // otherwise there will be a circular reference5 r/ G$ _& c+ X8 p0 E
        PlayerData* pSearch = GetPlayerDataForID( id );
    ; d; g# r" y; [% G1 h    if( pSearch != NULL )
    1 `3 J2 T+ _2 ^! T3 k2 |+ P        return;</P>
    , Y7 O1 i) Q: `0 L4 ]( m( {& v<P>    // Hash the ID to a bucket number% x- W. v. I1 ^+ Q3 J& m6 D' i
        DWORD   bucket = IDHash( id );</P>, v- E. w% Q7 _* f% f% C
    <P>    // Lock that hash bucket
    . j9 `( c3 ^0 ?/ d8 [& n    const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;" \$ C) D& |- a1 ^6 @# I% j3 Y0 W
        m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>
    ( t8 Y& i* A7 o, K<P>    // Add player onto hash bucket chain9 x  Q8 y# e" i" z
        pPlayerData-&gt;pNextInIDHashBucket = m_pstIDHashBucket[bucket];& _) ?6 b; U3 M. C% Z
        m_pstIDHashBucket[bucket] = pPlayerData;</P>
    , c2 h( |1 s- M9 c- L7 O<P>    // Store net id in player
    4 w" E* o4 W1 N4 B6 B3 u3 _/ g6 Z    pPlayerData-&gt;NetID = id;</P>
    ; ~; C! V3 J- l/ S5 z" L, u) t3 ?9 r  {<P>    // Unlock the hash bucket
    - _% W5 D1 N! p* i5 ^7 ^    m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();- E1 t! f- G: f  r' e6 l& `* K
    }</P>0 M) Z9 k+ U3 L

    + \+ t$ p+ b5 i) {8 }$ P<P>. B1 y6 |1 O( \( u  x
    //-----------------------------------------------------------------------------. ]2 k7 y6 W- K' V
    // Name:
    2 W& }6 x# c* `! d$ \0 m( l6 t// Desc:
    - S2 W5 T( ]4 P* d: l; O. L//-----------------------------------------------------------------------------: y+ _; Z# X) m1 @
    PlayerData* CMazeServer::GetPlayerDataForID( DWORD id )
    ' h2 j: S6 b2 R) D/ l# _1 A{
    & n, l+ Y. \3 w. d/ P) \2 S: M" \    // Hash the ID to a bucket number; c5 d% J! H+ V# E, B8 p/ D
        DWORD   bucket = IDHash( id );</P>- {$ l3 u# `% ^! O5 Z
    <P>    // Lock that hash bucket
    2 x' S/ |" E6 \; ?/ x3 m( ]    const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;
    8 e: C' S) h( H# j2 }' P* {" s    m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>
    5 m3 ~7 D  {; j4 ~5 a<P>    // Loop though players in bucket until we find the right one
    # q% g) i  F8 a/ F! d    PlayerData* pPlayerData = m_pstIDHashBucket[bucket];4 P  h2 X6 W8 m5 ?
        while ( pPlayerData )
    + G9 X. b' c' D/ \    {
    . X3 t- m1 S% ~6 N! `( x* `  w        if( pPlayerData-&gt;NetID == id )
    6 d8 E  D2 N0 ^+ @; `( o* a            break;  T/ L) b  ^* _# D# \
            pPlayerData = pPlayerData-&gt;pNextInIDHashBucket;
    0 y9 I3 B. ~4 O: U, m3 K    }</P>3 F0 B2 ?' J+ ^2 [
    <P>    // Unlock the hash bucket' K  T# O# n% v2 ]+ T
        m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();</P>
    , l& G7 o+ ]5 P# n! _+ O  T/ c1 n) u<P>    // Return the player we found (will be NULL if we couldn't find it)
    $ d) f' P, g- W; T/ I3 \4 `    return pPlayerData;
    8 t9 p: E# q0 e3 d  k  P: b}</P>
    ; c+ A3 F5 @5 Q; u% C  t  Z' `3 q. Y. s: g2 M& Z7 b. O/ x' d  H
    <P>
    0 r4 z  q5 ]" n0 E! M//-----------------------------------------------------------------------------
    8 [8 k3 L8 p8 K  J4 A: |% r// Name: 3 f  s! l' q. l4 m2 R# o) m
    // Desc: calls DisplayConnectionInfo for each connection in a round-robin manner
    , n* H2 |; X/ O8 Z9 f1 Z7 i$ ~  @//-----------------------------------------------------------------------------. s2 s+ d8 Z3 g8 s
    void CMazeServer:isplayNextConnectionInfo()7 k5 }5 O4 R* c% e0 y: ~
    {# \5 B4 u' w$ o+ M! Q
        if( m_pNet )
    , W6 _2 m2 C7 j' x' N! F    {6 L% v+ F( O- u0 U; {
            // Find the player that was displayed the longest time ago, and display it.# H% o* d, \- x+ k! f
            FLOAT fCurTime = DXUtil_Timer( TIMER_GETAPPTIME );
    4 U3 b/ h$ X. Z2 Y, ]        PlayerData* pOldestPlayerData = NULL;4 j) @6 k) G" `: Y, [
            FLOAT fOldestTime = 0.0f;</P>
    ) D& i7 P4 C0 Y4 N$ J! j+ A<P>        m_PlayerDataListLock.Enter();</P>
    ' e7 t: H: \1 h2 X: c3 @<P>        PlayerData* pPlayerData = m_pFirstActivePlayerData;- `8 D! v, L, L6 y* W: j6 t2 h
            while ( pPlayerData )# g/ N$ Z- R& S! S" h4 _4 f  P; u& |
            {! E3 y6 y4 M0 C( H$ p
                if( fCurTime - pPlayerData-&gt;fLastCITime &gt; fOldestTime )
    4 p" y% B2 s2 R            {
    1 Q" M( S1 W; D                fOldestTime  = fCurTime - pPlayerData-&gt;fLastCITime;2 B% v- `( R* K8 G; Q
                    pOldestPlayerData = pPlayerData;& G. b1 l: d+ `0 Z0 R, z
                }</P>+ g1 b/ `2 {0 V& b
    <P>            pPlayerData = pPlayerData-&gt;pNext;
    ' t: J  F4 J' u- E4 \, H        }</P>+ e* C5 k/ r  n; j3 M. s# i; ?
    <P>        // Display the player with the oldest CI field, and update its CI field.7 _2 {1 B, u6 }/ M0 W
            if( pOldestPlayerData ); p& z( T# f! h$ g$ R
            {9 ]( e0 v" C8 w, \
                ConsolePrintf( SLINE_LOG, TEXT("Displaying connection info for next player") );
    7 n5 ]2 u* E3 {2 T6 D0 E3 Y            DisplayConnectionInfo( pOldestPlayerData-&gt;NetID );
      T3 x6 p1 i+ V, b            pOldestPlayerData-&gt;fLastCITime = fCurTime;8 [6 j* N$ A; w+ w
            }
    : ]& A  j( L5 b$ R; j8 l        else
    2 `' v- q4 ]7 A: Z        {: u. a# t% G5 w0 P
                ConsolePrintf( SLINE_LOG, TEXT("No players found") );  X" g* L) @/ S, f( Y  ~9 @
            }</P>
    % _+ X3 g; j' _! ^<P>        m_PlayerDataListLock.Leave();
    % j. f. f* E! C) d& v1 L5 i5 l( w& C0 I    }' P: O0 P: g( d: j" E5 y8 I) I& T
    }</P>
    2 z  y4 B5 w0 ]" j6 n
    8 ^$ I0 n7 Z5 m$ ?& B! s<P>
    * d, N9 L: f% j  }- l/ v//------------------------------------------------------------------------------ v+ X4 n4 S) g4 b; a2 a: e! W
    // Name:
    / l+ Z' \1 l& t& [) G" n// Desc:
    8 d- I/ m& d$ ?. Y; e( `& r//-----------------------------------------------------------------------------
    : p8 R0 y/ J# g4 c- j) Z7 l- [% gvoid CMazeServer:rintStats()
    / `1 o" W: R& w0 ^{: a/ K# e8 Y8 ~) X
        ConsolePrintf( SLINE_LOG, TEXT("Thread count: Active=%d Avg=%.2f Max=%d"), 3 H9 G! H! s. }: d' W6 i; N
                                        m_wActiveThreadCount, m_fAvgThreadCount, m_wMaxThreadCount );
    7 h0 y0 a8 m- `! B    ConsolePrintf( SLINE_LOG, TEXT("Thread Time: Avg=%.4f Max=%.4f(s)"),
    8 N& c( O' t2 j& \/ X                                    m_fAvgThreadTime, m_fMaxThreadTime );
    & J8 r+ n% U& P) t) [    ConsolePrintf( SLINE_LOG, TEXT("Players online (not including server player): %d"), m_dwPlayerCount );  E) K7 f% c# {5 U
        ConsolePrintf( SLINE_LOG, TEXT("Peak player count: %d"), m_dwPeakPlayerCount );& B5 s1 [/ d* I# A1 [( ^( X6 P" ]+ z
    }</P>
    ! o: N  L1 p! ~8 a0 T1 p' M9 t! e6 G" y3 w, u  a
    <P>
    ) y% m$ P' @; D+ X6 e9 k2 q//-----------------------------------------------------------------------------/ }0 d3 b% }* i2 V7 S- M
    // Name:
    % I  B/ t. A4 X& T// Desc:
      `9 `( r5 k. d//-----------------------------------------------------------------------------
    , f, ~5 J' K# n$ e- hvoid CMazeServer:isplayConnectionInfo( DWORD dwID )
    + E0 l7 k  t9 ^4 l. D/ Z0 S{
    : ?; s! _% ^  p, f9 L7 P4 ]6 g/ m    TCHAR strInfo[5000];
    + K. }" T% o2 G$ U; Y    TCHAR* strEndOfLine;. x; v/ G8 U  c, d2 W4 w* F
        TCHAR* strStartOfLine;</P>
    5 {1 p& v0 v! ?' y) j! u3 q5 C/ C<P>    // Query the IOutboudNet for info about the connection to this user' R: @4 b7 J5 v8 Y; ^' q
        m_pNet-&gt;GetConnectionInfo( dwID, strInfo );</P>
    , X, F& j* W1 ?<P>    ConsolePrintf( SLINE_LOG, TEXT("Displaying connection info for %0.8x"), dwID );
    6 V( L* Z9 v4 H9 Q0 z# i    ConsolePrintf( SLINE_LOG, TEXT("(Key: G=Guaranteed NG=Non-Guaranteed B=Bytes P=Packets)") );</P>
    ! S# ~$ l2 Z* g6 \<P>    // Display each line seperately
    ' P( c) z# u7 n2 ~    strStartOfLine = strInfo;
    4 x5 e# T! N, E) r    while( TRUE )1 I/ A! D5 l3 l6 F( R
        {
    . V  N- [6 l3 G  d        strEndOfLine = _tcschr( strStartOfLine, '\n' );
    / b% l- ]4 R( J0 w2 V  d        if( strEndOfLine == NULL )
    " J7 Y9 F' Y9 x( }) n" }, H            break;</P>
    ( u8 Y* D( T& n- p8 i2 S<P>        *strEndOfLine = 0;' z) N6 R( a6 W8 @2 h# s
            ConsolePrintf( SLINE_LOG, strStartOfLine );: W( e' _) ]& F% P+ f3 K2 N  J
            strStartOfLine = strEndOfLine + 1;
      S) O/ G# `) H7 k7 z# [5 R    }) W- T( t' P, _7 C" K: P
    }</P>
    ' x3 l, y7 G' E! i4 j( l; E2 u2 r: S8 W  c' |
    <P>1 _4 I8 Z7 a0 Y! g7 I4 G3 m
    //-----------------------------------------------------------------------------* r1 z. P' Z' }$ D9 r
    // Name:
    " W: `4 Y5 k. n' J+ ^4 f/ w) B// Desc:
    1 m: @) L8 R1 N: ?//-----------------------------------------------------------------------------. s% a$ \; [; i9 d" I' Y" ~
    HRESULT CMazeServer::SendPacket( DWORD to, void* pData, : J) x. _4 t( M0 x
                                     DWORD size, BOOL reliable, DWORD dwTimeout )6 x, i  t3 \* b- v  b1 g3 A8 @/ ]
    {$ l6 f' u3 V5 o1 @' o4 O  y! g) x
        // Chance of forcing any packet to be delivered reliably2 [7 h3 M( @0 G) H% m9 O0 E+ ^
        if( m_Rand.Get( 100 ) &lt; m_dwServerReliableRate )7 f: _2 ]& B  v5 B
            reliable = TRUE;</P>* e& W& @. p  v7 W: c. c. l$ {
    <P>    return m_pNet-&gt;SendPacket( to, pData, size, reliable, dwTimeout );2 E- ?4 `6 g( V  S. E% `8 K
    }</P>
    6 _/ w* ^: z: w3 i2 |; `
    4 O3 b! n; W2 {6 i7 T- a! I, e<P>% s# }& X. u7 S+ O8 D8 X$ u
    //-----------------------------------------------------------------------------/ H3 u* Y* q+ ~2 @1 e
    // Name: 5 ~) X/ ~- P  C3 T5 r: P% T
    // Desc:
    ; m0 O, p+ X. c3 {( ?$ Z. i  [//-----------------------------------------------------------------------------) j* l4 T  b' n
    void CMazeServer::SendConfigPacketToAll( ServerConfigPacket* pPacket )3 ^* P8 l+ {3 v* u; s5 C: Z
    {
    & N! ?3 d6 A2 |' \8 }* u3 i/ A    // If we're up and running, then send this new information to all clients
    - m8 z& e1 s. X  b8 R! N    if( m_pNet )3 D" d9 p: X; B6 I# s% c+ b8 v. u
        {
    6 q& V! S1 B' k4 X  n. z        //Use the AllPlayers ID
    # i1 J* R2 ^* {2 c+ }        SendPacket( DPNID_ALL_PLAYERS_GROUP, pPacket, sizeof(ServerConfigPacket), TRUE, 0 );
    * o# x4 g, i; W1 o. p4 K+ i+ K* T    }. ^. P. J9 W' r3 o, I0 U$ J5 b2 X3 F
    }</P>1 Z9 U. B) R$ e8 D# h
    4 n7 a0 n% K$ {/ {
    <P>
    & v$ Y' r6 ]* ?) L5 G! c3 S. Z//-----------------------------------------------------------------------------
    ; `3 ^* D* q9 V/ D8 E0 ]: \$ [// Name: 2 E' @! r4 i# a3 r
    // Desc:
    3 I6 Y& k' l3 t& j5 x: x" c//-----------------------------------------------------------------------------4 a! V% Q6 Q; R' u4 Z( j8 H$ q0 f
    void CMazeServer::SetClientReliableRate( DWORD percent )
      J9 D9 V6 ]3 m5 e& g{* u4 ]3 g+ K, [
        // Update client config, and build packet containing that data
    1 |! t' r3 X$ o2 ~8 ^    m_ClientNetConfigLock.Enter();( s$ M) S9 [3 t% b9 g
        m_ClientNetConfig.ubReliableRate = BYTE(percent);
    2 @) k- B$ J0 J6 k    ServerConfigPacket packet( m_ClientNetConfig );$ d: I- s- [6 S1 A7 H" D- ?
        m_ClientNetConfigLock.Leave();</P>( T' ^8 V% F( A& @+ y3 C
    <P>    SendConfigPacketToAll( &amp;packet );
    7 p# q, {8 k! v2 `# F% T) j' r}</P>, ]3 Y% a9 n1 ^

    : h; s5 h( ^2 i) a- u9 n<P>5 E3 T1 x$ `' [5 U& a+ F
    //-----------------------------------------------------------------------------1 M% |! `  B6 P+ T: s6 j5 l( _
    // Name: ) ]0 r  u% ?; P# s* S6 n
    // Desc: 6 s) |) [% P$ Z; t* {4 G6 w) `
    //-----------------------------------------------------------------------------2 L* F3 d4 p. f) W! T( ]$ T2 R, Y
    void CMazeServer::SetClientUpdateRate( DWORD rate )
    - |* c8 r0 r8 b3 L& g{, ~' W+ P5 b, C- M2 R3 c% ?: s
        // Update client config, and build packet containing that data- d) I; t, b2 R- U. T" R/ H
        m_ClientNetConfigLock.Enter();: N2 }9 @! F' j1 A2 B+ V3 T
        m_ClientNetConfig.wUpdateRate = WORD(rate);
    : I4 ~2 ~2 S1 e- q, q) j    ServerConfigPacket  packet( m_ClientNetConfig );
    . j5 {( m# P* Y8 u4 W3 e    m_ClientNetConfigLock.Leave();</P>
    1 w# N! U  j* ~1 W; ~7 ]<P>    SendConfigPacketToAll( &amp;packet );3 n" m* k; P1 ]5 u4 O. R3 [
    }</P>: Q, a$ k  ]( P% ?% [

    9 G% ^) {5 |8 R! G" {+ O/ Q: l/ B# _<P>8 m- z$ y" Z% d- H
    //-----------------------------------------------------------------------------
    8 s4 q9 k0 i  ~5 T( s6 a// Name: * _5 ?. Z4 i* G' ?3 ~  w8 V8 ?+ ?0 f$ j
    // Desc:
    , \) Z  d) M1 b* z3 A8 [1 q5 J//-----------------------------------------------------------------------------5 M! g7 r. w$ G' D0 c4 Z! w& E
    void CMazeServer::SetClientTimeout( DWORD timeout )
    # J! `# E& i2 U2 k$ x: e2 K{
    5 n* q, v3 D; L9 _. Q    // Update client config, and build packet containing that data
    + {+ d/ P& q2 }    m_ClientNetConfigLock.Enter();$ T1 R! n: ?3 T' n' W( ^0 y$ o
        m_ClientNetConfig.wTimeout = WORD(timeout);+ B' w" O+ O- U: y$ t
        ServerConfigPacket  packet( m_ClientNetConfig );
    ; o) W9 O# X# R  m+ l# O    m_ClientNetConfigLock.Leave();</P>
    ' T- b! K: B3 w% g5 o<P>    SendConfigPacketToAll( &amp;packet );7 _5 q0 w" B' x
    }</P>( W7 X- x" f& `0 c4 _. C

    $ g: {+ K' {# y3 m( n<P>9 D3 W3 q: l! c( ^& {" k
    //-----------------------------------------------------------------------------
    0 P6 |' Q6 {: y1 e# B7 B4 |& V. X// Name: + I  C; }+ `0 c( d& a( }9 s, d* t- I
    // Desc: : V' m! K+ p  b% r- W- i% P- a
    //-----------------------------------------------------------------------------! i6 t3 z# ~9 \
    void CMazeServer::SetClientPackSize( DWORD size )! @+ b  ^6 w  W% o1 |
    {
    * P. n/ I; [6 [6 H$ r    // Update client config, and build packet containing that data
    2 C5 S2 l1 j! p0 i/ H" U    m_ClientNetConfigLock.Enter();, C; Z" H5 F. y; F
        3 _' D1 k8 \0 }/ h" f' \
        m_ClientNetConfig.ubClientPackIndex++; //Increase index and verify location in array.; u( C2 t- ?4 ~1 c: I8 e8 ^
        if(m_ClientNetConfig.ubClientPackIndex &gt;= PACK_ARRAY_SIZE)   
    " X& d9 s. ]7 q: j! M        m_ClientNetConfig.ubClientPackIndex = 0;</P>
    5 |* @$ T4 F6 l# ~8 b<P>    m_ClientNetConfig.wClientPackSizeArray[m_ClientNetConfig.ubClientPackIndex] = WORD(size);
    ( j/ `. B. }$ O* F& i% ~  c% u$ T  x    ServerConfigPacket packet( m_ClientNetConfig );
    : V( \2 M  v( ~    m_ClientNetConfigLock.Leave();</P>% l3 e' b3 B7 G5 C% G+ r
    <P>    SendConfigPacketToAll( &amp;packet );( h! R; I" H) g: I! a
    }</P>
      j, ^. f/ {4 w; j' a3 O& L
    2 U2 T5 N. A2 k! Y) [<P>/ f5 [% ?1 b8 C" s$ }9 ], p4 M: K
    //-----------------------------------------------------------------------------5 {# U, r3 U$ E; T
    // Name: + x- Q0 c2 Y; J* ?- |, M
    // Desc:
    ; C4 S; N  U4 P, m& Z//-----------------------------------------------------------------------------, t# M( k7 a4 p7 w( R: d9 E+ ?
    void CMazeServer::SetServerPackSize( DWORD size )  W' ^9 Y# X, \5 k0 b4 Y
    {
    4 C) {9 ^. W4 L  ]& A& p( k- O    // Update client config, and build packet containing that data) m! J/ B# Z* f7 B" s
        m_ClientNetConfigLock.Enter();
    ( }2 B& m  q, q0 t8 y1 W( e9 V   
    . R( V7 R2 B* ]$ U    m_ClientNetConfig.ubServerPackIndex++; //Increase index and verify location in array.
    , L: L* O$ M1 s% X$ s    if(m_ClientNetConfig.ubServerPackIndex &gt;= PACK_ARRAY_SIZE)   
    / v  @- H7 `0 Y. h" u1 Q" B        m_ClientNetConfig.ubServerPackIndex = 0;</P>/ ?' t9 d6 H4 V, ?, [( u% R* |
    <P>    m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex] = WORD(size);
    / ]7 g- P# e  T5 e9 R& m, F6 \    ServerConfigPacket packet( m_ClientNetConfig );0 ?# w+ K* N8 P- M8 E6 i8 f
        m_ClientNetConfigLock.Leave();</P>& C2 D2 v4 x7 |8 A" J4 k
    <P>    SendConfigPacketToAll( &amp;packet );
    6 d, q' z+ T6 G7 x5 E3 f# g}</P>
    , B: Q) a' p, F+ O<P>
    , t- N. f; ]  S! w//-----------------------------------------------------------------------------# [  X# y  E# {+ g0 ]5 l
    // Name:
    ! G, Z; f$ X: N' E// Desc: ' E$ q; P+ i; E5 _! f$ a8 f; W+ B) \
    //-----------------------------------------------------------------------------3 W/ W: e" q2 P: V! L' r. ]. _* _
    void CMazeServer::SetClientThreadWait( DWORD dwThreadWait )
    ) V7 A% N3 ~- n2 N6 W{
    ; H" L% e( _1 t    // Update client config, and build packet containing that data
    4 Y3 Z3 y# w  y, P0 k    m_ClientNetConfigLock.Enter();8 m- ?1 L# z) X. n- t# C
        " r2 M5 X# Q: K
        m_ClientNetConfig.dwThreadWait = dwThreadWait;" d( ^, P! M, B% z3 @7 f
        ServerConfigPacket packet( m_ClientNetConfig );: v7 Z# i" P' O) g
        m_ClientNetConfigLock.Leave();</P>2 I9 k+ j  O9 t) @' X. [( U
    <P>    SendConfigPacketToAll( &amp;packet );* ~# Y3 e/ K1 M/ ^
    }</P></DIV>
    zan
    转播转播0 分享淘帖0 分享分享0 收藏收藏0 支持支持0 反对反对0 微信微信
    您需要登录后才可以回帖 登录 | 注册地址

    qq
    收缩
    • 电话咨询

    • 04714969085
    fastpost

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

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

    蒙公网安备 15010502000194号

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

    GMT+8, 2026-8-9 03:45 , Processed in 0.490153 second(s), 51 queries .

    回顶部