QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 4249|回复: 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>. L! E% B1 a  e  Q% J
    <>// File: mazeserver.cpp
    + }$ ]' r7 J& l//
    ( \% p% k% ]# w4 x, {/ R// Desc: see main.cpp% t: I& s, z: e; X/ S
    //
    5 w  F2 f/ n% T6 w0 L, O6 W// Copyright (c) 1999-2001 Microsoft Corp. All rights reserved.% e; E7 q$ L7 C2 E4 d- n/ N' {
    //-----------------------------------------------------------------------------& ]8 Z7 \, ]7 V
    #define STRICT6 g2 n% E- t/ z, z8 l' K9 E6 x( x
    #define D3D_OVERLOADS
    6 f. w: V' z/ g#include &lt;windows.h&gt;: H0 J) L$ t1 F" g( n1 F3 T
    #include &lt;d3dx.h&gt;
    ) t; c" c  q: J5 K# O* P& i: J5 I#include &lt;stdio.h&gt;
    1 E: M" T2 n+ `. D#include &lt;math.h&gt;( D& e% G1 Z; m
    #include &lt;mmsystem.h&gt;
    5 ]/ {) r2 s5 U) f" C#include &lt;dplay8.h&gt;
    ' f  t# C, E# N  i4 T#include &lt;dpaddr.h&gt;, M7 \* x; w2 T; }* \  h  Y4 d( s; H
    #include &lt;dxerr8.h&gt;0 d: |0 ]8 g2 _# c$ W
    #include "DXUtil.h": _9 V7 }9 Q, U% V
    #include "MazeServer.h"+ a0 L  o1 ^# f$ `
    #include "ackets.h"
    + T3 g2 t5 o. t$ ?. s#include "Maze.h"
    ! s) ]  t; p4 v9 b8 Z#include &lt;malloc.h&gt;1 [& X, q* B2 N3 h( S- i2 t
    #include &lt;tchar.h&gt;</P>
    % }/ k" O  k9 {: t( i+ K3 _% n# O2 [  d5 `  m
    <>//-----------------------------------------------------------------------------2 A/ j' c" Y6 [) e+ @9 I4 q
    // Name:
    * |/ f3 G- `: L( O* {// Desc:
    # C2 E# h3 u4 V. h" e9 Y//-----------------------------------------------------------------------------
    5 J4 v0 l! J6 U" d5 l: ACMazeServer::CMazeServer()
    ! b) ?/ X  E4 }) K{
    ; Z4 u0 n" G  e" p; B    m_dwPlayerCount         = 0;8 {  v. O- s6 m/ A; q
       
    $ J1 B+ m7 Q: x5 w    m_wActiveThreadCount   = 0;. t# w2 A; z' W- o+ ~
        m_wMaxThreadCount      = 0;
    ! R9 M9 ^% J* Z5 Z4 E" E  z' M; t    m_fAvgThreadCount      = 0;: P( R4 _! o8 h5 d- D1 u
        m_fAvgThreadTime       = 0;
    & I' ]6 u9 W% c; O; m    m_fMaxThreadTime       = 0;</P>
    . a  ]1 g  N4 R( \. m6 L& l<>    m_dwServerReliableRate  = 15;
    # ^0 q% Y9 X8 q: Z( ?$ b! `    m_dwServerTimeout       = 150;3 a/ t- V5 v2 T5 L! b" b& w
        m_dwLogLevel            = 2;
      t7 T2 S- y) y5 X    m_pMaze                 = NULL;</P>4 {8 F9 W5 U4 F' m
    <>    m_ClientNetConfig.ubReliableRate = 15;2 `% \% c  w8 v. \  `4 P
        m_ClientNetConfig.wUpdateRate    = 150;
    8 }1 T) T& ?/ L+ G) d' u  l    m_ClientNetConfig.wTimeout       = 150;</P>
    : K# I8 a  a: R; s. ~$ L- M( S4 O<>    m_ClientNetConfig.dwThreadWait = 0;</P>
    # @# d7 f) r. c0 a. y<>    m_ClientNetConfig.ubClientPackIndex = 0;" R- k  i4 `5 o, i& i. t
        m_ClientNetConfig.ubServerPackIndex = 0;7 V1 D; w0 n  z
        for(WORD x = 0; x &lt; PACK_ARRAY_SIZE; x++)" Z) d. [) ?% X( W: r4 ^- ~; m
        {8 W+ q  y* u. Q4 l) f5 z, t
            m_ClientNetConfig.wClientPackSizeArray[x] = 0;6 i3 ^- v( S6 C8 I* l$ S) I
            m_ClientNetConfig.wServerPackSizeArray[x] = 0;* Y( k2 E+ H  J
        }5 ?" [! g# B+ y, {
    }</P>
    " a3 P* P8 ~' B, J" p+ u1 x% ~8 i/ X; u9 [2 O7 }
    <>) x# W2 M! ]. ~
    //-----------------------------------------------------------------------------
    % E: ]9 W8 p2 l: M// Name:
      _! A4 i2 L; s7 D$ l. \3 m// Desc: 6 S; i& |1 U% ^& n: k( M% R5 O
    //-----------------------------------------------------------------------------
    3 S. i( m# j0 }& nHRESULT CMazeServer::Init( BOOL bLocalLoopback, const CMaze* pMaze )# {  ~5 |+ h. [3 R% r
    {, x3 [3 c& W$ a# B
        m_bLocalLoopback = bLocalLoopback;
    6 B8 }1 \  T8 d+ T2 Y    m_pMaze = pMaze;: X8 B8 N8 h7 D! r: r6 l
        if( m_pMaze == NULL )
    , h9 l6 D+ d$ t5 ]! U! D! n        return DXTRACE_ERR( TEXT("aram"), E_FAIL );</P>
    ; J5 _6 n% T& {5 g% N& ~! K<>    // Grab height and width of maze' D, ~6 O" X+ d* F3 i+ u  h
        m_dwWidth = m_pMaze-&gt;GetWidth();; b* n# i0 e' z. P
        m_dwHeight = m_pMaze-&gt;GetHeight();</P>% F; x. _. {# n* m3 v
    <>    m_ClientNetConfig.dwMazeWidth  = m_dwWidth;
    : G+ X) I3 Y  n3 Q, W4 g    m_ClientNetConfig.dwMazeHeight = m_dwHeight;</P>
    + z% }; h+ k2 j! L0 v<>    // Validate size. Must be a power-of-2 times LOCK_GRID_SIZE. Compute the shifts.- @) b, e; h: ~$ c& `5 c
        if( m_dwWidth &gt; SERVER_MAX_WIDTH || m_dwHeight &gt; SERVER_MAX_HEIGHT )! {" G& U- W7 M" ]) [
            return DXTRACE_ERR( TEXT("Maze height and width need to be less than 128"), E_INVALIDARG );
    # U) ]% `$ G6 T    if( (m_dwWidth % LOCK_GRID_SIZE) != 0 || (m_dwHeight % LOCK_GRID_SIZE) != 0 )
    * H5 S. G" [) A# d6 E! M" r        return DXTRACE_ERR( TEXT("Maze height and width need to be divisable by 16"), E_INVALIDARG );</P>
    ) y8 R9 n6 E; b" @, |- @<>    DWORD scale = m_dwWidth / LOCK_GRID_SIZE;
    0 q6 q- @8 {3 Z' L4 v* J& u    m_dwMazeXShift = 0;
    $ A5 @7 i6 b) l    while ( (scale &gt;&gt;= 1) )
    % u+ h7 b! i! \. J) ~        m_dwMazeXShift++;</P>
    4 h2 E& Q! o, Z<>    scale = m_dwHeight / LOCK_GRID_SIZE;
    * }7 Z& E2 P% Q% _& V1 }' O: L2 |# H    m_dwMazeYShift = 0;4 f8 k- O' I6 h! y& A
        while ( (scale &gt;&gt;= 1) )& ~3 E" I( S4 n8 k( O. K, u& P: G
            m_dwMazeYShift++;</P>
    & @2 P5 `4 p' g" X4 \<>    if( ((DWORD(LOCK_GRID_SIZE) &lt;&lt; m_dwMazeXShift) != m_dwWidth) ||4 S' R" m$ z, @& M
            ((DWORD(LOCK_GRID_SIZE) &lt;&lt; m_dwMazeYShift) != m_dwHeight) )0 Z5 k6 b2 s: t# ^/ v
            return DXTRACE_ERR( TEXT("Maze height and width need to be power of 2"), E_INVALIDARG );</P>
    # [7 J& u  C: x! |<>    // Initialise the player list3 G$ ]$ S0 R% Q1 H; R% C
        ZeroMemory( m_PlayerDatas, sizeof(m_PlayerDatas) );. v- d/ R: F9 E( g
        m_pFirstActivePlayerData = NULL;
    - M+ g2 n9 O1 M2 F  \    m_pFirstFreePlayerData = m_PlayerDatas;
    9 g1 W' Q3 C  a0 q; C" \% Y/ `) [    for( DWORD i = 1; i &lt; MAX_PLAYER_OBJECTS-1; i++ )/ E. \( S1 }3 L
        {
    3 r! `- r6 J5 Q4 u        m_PlayerDatas.pNext = &amp;m_PlayerDatas[i+1];
    ; O% j" C1 v$ E6 U9 l        m_PlayerDatas.pPrevious = &amp;m_PlayerDatas[i-1];( _6 a0 y6 v" v7 S; Y0 \
        }</P>. l( `9 ?. \  l3 l  q) V8 K" ^
    <>    m_PlayerDatas[0].pNext = &amp;m_PlayerDatas[1];5 c. u( z9 x* o+ j; k
        m_PlayerDatas[MAX_PLAYER_OBJECTS-1].pPrevious = &amp;m_PlayerDatas[MAX_PLAYER_OBJECTS-2];7 I/ v4 \8 ~" s
        m_dwActivePlayerDataCount = 0;7 ]0 S" Y. h3 Z4 z
        m_dwPlayerDataUniqueValue = 0;</P>
    0 y5 V, l. q; X7 w* t5 Y6 X<>    // Initialise the cells
    3 I; o. c, @6 o. Z. _/ t5 R    ZeroMemory( m_Cells, sizeof(m_Cells) );) p9 I' Z/ Z3 {( m
        ZeroMemory( &amp;m_OffMapCell, sizeof(m_OffMapCell) );</P># x2 X3 t! P) k, _8 j. R
    <>    return S_OK;
    . y9 O, z! G1 @9 y8 i* {}</P>
    % I: x2 K7 N2 `1 l7 L. s; @5 d1 G+ a, C* X
    <>; u6 f, T4 j+ `
    //-----------------------------------------------------------------------------
    " ~8 q( r4 t; c% k3 r// Name:
    , F/ C5 z1 e' X. I$ [5 z1 ]// Desc:
    - ~; [9 S1 q2 n' B! z3 D//-----------------------------------------------------------------------------
    8 N; g+ d5 ?# x( I- `) d/ Kvoid CMazeServer::Shutdown()
    # F! t  p4 j  j/ U2 @& e8 W% u{
    - Q  j2 g. D. b2 b- {# C! b  y. w}</P>' ?- J- N/ Y$ I; |/ h2 [

    / }8 _" H! c$ |1 F, Y5 C<>& f, c( }6 ^  _  [
    //-----------------------------------------------------------------------------
    3 l3 T, }2 B/ ^! J/ E) j6 \- A- P" q0 _// Name:
    / r5 R8 N3 S  k8 D0 {// Desc:
    9 }; H, X; W' f; w, s: Q/ g% o//-----------------------------------------------------------------------------
    , S# a, v; `9 ?0 Gvoid CMazeServer:ockRange( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )$ i& n7 U8 x5 M, q4 n
    {3 Q1 A. m/ @* S& w6 L. M+ J4 ?, q
        m_LockGrid.LockRange( x1&gt;&gt;m_dwMazeXShift, y1&gt;&gt;m_dwMazeYShift ,
    & M  a, h0 a3 J- A3 a                          x2&gt;&gt;m_dwMazeXShift, y2&gt;&gt;m_dwMazeYShift );* ?& j7 C7 c4 K% T* K( ~( Z8 p
    }</P>
    ! ~' ~8 l3 R$ n9 i& P% i3 A
    2 T" ~" [$ f+ h7 M<>
    / `1 W* l# K5 p( ~//-----------------------------------------------------------------------------
    + h( ~6 ?8 i+ r$ P- d5 X// Name: " K1 s% m  y7 E; V. ~
    // Desc:
    8 E' c& T! m) T( b//-----------------------------------------------------------------------------" v& c3 g- t3 O: d0 B! U8 K, V, K
    void CMazeServer::UnlockRange( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )
    ; H2 n3 ^5 r9 u9 E! Y1 t{
    : g3 E! q1 V- S8 `& F9 Y# y" ~    m_LockGrid.UnlockRange( x1&gt;&gt;m_dwMazeXShift, y1&gt;&gt;m_dwMazeYShift ,- n( L5 d7 i/ P* N% H/ j
                                x2&gt;&gt;m_dwMazeXShift, y2&gt;&gt;m_dwMazeYShift );
    0 N; R6 o+ B- f$ o; W, e/ f}</P>
    $ D/ i/ A4 s# p" [( Q
    , m* |2 `5 }& F0 e+ A0 K8 c; {/ W<>
    + ^6 `. ?$ ~& R4 r( g# ]; M//-----------------------------------------------------------------------------! B3 a, {: u1 U: N: p9 v
    // Name: . I+ K# S( \3 [: z1 q
    // Desc:
    4 P( U& E5 x. F- O7 F% Z3 x//-----------------------------------------------------------------------------) p) Z/ J) P+ R/ E
    void CMazeServer:ockCell( DWORD x, DWORD y )
    3 J) p) g9 E# M6 _& N( r: z# ~. _{
    / l6 f' X3 V6 b4 g6 [- Z+ h: h& s    if( x == 0xffff ): ^( l# N6 S* q# Y1 w  `1 Q6 {
            m_OffMapLock.Enter();5 s9 C" {+ j" m0 V4 S
        else3 L% c7 x' ~) _' ]) E, N
            m_LockGrid.LockCell(x&gt;&gt;m_dwMazeXShift,y&gt;&gt;m_dwMazeYShift);1 \0 t. E" }4 j0 G: H' D
    }</P>! A5 W# m% C/ P. ]1 n

    ! x6 Z" Q; S" `<>
    1 e% Q0 [1 x( r9 l. \; y: D//-----------------------------------------------------------------------------
    4 @+ X& w$ ]( s* {/ I8 j// Name: 8 C  O: u/ Y( c' [* ^
    // Desc: ! t5 |4 R3 w. c" U/ R! O1 x7 h
    //-----------------------------------------------------------------------------* _* z7 X) P5 j- ~% f% o
    void CMazeServer::UnlockCell( DWORD x, DWORD y )
    7 Q! e; n* f, Q% A; s{; N% W7 S( @6 w
        if( x == 0xffff )7 |3 V, a4 }, D9 ?6 N, I
            m_OffMapLock.Leave();9 R' }, ]7 j4 D& K) o& m
        else. L* c* ?3 p* K2 \  S" D
            m_LockGrid.UnlockCell(x&gt;&gt;m_dwMazeXShift,y&gt;&gt;m_dwMazeYShift);* X1 V5 Q0 W3 j' Y% ~
    }</P>
    4 V; ~$ a6 [0 j1 x) ^! M3 J# y, t, J& F8 b% p, T" i
    <>) `, m( }0 t, b5 O% }
    //-----------------------------------------------------------------------------
    6 @. |5 P7 l' [// Name:
    ) t6 D. a0 F8 F// Desc: : U8 t& u6 Q, L- e: L5 b
    //-----------------------------------------------------------------------------
    6 R( o" Y! j. Tvoid CMazeServer:ockCellPair( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )
    ' J% b4 r* W' F$ P{3 F1 ^. z+ c0 I
        if( x1 == x2 &amp;&amp; y1 == y2 )
    8 _3 D7 K9 k3 _9 {) |" u& ?; a    {( x  ~9 q- K7 f/ P3 F7 `* ^: Z
            if( x1 != 0xffff &amp;&amp; y2 != 0xffff )( o+ d9 O! ]. Z3 S8 k
                LockCell( x1, y1 );
    5 `  r( F2 c$ w! ?# P/ }        else' b- u/ m! K* U% z$ b. z$ ~
                m_OffMapLock.Enter();</P>
    ' F( e3 ^" g9 C  C2 u+ e<>        return;1 T  }) U9 f2 W# f. r
        }</P>
    - r9 H' x, X# }9 b* W, |: g7 }1 }<>    DWORD x1shift = x1&gt;&gt;m_dwMazeXShift;, y6 ?& o# M1 L6 {$ w5 l! M. j
        DWORD x2shift = x2&gt;&gt;m_dwMazeXShift;" W2 k) t, }. R, b* d
        DWORD y1shift = y1&gt;&gt;m_dwMazeYShift;& V/ S+ W% A3 H5 ?% E+ t
        DWORD y2shift = y2&gt;&gt;m_dwMazeYShift;</P>' A6 @6 u' z3 L% w0 o/ }
    <>    if( x1 == 0xffff )
    / j# r/ p/ w3 l. X6 O) g    {( K  {* s, ?. P
            m_OffMapLock.Enter();/ N/ ]7 W3 ]) v9 W( O
            m_LockGrid.LockCell(x2shift,y2shift);, P# l6 l8 I0 J, x2 S
        }
    9 A& c- j5 H7 Z. ~    else if( x2 == 0xffff )
    1 U8 Z2 Q. s2 l    {
    ' \- B* n6 T( p  l3 }* V  q7 o3 n        m_OffMapLock.Enter();. N9 W& @+ n3 M; o% n6 V4 s
            m_LockGrid.LockCell(x1shift,y1shift);. i  h3 v( p) t
        }( h9 z% D( T6 Y: Z
        else 6 H  `- D* A8 z
        {
    ' }1 T3 h* d% K: Q5 E        m_LockGrid.LockCellPair(x1shift,y1shift,x2shift,y2shift);
      V- W# S8 N! a  g& G! M    }- {, n% ~. c, n( o7 j9 r. S; k
    }</P>
    3 _0 `! A4 {/ k4 Q% L! e- g
    2 o4 G& g0 m' K7 z- `<>2 B* x; v* l* L
    //-----------------------------------------------------------------------------
    0 V( r/ F4 l* V" e" \- H& q// Name: 1 b- G  i# ~; S' z0 F5 ~
    // Desc:
    - x: |' U/ D: ?& Q9 w) R//-----------------------------------------------------------------------------
    7 u1 \% j$ U! _5 r4 ?' p. t# ?, W4 hvoid CMazeServer::UnlockCellPair( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )
    2 d9 U3 P: r0 p5 P. s7 z{
    ! [+ K4 {' Y' a9 h5 }8 |. J    if( x1 == x2 &amp;&amp; y1 == y2 )
    0 Y- k3 C, U. u    {" o; u' ^2 Q& T% m9 x6 Y( |5 _
            if( x1 != 0xffff &amp;&amp; y2 != 0xffff )4 I: o' B7 v& ~' S& d$ u% W0 Q) n. ~( a
                UnlockCell( x1, y1 );% \2 `' b' }( m& Q* F
            else
    9 x3 W2 P  I  G4 F! Y) T& x            m_OffMapLock.Leave();</P>4 [: ?% q$ M- B  b# y/ u6 J0 O
    <>        return;& g+ J; @. w7 h5 z
        }</P>
    : Q; @& E8 A/ I8 Z, r) R/ f' l<P>    DWORD x1shift = x1&gt;&gt;m_dwMazeXShift;/ c  }6 L7 O5 M  L* U3 c
        DWORD x2shift = x2&gt;&gt;m_dwMazeXShift;% Z$ ^; S- i1 s7 w: k
        DWORD y1shift = y1&gt;&gt;m_dwMazeYShift;, C2 }' }$ N2 x; k  |2 J
        DWORD y2shift = y2&gt;&gt;m_dwMazeYShift;</P>/ n: h3 h  k3 P: S8 }1 H( f
    <P>    if( x1 == 0xffff )
    ( ?5 N2 s, R4 r3 H% M    {
    : P) N* Y! A* M* r. [+ l' F1 o        m_LockGrid.UnlockCell(x2shift,y2shift);  o  u8 d' s0 Q! O# ^0 N/ Q
            m_OffMapLock.Leave();
    9 M7 ~" R# I8 R4 U6 Z9 L    }
    3 E. `" B6 ?8 N6 Z    else if( x2 == 0xffff )+ g3 D3 R. v* ~* }! F9 d3 m
        {0 r! U+ N# F# M6 Z+ [5 ~( H
            m_LockGrid.UnlockCell(x1shift,y1shift);; w7 B. b! F4 z. n/ C) G6 G! `
            m_OffMapLock.Leave();
    : m" u0 ]: G8 V+ f, `& [& m" Z6 Z: P5 d    }( K  F( p4 c1 Z/ e3 O% [# m
        else
    8 w% J& s+ W  R; l: h0 ~    {0 {8 s+ S2 [8 @
            m_LockGrid.UnlockCellPair(x1shift,y1shift,x2shift,y2shift);0 f' T) z0 l: k# F1 x& J" V
        }
    : G9 [0 j) A  ~! y2 [4 N. p9 `}</P>' n/ f" K( @" O7 v( e

    ( v% s6 ]/ H9 f# m. b' s<P>
    ; i4 Q8 I6 T2 S# f& y" E//-----------------------------------------------------------------------------
    0 t  ~! K2 A: i0 r% P4 K  O// Name: 0 m9 K0 Z5 j. e' W) m4 @
    // Desc:
    8 l. e+ I# R) A6 a- v9 y! b//-----------------------------------------------------------------------------  }1 U' }9 H; T+ `7 S
    void CMazeServer::OnAddConnection( DWORD id )
    * r+ v4 K! {3 K- L* b( F5 w{$ B* D5 N  R* E
        m_AddRemoveLock.Enter();</P>; d8 R5 \2 q1 a, t4 U4 L  Q
    <P>    // Increment our count of players6 A; G$ o5 f4 E5 f. Y
        m_dwPlayerCount++;
    / p: v+ ^: J1 x5 y8 U, @4 J    if( m_dwLogLevel &gt; 0 )
    4 X0 m. r" E$ y6 ^    {% B) W1 B# H, t8 G
            ConsolePrintf( SLINE_LOG, TEXT("Adding player DPNID %0.8x"), id );
    1 B8 N2 j1 Q* |        ConsolePrintf( SLINE_LOG, TEXT("Players connected = %d"), m_dwPlayerCount );
    : q0 U5 _, y8 J/ G) S- i    }</P>
    - e* \8 E+ \6 ~) m# p( g1 q5 _7 W<P>    if( m_dwPlayerCount &gt; m_dwPeakPlayerCount )9 H# @( u  s! f8 Z. h6 U
            m_dwPeakPlayerCount = m_dwPlayerCount;</P>
    ) T% U0 S6 I# U' ?! E1 L# c5 r5 b<P>    // Create a player for this client
    & o; G& f* ]' B+ p  Y# [    PlayerData* pPlayerData = CreatePlayerData();  U" S3 C: l7 Z9 G6 O7 X& @; n9 `
        if( pPlayerData == NULL ); ?& W, J3 o) A$ O
        {  t: K, ^/ H& q, |  n. y7 e; \
            ConsolePrintf( SLINE_LOG, TEXT("ERROR! Unable to create new PlayerData for client!") );+ O' \4 t7 z* y# `
            DXTRACE_ERR( TEXT("CreatePlayerData"), E_FAIL );) i" t% h6 P" v2 p6 l3 F
            m_AddRemoveLock.Leave();2 L  ^3 T6 W4 c: I
            return;
      r4 w' `3 J' ^' F6 a; M( y2 b    }</P>
    ( F  G3 a: Y9 {7 m! o<P>    // Store that pointer as local player data
    $ l% W0 ]1 l4 j    SetPlayerDataForID( id, pPlayerData );</P>
      ^( h3 y$ S9 E<P>    // Grab net config into to send to client( ?. I0 J* f$ R* b
        m_ClientNetConfigLock.Enter();/ A5 e5 ]$ q% W( A2 H
        ServerConfigPacket packet( m_ClientNetConfig );
    * {* D! c4 \$ q5 X$ X" d    m_ClientNetConfigLock.Leave();</P>( h* D; K. |, S9 n; f! _
    <P>    // Send it3 h7 Q2 u2 h2 z
        SendPacket( id, &amp;packet, sizeof(packet), TRUE, 0 );</P>( S1 R, i! u% x8 h
    <P>    m_AddRemoveLock.Leave();
    3 O2 _: d6 @* P3 ~: \7 L5 |}</P>
    ' M. z/ ^1 i) }  k3 m3 {" @. S/ E
    <P>
    0 G6 B+ g0 N" L//-----------------------------------------------------------------------------
    # j! `; {# J0 ?# _// Name:
    ! m1 M9 v9 M! ~, U5 S// Desc:
    3 s8 f0 M4 X9 u, Q" S) R' l6 g& X//-----------------------------------------------------------------------------
    ) D0 a0 J" _, Bvoid CMazeServer::OnRemoveConnection( DWORD id )/ }0 |. b7 `1 w  t+ e( B& U
    {9 B' j7 M' W: T, Z8 ?
        m_AddRemoveLock.Enter();</P>5 j0 `% \; s& [; J- ^! {
    <P>    // Decrement count of players/ K, c3 h; D( ]4 I, [; O# C
        m_dwPlayerCount--;</P>5 q, o* V8 l4 b# C% V1 ^' W
    <P>    if( m_dwLogLevel &gt; 0 )' A- y+ y% U( w! Z" P/ {
        {" d- n0 t! X7 ]. a! c8 T5 J0 G" n
            ConsolePrintf( SLINE_LOG, TEXT("Removing player DPNID %0.8x"), id );3 ]2 y" U. u/ ~9 y' p+ J2 S
            ConsolePrintf( SLINE_LOG, TEXT("Players connected = %d"), m_dwPlayerCount );
    2 T. w( ~# h3 r1 Q$ J( p    }</P>
    $ g2 m1 A; b" o; l" q' a, x<P>    // Find playerdata for this client1 v/ p% v9 \7 Q; L
        PlayerData* pPlayerData = GetPlayerDataForID( id );* ^: _# b, ?, a+ f) P0 T
        if( pPlayerData != NULL )
    0 d( b- H5 L$ C) ^5 D: }    {3 j, x- D' ^5 X: k2 D! A5 T1 v
            // Destroy it& R! Z( n+ X# q6 n& x
            RemovePlayerDataID( pPlayerData );- U/ h. z& X6 ^) f2 p
            DestroyPlayerData( pPlayerData );# o) ~1 B# o% L" I8 O9 t9 z
        }</P>7 H6 a/ E: q5 g  s
    <P>    m_AddRemoveLock.Leave();
    : n+ j3 F( g. S3 y}</P>
    ( C2 k# M8 W1 X+ e' M# b
    # x2 Q7 J+ e  M1 l<P>
    8 H5 G# E: y( \* T. H//-----------------------------------------------------------------------------
    ) w1 i! k1 w- Y// Name:
    2 V* c* O' D. v0 u% u6 H( ~// Desc: , O! f, C# L3 g( l7 R
    //-----------------------------------------------------------------------------# g6 F' \* h; T( d  {; }4 ?- d
    HRESULT CMazeServer::OnPacket( DWORD dwFrom, void* pData, DWORD size )( i7 `" c- F9 g* \/ }/ L2 `( _
    {' H% Q3 U: b- a
        BOOL fFoundSize = FALSE;</P>" t; Z1 q( \. l$ f- \1 K
    <P>    // Increment the number of thread we have in this process.
    : g% p7 y; y/ @; N5 V8 |* u    m_csThreadCountLock.Enter();</P>
    / D2 l; v2 f- H$ _3 s<P>    //Get the start time of when we entered the message handler.
    : p: m8 P+ j+ A, K. j    FLOAT   fStartTime = DXUtil_Timer( TIMER_GETAPPTIME );</P>
    ) X# r5 W2 W  m# ^. o+ D<P>    m_wActiveThreadCount++;
    + }5 J/ c/ W+ p+ d, [* t) c# i    if(m_wActiveThreadCount &gt; m_wMaxThreadCount)+ m. J9 Y8 ^* b, h- J* J+ h8 |
            m_wMaxThreadCount = m_wActiveThreadCount;
    + D* i8 l& Y9 @6 _9 H; c    ; W. H6 N& f! F+ w0 F; L1 \: G( P
        // Calculate and average.& k4 [1 z' C5 _7 }0 k8 q
        FLOAT fdiff = m_wActiveThreadCount - m_fAvgThreadCount;
    : L; b4 K) ]/ S" x, \' T, E9 D    m_fAvgThreadCount += fdiff/32;- I9 s( d: F3 |5 [5 {9 R6 F# o
       
    0 k$ [7 p: k  U& ~  ?/ y/ O    m_csThreadCountLock.Leave();</P>
    6 q8 K! K( Q, \9 t<P>
    # h$ p6 y' s: l/ L    ClientPacket* pClientPack = (ClientPacket*)pData;
    9 u" I0 B. t8 H- a2 s2 C    switch( pClientPack-&gt;wType )
    . D/ }' F, ]9 K    {1 m+ _( E* U8 S% S# |  {/ X% q
            case PACKETTYPE_CLIENT_POS:: _: n7 ?) F( a8 f8 b
                
    3 I2 t0 R! u1 N' x. ^: H/ p            // Check to see if the packet has a valid size. Including ! S+ Y+ z; m+ M2 V  ?  o% |8 o
                // the custom pack size.6 f+ w3 G& f+ J6 Y
                if( size &lt; sizeof(ClientPosPacket))9 q$ ?+ I2 g, r  X$ B" z
                    fFoundSize = FALSE;
    * V$ P, r7 d4 ?5 l" g5 ]7 v) ?            else if( ! IsValidPackSize(size - sizeof(ClientPosPacket)))
    8 t; g9 T, w: u9 j                fFoundSize = FALSE;8 ], |& Z5 t% ?& x! w+ m
                else/ @6 Z2 [. [4 {$ s
                    fFoundSize = TRUE;</P>
    2 Y/ }2 t0 o" W4 r5 _) m<P>            // If valid sized packet, handle the position.
    - V3 q5 w4 F. o" ]* T3 y            if(fFoundSize)
    ' K3 D4 ~6 f5 u  ~+ S; @, F                HandleClientPosPacket( dwFrom, (ClientPosPacket*)pClientPack );) }0 J4 G( s7 g9 F
                else
    6 D/ U# c3 }& O5 E" s                m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );</P>
    2 D) S: c% R+ V2 j5 [; ^* `<P>            break;</P>
    ( X. a* v# w1 N) Z3 I- Y<P>        case PACKETTYPE_CLIENT_VERSION:4 X; I: X2 v- b4 [% N
                if( size == sizeof(ClientVersionPacket) )) x, S2 l) q" _- @
                    HandleClientVersionPacket( dwFrom, (ClientVersionPacket*)pClientPack );
    / ~) W% J! D4 [8 F. _- _            else
    9 n" \5 T& `' u2 _- \* g5 S                m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );
    6 j0 V- V- c; v, z  c& C+ M            break;</P>
    ! u- k" w9 I9 [3 N5 h  c) X' ?<P>        case PACKETTYPE_SERVER_CONFIG:</P>
    3 z7 k2 S( @& V3 g+ t3 ^# c<P>            // Server config packet sent to all users (including server). Just ignore and continue.</P>( e7 s' [/ L! k
    <P>            break;
    ) W3 l  a4 F0 F6 ?5 E- ?        default:
    ' L, g5 \. g" D. }* M2 V- C            HandleUnknownPacket( dwFrom, pClientPack, size );1 v" R: ~, l0 T6 d9 P
                break;+ C( G8 i0 b! D7 Z% O' m/ H7 X, g" |
        }</P>
    5 a/ y* x, M+ P- {' n; v<P>    //If the user wants to hold the thread, Sleep for given amount of time.+ S- S+ E6 l  C8 K7 |& P3 M
        if ( m_dwServerThreadWait &gt; 0 )
    ! s" B) R) c8 H# c3 f    {% o; G# {2 u3 S. j  p: u* J
            Sleep( m_dwServerThreadWait );
    - ^1 j2 k0 T- q) u0 l# l    }* _' @# y9 K, L+ ^+ v$ u
       
    # w6 W3 N9 t' Z  @) f* W& t" P' i    // Retrieve thread data for this process.* L( X4 L' l7 x. V  _- \" A6 i( @. }
        m_csThreadCountLock.Enter();</P>
    6 R$ o7 O. `" o/ ~  g  u; F  f<P>    m_wActiveThreadCount--;</P>7 f8 u1 x. M/ A; @
    <P>    FLOAT fDiffTime = (DXUtil_Timer( TIMER_GETAPPTIME ) - fStartTime) - m_fAvgThreadTime;2 L8 @6 f0 H5 Q9 _9 z
        m_fAvgThreadTime += fDiffTime/32;</P>7 J* H8 A" e7 L8 B
    <P>    //Get the Max time in the thread.) Z( k2 |2 j/ p) t
        if ( fDiffTime &gt; m_fMaxThreadTime )9 v" D( K) E: Y
        {2 F! G/ T3 I5 X
            m_fMaxThreadTime = fDiffTime;9 m! Y3 B) C# p5 ~2 k
        }</P>/ O2 d  ~4 ^) L6 e6 Q
    <P>    m_csThreadCountLock.Leave();</P>+ x( l) z: k$ t1 U% z
    <P>    return S_OK;
    , {6 C4 F9 w( R  O}</P>: r9 y7 `' m( n. a5 C+ F3 ]& @% k

    - j# _, \9 A* U/ Q<P>//-----------------------------------------------------------------------------
    " Y/ x! g! _; N8 Q) E- B, L! G. W// Name:
    , {0 X1 A9 e5 x  Z9 N2 g) V- W// Desc:
    5 W9 }' F. Z* d& B& A% m//-----------------------------------------------------------------------------
    - J% K" G2 V+ ?' O) Z8 B$ NBOOL CMazeServer::IsValidPackSize( DWORD dwSize )$ |: e( o, u' i3 G* z! g! N
    {% Y, ^, ^. n# M% E) E
        BOOL fFoundSize = FALSE;1 i/ j2 X4 l, s6 p6 z: n$ a4 M
        BYTE ubPackLocation = m_ClientNetConfig.ubClientPackIndex;
    . e' Z' Y; C5 g- Y- g& q2 ]   
    9 w& T7 q/ }+ l    // Check through the array of valid pack sizes., q; b) ^6 A  ^" w: C0 v
        if(dwSize != m_ClientNetConfig.wClientPackSizeArray[ubPackLocation])2 o+ H; J9 A7 T5 D( e  ^$ s1 R
        {5 }( f2 r- P; n
            for( --ubPackLocation; ubPackLocation != m_ClientNetConfig.ubClientPackIndex; ubPackLocation--)
      S; P* S, C0 \1 e7 U! f. z        {8 z9 }7 |8 q- [8 T2 _
                if(dwSize == m_ClientNetConfig.wClientPackSizeArray[ubPackLocation])
    ! X( l0 ^2 e- C# N6 Z            {
    ( R) S* X* r) R- S% Z                // Found valid size in the array.2 k; }4 h/ M( b& a
                    fFoundSize = TRUE;
    ' j: o. b- `: l4 I; j                break;0 m5 u/ W0 z# f/ u# `+ R
                }6 E8 w6 f/ _; Q" p: f8 A1 N
                if(ubPackLocation &gt;= PACK_ARRAY_SIZE)  ubPackLocation = PACK_ARRAY_SIZE;  //Wrap the array.& c  k; P3 _, S
            }
    % F- f+ u6 f& ?  A( z) A' g    }( ^" |$ b0 @' U& {1 E( x
        else! j8 A  ]2 @0 `4 |: m1 a9 T
        {
      h' E5 E) }  w4 Z$ z0 M& L        fFoundSize = TRUE;) L0 _# I5 f  R+ u5 C
        }</P>* I- @- c% c+ L/ w! l* j3 F, ]
    <P>    return fFoundSize;
    / X9 y- J6 c' s/ z, o# O}</P>
    ( O' R" @4 F& r8 G; g<P>* J* x6 }' v  p* K
    //-----------------------------------------------------------------------------
    $ s2 i- t& t- R. _// Name: - _' i2 e# H, a3 M2 n
    // Desc:
      L- S$ M3 y6 b. v, t//-----------------------------------------------------------------------------9 M0 v$ n/ q  c; a
    void CMazeServer::OnSessionLost( DWORD dwReason )
    7 A1 p' c! m9 L# A& i- Z{
    % I. G" U3 K9 r8 }5 Q  C6 R* G    ConsolePrintf( SLINE_LOG, TEXT("ERROR! Session was lost") );
    9 x) |" O0 e5 M; f7 c* \}</P>6 T. C3 |' j' l  l2 C$ b
    3 L- T$ K: Y: C" X' Y# o+ o
    <P>1 u. B7 C$ Q2 ^" m
    //-----------------------------------------------------------------------------
    5 `& L" w- t# ]6 c3 _, n& \" b( i// Name: 5 j/ S4 m6 \3 h  X6 t
    // Desc: + }! H3 m# K2 A/ h0 J( R9 h
    //-----------------------------------------------------------------------------; D5 z* \# I+ J
    PlayerData* CMazeServer::CreatePlayerData()  B9 F9 }4 p( K6 Z- @
    {
    % n) n: V# s5 @2 r' y" W    m_PlayerDataListLock.Enter();</P>
    * i- k3 V/ p# m- _* H<P>    // Grab first free player in the list  H& ~, K8 X; E2 z
        PlayerData* pPlayerData = m_pFirstFreePlayerData;</P>
    + @) E* R" I/ I2 a<P>    if( pPlayerData )
    ! e! V3 z( \% A4 z* q    {
    ( k7 h. G7 \! z        LockPlayerData( pPlayerData );</P>
    " h) r8 V2 e  l  |% k# H# J<P>        // Got one, so remove it from the free list# R  K9 A) b7 V9 L
            if( pPlayerData-&gt;pPrevious ), q5 ~5 M; H* i4 x' k* o* Y
                pPlayerData-&gt;pPrevious-&gt;pNext = pPlayerData-&gt;pNext;
    + `+ S1 Z# F7 q( B" A5 z8 O        if( pPlayerData-&gt;pNext )
    # x5 Y% o- D/ \/ B$ _            pPlayerData-&gt;pNext-&gt;pPrevious = pPlayerData-&gt;pPrevious;
    % k  a( ^# J0 T# E2 t' |) K" q        m_pFirstFreePlayerData = pPlayerData-&gt;pNext;</P>
    - N' ]; T1 i- H1 d1 r& [4 Z, h: Q<P>        // Add it to the active list! J& L2 H, T1 L7 o1 O
            if( m_pFirstActivePlayerData )
    : H0 x  V( v  }- F6 m) F) M            m_pFirstActivePlayerData-&gt;pPrevious = pPlayerData;3 A% W' J+ i- n9 i
            pPlayerData-&gt;pNext = m_pFirstActivePlayerData;* \* l* C' L6 N3 R3 R& \
            pPlayerData-&gt;pPrevious = NULL;3 b- n$ Y& n, E" v7 F5 n
            m_pFirstActivePlayerData = pPlayerData;</P>2 |- _1 E6 @- ~, D( d
    <P>        // Update count of players
    4 \% R# x3 U2 X' R5 n. P- M2 @        m_dwActivePlayerDataCount++;</P>. Z. z; S& B( t; e: a- x+ l
    <P>        // Generate the ID for this player$ [/ L9 Z+ j+ B
            m_dwPlayerDataUniqueValue++;
    9 T+ `$ P& G: m+ V* B! H        pPlayerData-&gt;dwID = (DWORD) ((pPlayerData-m_PlayerDatas)|(m_dwPlayerDataUniqueValue&lt;&lt;PLAYER_OBJECT_SLOT_BITS));</P>
      U7 \7 X0 x1 W" H# G! ]7 {: {8 N<P>        pPlayerData-&gt;pNextInIDHashBucket = NULL;
    ( ~- o, G' M6 R1 V% r        pPlayerData-&gt;NetID = 0;* b. e3 G9 @1 Z5 b6 \7 v$ ?
            pPlayerData-&gt;dwNumNearbyPlayers = 0;</P>0 ?+ X  p/ u' o2 H* W
    <P>        // Insert into the "off-map" cell
    $ k2 f! _: Y) H        pPlayerData-&gt;fPosX = pPlayerData-&gt;fPosY = -1;
    6 X) _6 H) g3 i# x        pPlayerData-&gt;wCellX = pPlayerData-&gt;wCellY = 0xffff;, ~" \9 f( |" W- d0 p* d2 ]
            m_OffMapLock.Enter();$ X( Q; H) e, Z4 P; A0 a
            pPlayerData-&gt;pNextInCell = m_OffMapCell.pFirstPlayerData;+ H; t- F4 \- a7 F& O: {( |9 I
            m_OffMapCell.pFirstPlayerData = pPlayerData;
    $ H" D. @1 y8 Y/ L& k        m_OffMapLock.Leave();</P>
    ( }2 Z! C0 \& a( N<P>        // Mark as active5 a7 R5 c' H2 l
            pPlayerData-&gt;bActive = TRUE;</P>
    5 o  l0 }" m% t; z! Q( @& i  I7 s<P>        UnlockPlayerData( pPlayerData );0 @! }$ s9 I7 e9 i) @" K& h
        }</P>
    0 p% B/ v- F3 E% d# _( {0 w' V<P>    m_PlayerDataListLock.Leave();</P>
    - H; [+ u. [' x( M" z<P>    return pPlayerData;
    7 r0 V/ H. v2 q# ]& f' R+ A}</P>0 e: d# c! l6 V; Y# r* I+ @" [2 V% t
    - D7 f. X! x3 F: H( B- j. P
    <P>$ Z* p! l! J: h  j
    //-----------------------------------------------------------------------------
    0 N2 L$ r+ n8 y, l6 U$ C3 w3 e// Name:
    . m9 k, T, P* B6 w0 |// Desc:
    3 {. I3 B* V7 R* l//-----------------------------------------------------------------------------1 A. b' \! J( Q8 w6 E
    void CMazeServer:estroyPlayerData( PlayerData* pPlayerData )+ X  s3 v2 P4 @# e5 [
    {
    - c7 D; ?+ F7 M) e% X! u2 Z0 s    m_PlayerDataListLock.Enter();( X! F7 G8 z9 G
        LockPlayerData( pPlayerData );</P>+ j! V5 I; o* t( S1 b! Q
    <P>    // Remove the player from its cell
    7 }. L$ G# s) }$ e; q9 g, W6 A    RemovePlayerDataFromCell( pPlayerData );</P>* K9 U6 f6 `. R3 I& P
    <P>    // Mark as inactive
    3 J( E) }, F; I; j    pPlayerData-&gt;bActive = FALSE;</P>7 _# x' W* ?/ e) U" B0 S
    <P>    // Remove player from active list. ?  Y: I1 Y0 G' C9 g) o; H
        if( pPlayerData-&gt;pPrevious )' z! ]+ N. q! I4 m
            pPlayerData-&gt;pPrevious-&gt;pNext = pPlayerData-&gt;pNext;
    1 Q( Y2 o8 j0 ]) N8 f3 H    if( pPlayerData-&gt;pNext )0 `- m- \  j- D. E& h" e, k
            pPlayerData-&gt;pNext-&gt;pPrevious = pPlayerData-&gt;pPrevious;</P>+ Q! C, b8 P5 p+ E1 s6 e* @
    <P>    if( m_pFirstActivePlayerData == pPlayerData )
    3 u2 N4 x& g! s) j* t/ p: z; H        m_pFirstActivePlayerData = pPlayerData-&gt;pNext;</P>; z2 Q) D) ]  S) G/ Y; Q
    <P>    // Add it to the free list6 L2 j. }( m: R" y, _
        if( m_pFirstFreePlayerData )
    7 B3 e# V" N  E/ \" ], G7 Z' L        m_pFirstFreePlayerData-&gt;pPrevious = pPlayerData;
    8 Q; b5 K; M/ ], o; x- @    pPlayerData-&gt;pNext = m_pFirstFreePlayerData;3 A8 U7 L5 _2 s, ?+ t
        pPlayerData-&gt;pPrevious = NULL;( x* [, c- B$ @! F
        m_pFirstFreePlayerData = pPlayerData;</P>
    9 _1 u" h& X" H; v& q% u<P>    // Update count of players  T! x" g1 v+ w; w5 U2 ~
        m_dwActivePlayerDataCount--;</P>" [7 Y5 t9 A. g# u$ _, `
    <P>    UnlockPlayerData( pPlayerData );
    , {( w, N0 @9 A7 s1 `0 S$ u2 t6 s8 }    m_PlayerDataListLock.Leave();1 z6 p! ^( Y) ^/ ?1 _7 u
    }</P>" B1 o2 J3 H' W! v; L, p8 E% E$ S( j

    % H' D; t, D4 p6 K/ I2 w<P>, n# Q6 g! r( N2 L6 W4 `3 r
    //-----------------------------------------------------------------------------  C6 P5 Y5 K! F. y- h, _! @
    // Name:
    ; z9 p5 F* j9 @1 y9 ~// Desc: - ]  \% }4 z# M  n- |$ L' g9 E6 z
    //-----------------------------------------------------------------------------" a* y- R% m- b  d! t
    void CMazeServer::RemovePlayerDataFromCell( PlayerData* pPlayerData )' R5 v- y$ }* F0 R0 s& d: t. I
    {6 ?1 C/ y0 O: H# C2 m" _
        // Lock the player6 l7 _+ u5 v, a" e  W
        LockPlayerData( pPlayerData );</P>
    , g7 f' J$ S( w; o- u% c& u; S  d5 s<P>    // Lock the cell the player is in
    ( t! n) l1 [3 ^* B% t    ServerCell* pCell;7 m$ |( {8 M* \- ?- k4 S
        if( pPlayerData-&gt;wCellX == 0xffff )
    8 y; V' s( i& Q$ o) m" X    {
    ) [! Y2 W8 y+ [0 }7 c0 H7 @        m_OffMapLock.Enter();. Z* X; _8 n7 \3 X/ \$ l  B
            pCell = &amp;m_OffMapCell;8 \% R& j7 h6 n' }+ V
        }
    ! |& A$ T1 `  O) j( l2 B    else
    / g! O$ ^. [' l( @    {1 R6 K% C. k  M8 D) V* ]' z
            LockCell( pPlayerData-&gt;wCellX, pPlayerData-&gt;wCellY );4 @# l6 A! g7 Y6 J
            pCell = &amp;m_Cells[pPlayerData-&gt;wCellY][pPlayerData-&gt;wCellX];$ t6 v- ?8 i% `1 x( I+ ~
        }</P>2 ~5 o7 u* m/ p3 d; H
    <P>    // Remove it from the cell
    8 |7 h, j' V% Z* t' I. d3 L/ ~# b  _    PlayerData* pPt = pCell-&gt;pFirstPlayerData;
    - K; H' Q; N4 a9 I" b    PlayerData* pPrev = NULL;
    ( Y& X( M. P/ J% ~    while ( pPt ): N* a9 }; n$ ?/ o& }6 {+ A
        {
    ) |5 B, s1 Z9 R+ a" d* c7 a        if( pPt == pPlayerData )
    " ?& O% n* G" G: |* `4 G        {9 \* Y! i2 \1 K7 ]0 Q
                if( pPrev )
    - O' G$ G/ u- ]8 t. Q8 t                pPrev-&gt;pNextInCell = pPlayerData-&gt;pNextInCell;
    ; V( ^7 }$ `; o7 q+ U% u. d: v            else
    2 w2 E3 G6 j- k5 A. I+ A                pCell-&gt;pFirstPlayerData = pPlayerData-&gt;pNextInCell;</P>
    # k# k/ n/ }, Q  n; g/ ?<P>            pPlayerData-&gt;pNextInCell = NULL;; ?: J, j, K  f3 m6 k
                break;0 P0 e8 t2 n" ?+ s$ {& w
            }9 x7 I: }% a( q0 H
            pPrev = pPt;
    1 H9 e4 j$ N; k: j8 r+ I; y        pPt = pPt-&gt;pNextInCell;
    % s/ }( O& {8 r; j% Y. k3 l    }</P>
    + r8 d, S* ]. i! ^% |6 N6 `; ~<P>    // Unlock the cell
    ; K3 I/ F8 {, Y" p7 }5 i' A" p% x    if( pPlayerData-&gt;wCellX == 0xffff )
    . C) v  `' W' S# ~7 w        m_OffMapLock.Leave();) L2 j9 \8 [: P: O+ S; C
        else% s, y% }, J' r1 i9 v
            UnlockCell( pPlayerData-&gt;wCellX, pPlayerData-&gt;wCellY );</P>
    ' c, X3 X1 G0 ]+ a. b<P>    // Unlock the player& H2 c' ]5 r- Y/ S$ `4 ?% [0 b6 E
        UnlockPlayerData( pPlayerData );
    # n: J. e- }6 F: U5 R# r}</P>
    " Y8 `1 a3 p8 r5 d) n, A# W, k4 Z( O) u( p- n! v
    <P>3 r+ k; A" K4 @5 g* N
    //-----------------------------------------------------------------------------; U( }0 w' W# N6 s" h
    // Name: 8 r6 s. R  R8 t: s/ |* y
    // Desc:
    % y1 o6 Z0 Y; V0 l6 c: ]. n' B//-----------------------------------------------------------------------------, s  d& o' L* S
    void CMazeServer::UnsafeRemovePlayerDataFromCell( PlayerData* pPlayerData )
    + l) k# ]! `* }. t' F' u{
    ) x: {5 m  \/ s: D+ G0 m4 v9 f    ServerCell* pCell = GetCell( pPlayerData );' _) I( o! j2 P" j) }
        PlayerData* pPt  = pCell-&gt;pFirstPlayerData;1 j7 _2 Q' z  g. z- l* Y
        PlayerData* pPrev = NULL;
    7 r, {5 h" _7 y    while ( pPt )
    7 x% k7 o! W2 y6 K' Y& H5 D    {
    * }3 K( l- O. c% h9 ^' S' U% \        if( pPt == pPlayerData )8 ~- c, V; C" ?
            {
    ! m& j! j' h* k7 W; H9 k8 i            if( pPrev )& x4 b/ i. [' ?% g: M
                    pPrev-&gt;pNextInCell = pPlayerData-&gt;pNextInCell;
    . ^0 k3 \& |; a( ?            else
    9 a7 j" ?1 Y& P& U* m                pCell-&gt;pFirstPlayerData = pPlayerData-&gt;pNextInCell;- b: C. Q6 G4 p: `3 v* c' g
                pPlayerData-&gt;pNextInCell = NULL;# s0 `+ d9 X( t$ [3 e5 o
                break;" v" b& D6 q0 D' F9 h- ~% u8 d( c0 i) p
            }
    & w: V9 ]# P. e8 y* i9 Y        pPrev = pPt;
    1 j) _: g7 \& r& K  J5 c  z        pPt = pPt-&gt;pNextInCell;/ r) x$ m, R' H+ x2 J
        }
      u, ^9 ?4 k. I$ t}</P>
    6 K- {+ Y, g+ A' L3 K! n
    5 G9 C! x) r. {# W1 R1 R# M8 {<P>' c8 M5 o! k! i* ^5 L- n
    //-----------------------------------------------------------------------------" @$ b, @5 y$ s/ I  s% y  C0 G
    // Name: 2 _& x  b+ W3 \0 p0 @4 M7 x4 b
    // Desc: . n( o6 H/ w( a2 D! P9 H7 D* r' }
    //-----------------------------------------------------------------------------' n$ _! O6 w. [% N8 x
    void CMazeServer::UnsafeAddPlayerDataToCell( PlayerData* pPlayerData )& z# e& o' \* R5 U
    {
    0 N# w8 g' s8 S9 d7 c6 a    ServerCell* pCell   = GetCell( pPlayerData );  H) \; G' Z4 A1 J6 `6 d
        pPlayerData-&gt;pNextInCell = pCell-&gt;pFirstPlayerData;& o* e# L2 t+ ~9 S* \0 u; N! Q
        pCell-&gt;pFirstPlayerData = pPlayerData;
    * E& d' V$ @( w}</P>
      J% v' ]- S2 s1 q2 T. @: B9 \$ d* i  n, K
    <P>
    : E% B' m. S) e/ U1 ^1 m& a//-----------------------------------------------------------------------------
    5 I; k0 |) n9 ^/ g// Name: ' G- y2 C  E6 d2 K2 j5 e9 B( `
    // Desc:
    6 j+ l! I9 r; J: n//-----------------------------------------------------------------------------  g: L0 H" s$ b5 {
    void CMazeServer::HandleClientPosPacket( DWORD dwFrom, ClientPosPacket* pClientPosPack ); Y* B6 P  G2 V) T! m+ a% h
    {' V9 w! ?, L# W% @- @: O' g! y  _
        // Grab player for this client and lock it' k$ |1 [+ j, I% x4 |
        PlayerData* pFromPlayer = GetPlayerDataForID( dwFrom );4 L2 X7 C) ?- _4 W3 ^' l- l
        if( pFromPlayer == NULL )/ }, v; y$ Z4 }- N; ^; z
        {
    2 Z% }9 ]& U. B* _' }        if( m_dwLogLevel &gt; 1 )' C9 ^+ \; f- ]4 G+ N1 ~
                ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Could not find data structure for this player"), pFromPlayer-&gt;NetID );  u3 K9 j, ^9 @8 X. C* l* c
            return;
    & s* L' A  i8 }( u$ O: C    }</P>7 @" a! x# g* ^+ E0 M2 H
    <P>    LockPlayerData( pFromPlayer );</P>0 P- N7 p. O8 F% }& z! Y: M
    <P>    if( FALSE == pFromPlayer-&gt;bAllow )
    6 ~5 i- w2 R  Y# L+ S    {
    & ~9 ^2 s9 O$ N) P" r: b% g" S+ \        if( m_dwLogLevel &gt; 0 )& ^( s( c% b2 ]) R% g( a
                ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Got position packet from bad client.  Rejecting client"), pFromPlayer-&gt;NetID );</P>
    + c" n& M' _( ~+ q& J<P>        m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );
    & ~1 e' D7 l9 S2 @4 l1 d        UnlockPlayerData( pFromPlayer );
    # n8 j: Y$ t5 k- D: a* U% }9 c        return;3 Q! d5 m: ?' r6 Z5 ~( N
        }</P>2 x: m; O2 W0 M3 e  L) \
    <P>    // Compute the cell the player should be in now: L# ?) q! e" i% c0 v; M: f
        DWORD newcellx = int(pClientPosPack-&gt;fX);
    + f0 Q" L( B2 n: S  M, G    DWORD newcelly = int(pClientPosPack-&gt;fY);' W: v  T8 i+ @' d" r' a. O' a! r
        DWORD oldcellx = pFromPlayer-&gt;wCellX;$ c7 ]: w5 R$ ^7 I% ^
        DWORD oldcelly = pFromPlayer-&gt;wCellY;</P>. Q2 R7 e3 l+ G
    <P>    // Have we moved cell?
    " T' e9 o# Q- B; g+ w3 d! J; B    if( newcellx != oldcellx || newcelly != oldcelly )
    $ Y  e& c' s: Y9 @4 R$ c2 _    {
    ; R3 A/ @: ?( u. G7 b        // Yes, so lock the pair of cells in question' t2 A; U- R- l& ], H
            LockCellPair( oldcellx, oldcelly, newcellx, newcelly );</P>
    & z; d2 J* I, w- }0 x<P>        // Remove from old cell and add to new cell
    6 k' @! F) g3 W+ j* O2 E, @4 P7 a; @        UnsafeRemovePlayerDataFromCell( pFromPlayer );; U  T% J8 Y+ t4 Y# ?2 }7 g
            pFromPlayer-&gt;wCellX = WORD(newcellx); pFromPlayer-&gt;wCellY = WORD(newcelly);
    ; l; F) ~$ d; i; v7 Y, g        UnsafeAddPlayerDataToCell( pFromPlayer );</P>
    . a* j+ e9 k2 u- T/ C+ C) q<P>        // Unlock cells# |: v2 q4 n+ E( Q
            UnlockCellPair( oldcellx, oldcelly, newcellx, newcelly );; O! N# `- U; f( e$ j% B
        }</P>
    ( E% S0 ^6 U8 n& s6 K& w" m<P>    // Update player position
    5 T, ^! O8 ~$ N4 P5 i3 L    pFromPlayer-&gt;fPosX      = pClientPosPack-&gt;fX;
    $ S7 c' w6 k; I8 \    pFromPlayer-&gt;fPosY      = pClientPosPack-&gt;fY;
    2 q5 F: X% K  t3 B    pFromPlayer-&gt;aCameraYaw = pClientPosPack-&gt;aCameraYaw;</P>' h! R( x! d- @3 r0 A5 W) ]6 p8 w
    <P>    // Allocate space to build the reply packet, and fill in header
    , V! r& O; ]( L7 T6 b+ l  B  Q8 r    DWORD dwAllocSize;/ S6 s# k# \+ |" }
        ServerAckPacket* pSvrAckPack = NULL;</P>5 U1 `' o" }0 n: q/ {( K
    <P>    // Begin by allocating a buffer sized according to4 X2 d" A5 V* n
        // the current number of nearby players + 4.  This will give 7 B8 a+ H' R3 l+ X
        // a little room for more players to come 'near' without resize
    & C) u# h% ]; }% h% u    // the buffer.- _) G6 V0 f! i$ \2 k
        DWORD dwMaxPlayerStatePackets = pFromPlayer-&gt;dwNumNearbyPlayers + 4;</P>
    # h/ m  `0 D& ?6 v<P>    dwAllocSize = sizeof(ServerAckPacket) + dwMaxPlayerStatePackets*sizeof(PlayerStatePacket);5 C2 ~& @) A: c7 @
        pSvrAckPack = (ServerAckPacket*) realloc( pSvrAckPack, dwAllocSize );" h9 B! a! I& @" T' S2 i
        if( NULL == pSvrAckPack )
    * M% j' _! n: b) i7 ]5 z, r    {* S- F2 ~+ Q7 [0 q" A7 m$ }
            // Out of mem.  Cleanup and return  o' @9 v. [0 k5 X$ e
            UnlockPlayerData( pFromPlayer );  ^* b- S) }( m
            return;      
    2 a1 r' f3 t6 L: U. }, |( Z    }6 n7 U+ D% ~) c4 w# _- e
        ZeroMemory( pSvrAckPack, dwAllocSize );</P>
    * P; L4 T6 q$ L+ M. @. @* N<P>    *pSvrAckPack = ServerAckPacket(m_dwPlayerCount);3 t6 J: m* c" p0 c1 U0 B3 m$ K: A
        pSvrAckPack-&gt;wPlayerStatePacketCount = 0;
    ; n. a( E. N( M2 k4 K) x; x    PlayerStatePacket* pChunk = (PlayerStatePacket*)(pSvrAckPack+1);</P>& m1 |& g1 f8 [* v. g
    <P>    // Compute range of cells we're going to scan for players to send  z! ~5 q4 O1 B
        DWORD minx = (newcellx &gt; 7) ? (newcellx - 7) : 0;
    " v$ w% }8 s2 n  \    DWORD miny = (newcelly &gt; 7) ? (newcelly - 7) : 0;
    6 B# `1 \& r8 W5 o- r    DWORD maxx = (newcellx+7 &gt;= m_dwWidth) ? m_dwWidth-1 : newcellx+7;+ p" O$ E9 J( `1 q8 S
        DWORD maxy = (newcelly+7 &gt;= m_dwHeight) ? m_dwHeight-1 : newcelly+7;</P>, O# W2 f1 y; k* S, N  y1 r# q2 p
    <P>    // Lock that range of cells
    : S7 v) T+ X1 L$ n    LockRange( minx, miny, maxx, maxy );</P>* A+ @, ~& d9 K1 n- y
    <P>    // Scan through the cells, tagging player data onto the end of: U9 H" y$ n/ N2 j. i8 e* Y8 \- J
        // our pSvrAckPacket until we run out of room) S) ^6 A- H3 P- l
        for( DWORD y = miny; y &lt;= maxy; y++ )
    + y% }3 d6 F  N    {$ u# j0 w7 ]* H/ _! H4 J3 R
            for( DWORD x = minx; x &lt;= maxx; x++ )) l2 r3 p2 T5 n9 g* j1 h3 g
            {' b: D$ p! K$ q' `6 Y
                PlayerData* pCurPlayerData = m_Cells[y][x].pFirstPlayerData;' l# i0 p# O( e1 _1 x* j
                while ( pCurPlayerData )$ o1 w4 y$ j0 `
                {7 J& t7 ]. T% s: l6 d% a' B! R
                    if( pCurPlayerData != pFromPlayer )0 K" {9 v- }$ _+ }) h& X+ ?5 D) J
                    {
    " {# k' N6 `: a  D+ ?5 k  d                    if( pSvrAckPack-&gt;wPlayerStatePacketCount &gt;= dwMaxPlayerStatePackets ). K3 e- A* S- T- _, A
                        {
    2 V! p/ {& @9 A, L1 H" q2 b3 Y                        // Make sure pChunk is where we think it is
    ' F2 ^6 C, T% ?% E8 J8 Y3 X  w                        assert( (BYTE*) pChunk == (BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket)) );</P>
    % [0 V' Q. S2 w9 ^8 _; ~<P>                        // There are more than just 4 new nearby players, so resize the
    ! R8 E* H/ [. D3 ?" d' @                        // buffer pSvrAckPack to allow 16 more PlayerStatePacket's.. A' K4 v: H- F, a% z( d7 Q
                            dwMaxPlayerStatePackets += 16;
    5 |5 J2 N# V" K( K' M9 z3 i+ T                        dwAllocSize = sizeof(ServerAckPacket) + dwMaxPlayerStatePackets*sizeof(PlayerStatePacket);
    3 z* b+ [  f+ M( D, q7 g( l6 L                        ServerAckPacket* pNewSvrAckPack = NULL;1 M( p" }: S; d  ~% u
                            pNewSvrAckPack = (ServerAckPacket*) realloc( pSvrAckPack, dwAllocSize );# x. n9 R7 X4 Y5 a6 B) }
                            if( NULL == pNewSvrAckPack )4 {4 Q# \* L; a
                            {
    6 \" i" H, z: W3 Z! \                            // Out of mem.  Cleanup and return% V! U3 l( G7 ~" g9 x+ J! V
                                free( pSvrAckPack );
    " q" U% U5 V; b% p* `                            UnlockRange( minx, miny, maxx, maxy );
    2 l: A7 W' F/ d                            UnlockPlayerData( pFromPlayer );
    " H' v- M4 d' a) P" r                            return;      
    3 T3 R! H7 Q- j) W                        }</P>
    # r8 e+ A- c$ O" P# a. F<P>                        pSvrAckPack = pNewSvrAckPack;
    2 t# q5 W) W" \+ y; E                        pChunk = (PlayerStatePacket*) ((BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket) ) );</P>' m( _1 O& U) j5 _7 O
    <P>                        // Make sure pChunk is still where its supposed to be3 Q4 J- ^$ W0 l$ a
                            assert( (BYTE*) pChunk == (BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket)) );1 n* A& m$ Q* R. ^7 x% w- ]4 v
                        }</P>
    : ^- f$ `7 Z  t9 c3 P% u<P>                    pChunk-&gt;dwID       = pCurPlayerData-&gt;dwID;+ H% s* P: w& t* P% F, a4 ~4 G( C
                        pChunk-&gt;fX         = pCurPlayerData-&gt;fPosX;. }7 n& q8 n, F% T/ a
                        pChunk-&gt;fY         = pCurPlayerData-&gt;fPosY;
    + q# w  q# e1 X- o                    pChunk-&gt;aCameraYaw = pCurPlayerData-&gt;aCameraYaw;# i* W* l7 u: s9 I8 x
                        pChunk++;! g( C# S. z# `
                        pSvrAckPack-&gt;wPlayerStatePacketCount++;
    ' y) N9 s8 G3 D1 Q) y7 v                }0 J' k- I4 T" `, p3 F+ x; |! j
                    pCurPlayerData = pCurPlayerData-&gt;pNextInCell;$ J5 i! l+ g- C  @) B' r8 J1 O
                }2 ?$ |1 t  U" ]( H  q" M
            }+ B* U) Q3 h9 M& r
        }</P>
    " U+ a  }9 ^8 f9 t. }<P>    // Update the dwNumNearbyPlayers for this player
    ) V  Y. y; A7 J. g" @. A7 _) i, c9 g) p    pFromPlayer-&gt;dwNumNearbyPlayers = pSvrAckPack-&gt;wPlayerStatePacketCount;</P>
    6 @) r1 W" b3 D! k) u' z* R<P>    // Unlock range of cells
    ( }  R9 ?+ H- }) r! f5 P! R    UnlockRange( minx, miny, maxx, maxy );</P>& J1 L: ]/ w/ @" p
    <P>    if( m_dwLogLevel &gt; 2 )3 p' y, t9 n2 R" n" [3 S" n
        {
    * I1 ?, W) e- W6 I        ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Position is (%0.2f,%0.2f)"), pFromPlayer-&gt;NetID, pFromPlayer-&gt;fPosX, pFromPlayer-&gt;fPosY );/ s9 o# ^! r: O/ y" r
        }
    , @2 A% j5 X6 v! c9 u    else if( m_dwLogLevel == 2 ), [. C* i+ ?2 G% K7 o
        {6 M5 r  H: @- S$ n
            FLOAT fTime = DXUtil_Timer( TIMER_GETAPPTIME );
    ( f( F+ m6 Y: o" U( h, c        if( fTime - pFromPlayer-&gt;fLastDisplayTime &gt; 60.0f )# R3 p9 v, ?& [6 o; \. C& ~: L" ^
            {8 \0 \. U2 g; q+ E, p# z" y- c, p
                ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Position is (%0.2f,%0.2f)"), pFromPlayer-&gt;NetID, pFromPlayer-&gt;fPosX, pFromPlayer-&gt;fPosY );0 p1 r9 r! _2 s' E' A6 }
                pFromPlayer-&gt;fLastDisplayTime = fTime;$ {& Y7 Z, X8 U: x; o5 K0 q
            }  m, j+ ?& K. }7 Y: E$ G
        }</P>
    " N8 z9 h  O( S" j' B4 m9 a<P>    // Unlock the playerdata% s) i1 Y9 K# X' e# k& v, q
        UnlockPlayerData( pFromPlayer );</P>
    . Y7 C+ M" U/ I! N2 q+ J<P>    // Send acknowledgement back to client, including list of nearby players & k5 u" x" L; E  e
        DWORD acksize = sizeof(ServerAckPacket) + (pSvrAckPack-&gt;wPlayerStatePacketCount * sizeof(PlayerStatePacket));; ^, A; w/ J) u
    ! Q# H8 j' _' F: e+ T% n) v
        // Pack the buffer with dummy data.
    & b/ ~* V+ a) r3 U    if(m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex] &gt; 0)
    5 d6 O( `4 |5 K  s1 p; H    {
    6 u  @8 c3 m7 Z' T% I2 e        DWORD   dwBufferSize = acksize + m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex];+ v9 P( O' Z6 n/ d* c, T+ o8 e, C
            VOID*   pTempBuffer = 0;</P>
    7 l% N& G9 z" V! ?<P>        pTempBuffer = malloc(dwBufferSize);' V# B7 j- {; r; u
            if( NULL == pTempBuffer )
    ' H2 Y. Z! b( V1 k8 M1 f# l# i* U        {
    1 Q, W8 z# }+ T            //Out of memory0 }1 z9 e8 P4 O' |2 q
                DXTRACE_ERR_NOMSGBOX( TEXT("System out of Memory!"), E_OUTOFMEMORY );
    ' N6 V% C3 o" t$ E            free( pSvrAckPack );: S. k0 [7 u) U& W. F
                return;
    " I' N% h3 |0 ?6 v0 O! L        }</P>
    2 |# R, ?% v- _4 j9 J7 c<P>        FillMemory(pTempBuffer, dwBufferSize, 'Z');
    1 C  r7 a0 r$ s1 ?3 b        memcpy(pTempBuffer, pSvrAckPack, acksize);</P>& N* ?. a; X8 P, t0 }& n
    <P>        SendPacket( dwFrom, pTempBuffer, dwBufferSize, FALSE, m_dwServerTimeout );
    ( \) R! i1 }! [0 O3 y   
    0 Z; d* ?+ o; n; @3 H        free(pTempBuffer);
    , f: K2 k9 h+ R1 w    }   
      \( @$ a+ X  ^    else
    ) h. y6 |& S2 E) h5 W    {9 ~' W: x* n1 e- n7 B
            SendPacket( dwFrom, pSvrAckPack, acksize, FALSE, m_dwServerTimeout );
      [# s' N( L( D- I, e    }</P>
    ; h& G) J. i: o3 Q<P>    free( pSvrAckPack );</P>7 k# ?0 X$ X3 F
    <P>}</P>3 k0 h3 ^8 ]0 L, P3 A5 T% N$ c7 {* f

    9 F% X1 U) V. @+ X. K# G; c" p/ z<P>0 l/ U" g, y. B1 q, L0 s* q6 U
    //-----------------------------------------------------------------------------" k- P# F" l4 q+ K; W% I8 m% O* `5 p8 v
    // Name: , _. s- C5 Z2 {* }" b/ {2 t/ v
    // Desc:   Y; G! b' F6 `  X( k! \
    //-----------------------------------------------------------------------------
    + t9 J8 ~; C" jvoid CMazeServer::HandleClientVersionPacket( DWORD dwFrom, ClientVersionPacket* pClientVersionPack )0 `8 U1 I" P# l: @0 s) t
    {4 K9 e/ m" y+ B0 N3 s5 i
        // Grab playerdata for this client and lock it
    - [0 l" v, ^  T( |- I* s0 J1 E    PlayerData* pPlayerData = GetPlayerDataForID( dwFrom );
    + M. o/ v' F6 Y    if( pPlayerData == NULL )
    : F6 L7 w7 H& P  a1 V        return;
    : K; K6 D6 [0 c- P1 Y9 S1 j& X4 R5 t1 k, X    LockPlayerData( pPlayerData );</P>2 J# B$ c' L# x: l
    <P>    // Record the version number 3 Q$ \1 _. R& a# n; w, Z
        pPlayerData-&gt;dwVersion = pClientVersionPack-&gt;dwVersion;</P>1 X) r6 K& E' z- `& ]) I- O
    <P>    if( m_bLocalLoopback )2 m5 s4 G8 a$ a3 k
            pPlayerData-&gt;bAllow = TRUE;6 ~6 H7 }) I$ g9 f1 V. M5 P7 L8 _
        else
    ) J! t7 E6 o0 M) i( g, f        pPlayerData-&gt;bAllow = IsClientVersionSupported( pClientVersionPack-&gt;dwVersion );</P>
    5 B# V- r7 f" r7 |" w( T<P>    if( m_dwLogLevel &gt; 0 )
    ) U1 X$ ~: v- x        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>. L9 c7 b4 `( m. }) ]$ g1 \* H
    <P>    if( FALSE == pPlayerData-&gt;bAllow )
    * S; b" ]% h7 X( P7 I; _    {
    0 C" _7 C7 ~) b& A: m7 N        if( m_dwLogLevel &gt; 0 )
    ! j; x( X- x9 Q6 o- ~% u            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Rejecting client"), pPlayerData-&gt;NetID );</P>) ^! f. J! l: S
    <P>        m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );; e0 H$ b, m( c- P; n2 ?! q  K
            UnlockPlayerData( pPlayerData );2 W/ Q# S& E. I
            return;
    + G- Z; h. v0 n! m3 i    }</P>: \# X: B3 h; T, @
    <P>    // Unlock the playerdata
    9 M; j5 n* Z1 p( x& W! U* K# T5 U    UnlockPlayerData( pPlayerData );</P>
    0 {, Z, c9 n/ i<P>    // Send acknowledgement to client that the client was either accepted or rejected1 U$ f2 r. y- v
        ServerAckVersionPacket packet( pPlayerData-&gt;bAllow, dwFrom );! l4 B! T- a! h7 J" a6 s
        SendPacket( dwFrom, &amp;packet, sizeof(packet), TRUE, 0 );: G$ s  h# K& }  N) l7 f, e
    }</P>6 ^. B, k0 ]% L" \

    ! R5 `! T3 [' r<P>
    2 O( ^1 P1 t  C: x5 K//-----------------------------------------------------------------------------
    . K1 s2 D; U, Z7 G# k// Name:
    ) k7 z) _2 I+ _( z6 T' S// Desc:
    / _0 z4 X& A& R9 h//-----------------------------------------------------------------------------) V$ f0 E  k: R3 a$ M
    BOOL CMazeServer::IsClientVersionSupported( DWORD dwClientVersion )
    : w: Y0 g* T- A8 ^% i{+ Y9 W/ q/ \0 d5 C( p7 j9 o) A
        switch( dwClientVersion )
      [( x' H; r: B# l$ F) ]* I    {/ ^3 ~, ]+ x( R( N
            case 107: // only v107 is supported
    + _  X' h- K. n4 c            return TRUE;6 p* W0 ?# N5 C; T5 {7 p/ S- \
            default:) v; F9 r' F! P. p& d
                return FALSE;9 v4 r" k0 z- w7 s7 e% a3 B, m
        }
    * j8 m# {6 k. a$ v5 X}</P>1 ~8 C0 U+ h& H: D& L
    ; \4 O, v/ \- o6 N
    <P>
      a7 x' K1 X  ~1 |; ]7 Q! B//-----------------------------------------------------------------------------
    / e7 r. Y$ |0 f* X6 _// Name: / K! D7 o9 X" _' J1 O" {: i7 P% X( \
    // Desc:
    9 S1 D6 O- |) E0 R2 B% H$ v0 ]* @1 `//-----------------------------------------------------------------------------
    & f- X+ }0 i$ `" _! Tvoid CMazeServer::HandleUnknownPacket( DWORD dwFrom, ClientPacket* pClientPack, DWORD size )
    6 C" G3 r5 i6 g& b  \$ h- m% C{
    # H3 q1 t. R3 X  J# }" C, ?    if( m_dwLogLevel &gt; 1 )
    7 K) |2 P' y( ~        ConsolePrintf( SLINE_LOG, TEXT("ERROR! Unknown %d byte packet from player %0.8x"), size, dwFrom );</P>$ H" x$ D$ ]( ]* N! k- h
    <P>    m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );
    8 @, t' C  H+ m0 ^  N6 K}</P>9 M0 D- k. A- x5 J. s
    / D: A- j6 P# P- M$ f
    <P>
    5 q# W3 P3 w/ M+ Z0 B, E//------------------------------------------------------------------------------ ?- G& k, Q, _! E) K+ m! h
    // Name:
    / j5 G- C2 P. v$ N6 G* e$ o% X// Desc:
    . S( m' B1 y9 ?; a//-----------------------------------------------------------------------------* X# O% F# g3 F( t7 U. d
    DWORD   CMazeServer::IDHash( DWORD id )
    5 C5 |7 c: j. I# V{' v2 G/ b/ W9 ~. b0 n  z
        DWORD   hash = ((id) + (id&gt;&gt;8) + (id&gt;&gt;16) + (id&gt;&gt;24)) &amp; (NUM_ID_HASH_BUCKETS-1);
    . y: Y" R! z) f+ o# S1 k7 i    return hash;
    . t0 c5 R! ~/ F}</P>, [3 }# h+ D1 j/ k3 a0 c2 Q5 r, K

    " F1 }) W+ r* ^4 L! L+ v: e<P>, ~5 r( n9 z# L
    //-----------------------------------------------------------------------------/ e8 E% |5 q5 p' i- i: N' p
    // Name: 2 c+ m$ |4 Q  x0 u' B' o
    // Desc: 8 B% v; b  L: y
    //-----------------------------------------------------------------------------1 N0 w" L  `7 T# b) r3 }6 ^
    void CMazeServer::RemovePlayerDataID( PlayerData* pPlayerData ), h' o: c# w3 Q5 h! I! j4 x
    {) g/ J2 W  k  u4 K- v
        // Hash the ID to a bucket number4 [' H1 Y4 A* u1 ^: Y6 y. B* V
        DWORD   bucket = IDHash( pPlayerData-&gt;NetID );</P>& ?+ R/ W7 p; t$ f) Q' ]+ e8 h
    <P>    // Lock that hash bucket2 ~+ @9 I0 e: g6 J9 B1 F9 D
        const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;
    % m9 m9 K+ u. x0 g    m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>
    * \8 L# ~/ l) m<P>    // Loop though players in bucket until we find the right one8 j0 g3 u3 ~& P+ Z/ ]
        PlayerData* pPt = m_pstIDHashBucket[bucket];
    % N8 T( j7 a. _$ \. q    PlayerData* pPrev = NULL;
    2 y# G3 ~' V9 W9 W* a: i* R    while( pPt )
    ; h' g4 Q  w& M8 L    {
    4 z+ ]5 V" o1 K1 L2 D4 l        if( pPt == pPlayerData )
    + n  [8 A6 _% P; ]8 F% b; [            break;
    $ i% B( s: Z$ F$ [& U7 H2 y! ?: V6 K3 R        pPrev = pPt;# }* s+ u! z$ B* ~! L8 z. O9 A2 @' }
            pPt = pPt-&gt;pNextInIDHashBucket;7 _' B+ g. P- q) o
        }</P>4 u+ q  a- p7 v
    <P>    if( pPt )
    3 F& P% \9 w; Q* Q    {
    * b2 W+ d) h4 ^) I7 v        if( pPrev )( q0 v9 J6 Y3 t- B" I8 @/ g( s
                pPrev-&gt;pNextInIDHashBucket = pPt-&gt;pNextInIDHashBucket;& a0 o3 m7 W1 c
            else+ p' S3 b3 m- P& B9 b$ |3 V
                m_pstIDHashBucket[bucket] = pPt-&gt;pNextInIDHashBucket;
    ! |$ M& ]- O* v$ X, p. W- v        pPt-&gt;pNextInIDHashBucket = NULL;- _$ Z1 }- J% U
        }</P>
    9 R8 @1 ^# F  Y3 ?: Z<P>    // Unlock the hash bucket
    7 ^+ `: W; X* B6 K    m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();* E0 N9 E+ \1 {9 x4 }
    }</P>
    0 Q( u* k& i+ `/ B" g
    ) u5 v0 t5 v: x. f<P>! o7 w" t, d( \# D; g( T) H
    //-----------------------------------------------------------------------------
    ' K/ d5 B9 j2 q! x$ k0 q! P// Name: 5 c- @* ?3 F& z' m2 @
    // Desc: 4 l  q0 ?1 |4 F2 g+ {
    //-----------------------------------------------------------------------------
    & j2 {2 G! K" a4 z/ ?. i) s5 D8 nvoid CMazeServer::SetPlayerDataForID( DWORD id, PlayerData* pPlayerData )
    5 Q+ x) |% ?. B* W) X- s" S$ _% @{  ^& F: r- n" q" J1 w$ A
        // Make sure this player isn't added twice to the m_pstIDHashBucket[]+ e9 J- S! Q  Y# |1 I0 q
        // otherwise there will be a circular reference* p/ s) G$ B" L( W- Q& ^
        PlayerData* pSearch = GetPlayerDataForID( id );$ e" D5 X  k2 `9 G6 N$ X
        if( pSearch != NULL )4 z3 I; W" y+ u5 l- N8 i/ V
            return;</P>
    5 f3 e% ]" O# Q<P>    // Hash the ID to a bucket number9 N( _1 Z' ?! S' u5 Z2 X7 c8 s/ s
        DWORD   bucket = IDHash( id );</P>" W6 A6 W1 a8 j
    <P>    // Lock that hash bucket+ N6 N. q' Z! @3 r) J) d
        const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;" g6 z( a: a- V; a& h7 \* ?
        m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>  K9 U2 t; ~0 j8 @( A) X) z
    <P>    // Add player onto hash bucket chain# u. b* W! |3 n- ^+ ^! i
        pPlayerData-&gt;pNextInIDHashBucket = m_pstIDHashBucket[bucket];" V9 H" q4 H: a( h  ^( v! l* }
        m_pstIDHashBucket[bucket] = pPlayerData;</P>0 }* a! e- F4 c# M+ Q5 R4 ^
    <P>    // Store net id in player
    3 {/ }( t4 P- Q* ^/ f    pPlayerData-&gt;NetID = id;</P>
    " q, Z- O5 y4 ~<P>    // Unlock the hash bucket2 t% ~2 r& o- A- H" A2 P( H
        m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();
    ; V# y4 F, S+ ^, u! U}</P>
    + K6 n) J& ]6 X8 l) e" ]3 a, r( L% R
    , {1 w- Y( [; w& K3 B<P>
    + ~3 V/ m$ _0 v: j* [/ A//-----------------------------------------------------------------------------% k. U+ T# C& R+ n; l* Y4 K! S6 ^
    // Name:
    1 K! {  T! o& H" w+ n) M// Desc:
    0 E6 R) [3 o& F$ v. [  E//-----------------------------------------------------------------------------1 a# R- L3 T1 [
    PlayerData* CMazeServer::GetPlayerDataForID( DWORD id )
    3 v0 f% y- {3 v& j{6 y2 K+ v! f4 f+ \& `* }
        // Hash the ID to a bucket number. S0 G! c$ u& v7 v
        DWORD   bucket = IDHash( id );</P>
    # c8 ]7 a1 d6 Q* ]* S# O<P>    // Lock that hash bucket7 y. F+ X, Z/ @9 {( W: ~( A  \' `
        const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;
    + u# W4 h+ q/ w; E; @! P    m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>* [+ I4 ~/ c" c0 N3 f
    <P>    // Loop though players in bucket until we find the right one8 q) {" Q7 h$ x, X
        PlayerData* pPlayerData = m_pstIDHashBucket[bucket];  [5 }9 |$ w- O3 \& i
        while ( pPlayerData )
    + o7 ?1 M- |# W* R0 D2 u! {    {
      ~- n: a8 r  ?8 W        if( pPlayerData-&gt;NetID == id )
    % G& e& U. v6 z1 c. V* P, F            break;
    * e7 _0 `6 e( N. `$ m        pPlayerData = pPlayerData-&gt;pNextInIDHashBucket;! C' e3 C. E% y2 v' ~; ^
        }</P>
    : D9 a  J* h0 x9 H, Q7 G$ Q6 p<P>    // Unlock the hash bucket) q1 K% N/ |# Y! h2 |3 V
        m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();</P>
    & b  E: B$ H  T<P>    // Return the player we found (will be NULL if we couldn't find it): y2 W& G( T# x/ z" F- R
        return pPlayerData;
    . T8 `+ a/ V1 B3 c: s$ V}</P>
    # P2 e, _, A* l$ L+ K$ @$ \' g
      i' n! `  D* G6 P4 S" @; {: P<P>
    $ s  G6 W- g# D) ^* ]//-----------------------------------------------------------------------------+ z3 q! P- J: k. A
    // Name:
    1 v$ ]. t6 O1 f& v1 B8 X// Desc: calls DisplayConnectionInfo for each connection in a round-robin manner
    ' M9 }3 A. i: h# m! u" o1 L//-----------------------------------------------------------------------------4 L2 t' @( \6 w  c7 K
    void CMazeServer:isplayNextConnectionInfo()) l: Y# c; I- ?9 @0 `0 u8 \5 w
    {
    1 Y/ Z; X. Z4 @: c' i7 a- R0 r    if( m_pNet ): \4 Z, }6 Y: i
        {1 Q% L" o3 U3 I" n& b! g! ^1 ^+ K
            // Find the player that was displayed the longest time ago, and display it.
    5 R9 T) C3 f) E5 a, B        FLOAT fCurTime = DXUtil_Timer( TIMER_GETAPPTIME );
    $ D# E0 J8 q: t) Y  \$ K# N; R        PlayerData* pOldestPlayerData = NULL;
    9 a* e0 J; h: a4 {        FLOAT fOldestTime = 0.0f;</P>  O& F/ g. C" y4 \/ g
    <P>        m_PlayerDataListLock.Enter();</P>
    9 v& r2 Q+ c: Y& s: L3 q<P>        PlayerData* pPlayerData = m_pFirstActivePlayerData;
    0 j, t4 v2 a8 l  Y+ U2 u8 A        while ( pPlayerData )
    7 t- ~! k2 a8 n' n8 j3 x        {
    3 `9 a$ ^+ [9 H3 I# V            if( fCurTime - pPlayerData-&gt;fLastCITime &gt; fOldestTime )
    " G  \8 G  z' t            {
    , y1 E( s" x. r                fOldestTime  = fCurTime - pPlayerData-&gt;fLastCITime;2 ?0 F0 ~# c- h
                    pOldestPlayerData = pPlayerData;
    + R0 J8 j* K, N            }</P>* U! `% U# m* h. \1 i( s
    <P>            pPlayerData = pPlayerData-&gt;pNext;
    0 w9 B: x/ k. R        }</P>
    9 `/ ~1 Q2 t# N2 v( y# H, y<P>        // Display the player with the oldest CI field, and update its CI field.2 }2 g; T# U3 s9 @7 {& S) a/ Y% b! o
            if( pOldestPlayerData )( i# l: [; K0 J
            {; E1 y" l. W6 D, X
                ConsolePrintf( SLINE_LOG, TEXT("Displaying connection info for next player") );8 E4 |3 t8 ]6 u2 ]' Q
                DisplayConnectionInfo( pOldestPlayerData-&gt;NetID );. ~6 @( a! X% `3 _2 m- n
                pOldestPlayerData-&gt;fLastCITime = fCurTime;
    + q" C1 B$ d/ J% @0 K1 `" M3 U        }
    & `8 L' K* g, F; d        else
    2 [3 a- l8 b4 s+ `! x        {
    6 C$ S  P  g9 Z9 B            ConsolePrintf( SLINE_LOG, TEXT("No players found") );
    , d* R6 R( i- o0 z! T( }3 s0 K        }</P>
    9 e( T5 E6 {7 F8 p9 _* g- Z<P>        m_PlayerDataListLock.Leave();# o$ x6 [" X# |' z4 f, F1 E
        }
    0 M: r' t) c4 k1 r& c}</P>* X. ~6 l% k& D

    1 g% Z4 Z8 Z( D1 J<P>7 C; {2 R) K9 a/ k0 w
    //-----------------------------------------------------------------------------
    9 ]: l  D* L/ H0 W6 H1 u// Name: + t9 ^# I/ D# M7 o  B" ~9 m
    // Desc:
    & U  n3 `" _' s1 i& X9 m( |; o. @//-----------------------------------------------------------------------------
      l5 z/ O7 t" R- D, r) J5 |. Hvoid CMazeServer:rintStats()( g6 q$ c) N( _* [. v
    {, Z( ?9 a5 O1 D, n" W( y2 b1 F
        ConsolePrintf( SLINE_LOG, TEXT("Thread count: Active=%d Avg=%.2f Max=%d"), ! V" \: F& ]2 Z/ h2 B
                                        m_wActiveThreadCount, m_fAvgThreadCount, m_wMaxThreadCount );6 ]: G7 @1 w4 c9 r" `7 R
        ConsolePrintf( SLINE_LOG, TEXT("Thread Time: Avg=%.4f Max=%.4f(s)"),$ A3 k. [8 F! }7 e# V
                                        m_fAvgThreadTime, m_fMaxThreadTime );
    * N: |  I! u6 ^6 {5 h    ConsolePrintf( SLINE_LOG, TEXT("Players online (not including server player): %d"), m_dwPlayerCount );. M, \4 Q- S$ \0 ~/ P" v% K
        ConsolePrintf( SLINE_LOG, TEXT("Peak player count: %d"), m_dwPeakPlayerCount );
    8 f* s! ^% b5 h% q( p}</P>' @$ N: g9 R" d" v% G
    6 L3 f4 M- u4 V! W! f; f5 r$ n0 l
    <P>
    ( \' p  o& d/ V0 i* p//-----------------------------------------------------------------------------
    ! G- S: W/ x' `5 x; T// Name: 3 I; o: a; F: H" b
    // Desc: $ J3 n: v$ W" S2 |* a& S7 }# z5 W
    //-----------------------------------------------------------------------------  K  U  Y8 ^% F
    void CMazeServer:isplayConnectionInfo( DWORD dwID )" s# O' q8 N5 Z: P# {/ ?9 h
    {
    1 w  }7 |8 K# x* ]5 |    TCHAR strInfo[5000];$ h" C' v% m9 k. L) k
        TCHAR* strEndOfLine;
    ) I+ u  U) n% Z* [; t1 {% O    TCHAR* strStartOfLine;</P>
    ' B. G; p! M' g% n( {8 Z  B8 u& F2 K<P>    // Query the IOutboudNet for info about the connection to this user( ^5 a- i4 [+ m  e: v# `2 q
        m_pNet-&gt;GetConnectionInfo( dwID, strInfo );</P>
    + s3 i$ [. K4 L<P>    ConsolePrintf( SLINE_LOG, TEXT("Displaying connection info for %0.8x"), dwID );  Z' d! S7 j1 G" J# [- Q, `; N
        ConsolePrintf( SLINE_LOG, TEXT("(Key: G=Guaranteed NG=Non-Guaranteed B=Bytes P=Packets)") );</P>
    % Q9 i, c) f9 J" f( y8 K0 }' F! Q<P>    // Display each line seperately3 V" W/ ~- J9 n- o' \0 e
        strStartOfLine = strInfo;
    - K9 B" \3 r" x! D. Y0 j    while( TRUE )7 |4 Q2 Z2 U* _# ~/ B
        {4 q2 t5 H. L2 e. R1 k; f% }) j% D
            strEndOfLine = _tcschr( strStartOfLine, '\n' );3 b8 S! d* Z/ a8 l" R
            if( strEndOfLine == NULL )
    + S  n" P0 f1 X) _3 d            break;</P>; p7 ]  R! }9 @
    <P>        *strEndOfLine = 0;* i6 I8 ?. b! ^/ X( |
            ConsolePrintf( SLINE_LOG, strStartOfLine );" I- s) x6 I. S8 @. z. V1 r; X
            strStartOfLine = strEndOfLine + 1;  f, U4 b- U$ Z% O" P! V
        }
    1 y2 u0 C! j1 z0 [}</P>- y" j- `( f& H) j

    $ l1 f* E8 c9 F: z/ ?; [<P>& D* u, k, j: c5 A
    //-----------------------------------------------------------------------------
    2 m6 e& u0 \6 U; {( {3 Y/ n; S% \0 F// Name: 4 L( C' v0 B& c: z7 v/ m2 x* b7 b* d" M
    // Desc:
    9 P4 G  w9 m( {( S//-----------------------------------------------------------------------------
    0 N+ N- z) W  N( M! r, RHRESULT CMazeServer::SendPacket( DWORD to, void* pData,
    5 ^: ?. U0 u+ v. R" C  m# W8 c. w                                 DWORD size, BOOL reliable, DWORD dwTimeout )/ W% h% `' S" V) }% }
    {+ W" u$ B0 u( v& T9 e7 K  H% L
        // Chance of forcing any packet to be delivered reliably
    0 k% G4 u/ ?* ?; a4 N* f* H    if( m_Rand.Get( 100 ) &lt; m_dwServerReliableRate )
    ) z3 m/ T* K9 E( \% v0 t& q        reliable = TRUE;</P>
    & g4 L# V" q" [/ j. k+ R+ [<P>    return m_pNet-&gt;SendPacket( to, pData, size, reliable, dwTimeout );8 G" u4 V# h: @9 C; Q
    }</P>
    : ]( b/ g; A9 c$ Q3 w6 F0 O; u& A5 v
    <P>% J7 B+ e: y9 Y# w
    //-----------------------------------------------------------------------------
    / x$ T5 |, X  g. o( M0 \3 m// Name: 3 A, {$ \1 ?$ w8 V- D
    // Desc: 9 V* }. U5 x4 L9 I3 D
    //-----------------------------------------------------------------------------: _# Z1 L$ w; D6 i
    void CMazeServer::SendConfigPacketToAll( ServerConfigPacket* pPacket )* c  Q! m6 G( C( n0 s, d
    {
    0 [7 {" V6 n: _7 Y2 ~9 k    // If we're up and running, then send this new information to all clients/ f: |% `5 q7 [9 v2 L+ l. b3 @
        if( m_pNet )
    # G6 P2 l& ]1 r' `$ W1 g    {
    ( O! ~0 A7 C" B! T        //Use the AllPlayers ID
    $ K7 P0 X& Z+ y9 r; x/ e        SendPacket( DPNID_ALL_PLAYERS_GROUP, pPacket, sizeof(ServerConfigPacket), TRUE, 0 );) S9 I. F. t6 ~! \/ `
        }& `" Z" t. Y2 Q/ F5 _  f( Q0 r$ _
    }</P>' U: z0 E' e: Y# `) f9 s

    2 h1 l* P/ L5 W<P>' S  J$ w6 u  w% l' j! q9 y
    //-----------------------------------------------------------------------------9 n% l! F/ @. W& [7 X
    // Name:
    1 k8 s& Y! M* T/ Q// Desc: ! l  T& l5 ?. i2 R4 [& i; l; F
    //------------------------------------------------------------------------------ g& ]: e* r8 @. [8 j0 w% _
    void CMazeServer::SetClientReliableRate( DWORD percent )) _" G6 l2 ?7 w2 N  z* e% h3 U
    {
    $ ^  z2 c6 s! L+ g    // Update client config, and build packet containing that data- i9 L* p" z+ I: t
        m_ClientNetConfigLock.Enter();- c/ o; q+ e1 o+ W
        m_ClientNetConfig.ubReliableRate = BYTE(percent);+ S) z. S% b" d+ R* t
        ServerConfigPacket packet( m_ClientNetConfig );' T" L$ |& v( \. o& ^- C% v
        m_ClientNetConfigLock.Leave();</P>
    9 L0 s/ Q( H" x! Z<P>    SendConfigPacketToAll( &amp;packet );
    ( @9 m/ C( |7 L+ Z3 P" x; i}</P>
    , Q$ n* M# n+ N5 o1 N- g+ Z+ J* k1 Y& D2 Q. I: b, h2 n' z
    <P>4 ?% o7 f9 Y( H4 F
    //-----------------------------------------------------------------------------
    8 C: n2 l3 R  ^  R7 A- O5 w" E1 p$ g9 Q// Name:
    / ?" X* @3 `, E6 @8 p) c! ?// Desc: ! C: H& b  X& t
    //-----------------------------------------------------------------------------' d: B7 M9 r# k# [7 X
    void CMazeServer::SetClientUpdateRate( DWORD rate )
    2 w- D* ?- K: S; z; S% j; K. h( ~{
    # k# n) L- A* G6 g' Q    // Update client config, and build packet containing that data9 M/ k7 E( \4 Y9 N; Y  ~
        m_ClientNetConfigLock.Enter();
    ' ?! p$ E; e/ v1 p* Y    m_ClientNetConfig.wUpdateRate = WORD(rate);9 q. _/ T; V3 S$ c- t" w, B
        ServerConfigPacket  packet( m_ClientNetConfig );7 F$ D/ j8 I5 e
        m_ClientNetConfigLock.Leave();</P>7 e! N) [8 {6 C: r! x
    <P>    SendConfigPacketToAll( &amp;packet );, x  I7 R  m5 \& F  r( O' }
    }</P>: d0 u/ K5 K! O% W7 m( m  U+ V
    " m: }$ K7 D% C6 G, j
    <P>
    2 @. U, C$ l3 ^1 R2 A7 s( \9 O% c//-----------------------------------------------------------------------------! z) O$ ]" @* N; E
    // Name: $ C8 |: z6 p2 v
    // Desc:
    ' D3 V2 V' p+ P* e5 W//-----------------------------------------------------------------------------, w% e/ \7 _+ w2 r* v1 C
    void CMazeServer::SetClientTimeout( DWORD timeout )$ a& w1 s$ w1 r, H8 v$ G5 R: u1 E
    {# I' P& i: z" U0 h7 ]
        // Update client config, and build packet containing that data) P4 p, E& N; k& \" K# h
        m_ClientNetConfigLock.Enter();; B3 W% x6 A% ^( s& \3 @
        m_ClientNetConfig.wTimeout = WORD(timeout);! w( Q* V- S! c2 F" ?5 z
        ServerConfigPacket  packet( m_ClientNetConfig );7 C/ _4 ?: {3 D! l% d7 f  z0 j
        m_ClientNetConfigLock.Leave();</P>! J' P  ?0 L8 p8 Q' W: X6 R5 G
    <P>    SendConfigPacketToAll( &amp;packet );4 D# y' k6 \# d& J) A0 J7 O: g
    }</P>2 @8 d; L4 ]$ H9 K/ }* ?9 F7 V# w

    2 [* _- g) R& z$ c4 @+ I<P>0 Q5 h. v* |. n: e1 f+ N- J
    //-----------------------------------------------------------------------------
    2 `2 t' j' j* n' @4 Z1 d// Name:
    ( ~0 s& W. X  `9 a// Desc:
    1 O& d* p2 F. K' R//-----------------------------------------------------------------------------5 `2 K7 o. i& _
    void CMazeServer::SetClientPackSize( DWORD size )% Y) j+ x$ C; i8 H- D
    {/ b7 Y! _' `; [* |2 v7 Q; r
        // Update client config, and build packet containing that data
    : N+ b0 E# n: E, m    m_ClientNetConfigLock.Enter();
    6 d8 G/ i" a: A9 K. o( U. K    ( L1 ~0 b" u; M* A
        m_ClientNetConfig.ubClientPackIndex++; //Increase index and verify location in array.! r4 S* d# X: ]) J
        if(m_ClientNetConfig.ubClientPackIndex &gt;= PACK_ARRAY_SIZE)   
    ' C. w& p& l. g4 [5 \        m_ClientNetConfig.ubClientPackIndex = 0;</P>
    0 P' _7 I8 Y' o  _/ g  b" Y( f7 I<P>    m_ClientNetConfig.wClientPackSizeArray[m_ClientNetConfig.ubClientPackIndex] = WORD(size);
    3 l, ?6 _. B' F% D    ServerConfigPacket packet( m_ClientNetConfig );9 N& x0 y; T5 l' A
        m_ClientNetConfigLock.Leave();</P>
    , k- O: ~/ h# f<P>    SendConfigPacketToAll( &amp;packet );
    0 E. M: X% U0 j* Q}</P>
    3 r4 t, S6 L2 X3 u; M
    ' F6 B  g' e7 Y. f' w<P>
    2 F: M* F% @8 S1 Y4 s//-----------------------------------------------------------------------------+ x  }, ]$ l5 @7 t! U
    // Name: 0 ^3 @8 x( b% V
    // Desc:
    & x$ b6 K3 l0 E1 S: i  ~//-----------------------------------------------------------------------------
    2 ~( s% e9 W. T. [( c* _* J" J  @void CMazeServer::SetServerPackSize( DWORD size )
    . v  Z2 [0 V  ~8 A4 Q' t6 L{
      v# }) O8 C5 c6 ~3 B    // Update client config, and build packet containing that data
    2 s0 f: s2 j# L3 ?3 X' y    m_ClientNetConfigLock.Enter();
    ) y% i5 M, s) B0 _& u5 t   
    / E, ?2 F7 Y  k& N    m_ClientNetConfig.ubServerPackIndex++; //Increase index and verify location in array.
    5 q; C& V" W& k/ g& Z    if(m_ClientNetConfig.ubServerPackIndex &gt;= PACK_ARRAY_SIZE)   8 F! h  a/ t+ R- I
            m_ClientNetConfig.ubServerPackIndex = 0;</P>
    / @& d$ Z) I! @+ w0 \<P>    m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex] = WORD(size);
    9 y( `* C' m9 \$ w% J' r; D    ServerConfigPacket packet( m_ClientNetConfig );
    : e7 N. t* C( @% n8 g    m_ClientNetConfigLock.Leave();</P>
    4 S8 E4 ]; M- b  i6 v& L<P>    SendConfigPacketToAll( &amp;packet );9 [; q& B: y. }' N3 }% S
    }</P>
    & \  z+ w9 T; F% |0 S<P>
    * R& q& o8 h2 C' ]6 j9 N$ r//-----------------------------------------------------------------------------
    * z. X& h+ x! v/ k& P+ R) A$ t  ~4 u' @5 k// Name:
    " h) Z2 d( u6 K: O# H" q// Desc:
    " c! Y! p+ g6 v. s) K& S. C% N# s+ P//-----------------------------------------------------------------------------
    0 m; T& n: S7 n' d' Q: Q8 e+ Svoid CMazeServer::SetClientThreadWait( DWORD dwThreadWait )
    $ A) h( I# `# }& Z- Y{
    ' ^" ~2 ~: L  x% A/ V7 ~, M    // Update client config, and build packet containing that data& \; g# v5 ~/ B* r( G" v
        m_ClientNetConfigLock.Enter();( t1 B) s6 x7 B3 T
       
    2 ~/ ]& U" ]# o) |0 R    m_ClientNetConfig.dwThreadWait = dwThreadWait;4 Q0 i0 a2 z9 D. F
        ServerConfigPacket packet( m_ClientNetConfig );0 ^3 m& V7 P' v9 l4 _0 r, @
        m_ClientNetConfigLock.Leave();</P>
    / y; @& f3 j/ P6 d/ S0 r6 M; p# ]<P>    SendConfigPacketToAll( &amp;packet );
    # d' ]. e. i# 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-10-10 02:01 , Processed in 0.749290 second(s), 50 queries .

    回顶部