QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 4245|回复: 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>' I; j, z  M3 x' P+ [
    <>// File: mazeserver.cpp
    1 D$ o' k8 M5 m' ^//
    $ @- E' _5 b6 N// Desc: see main.cpp& E  |. J- L+ G# ]1 i: T" ]
    //
    2 d* p% T; u: Z! b3 s. x/ f* O// Copyright (c) 1999-2001 Microsoft Corp. All rights reserved./ W2 b/ a8 m! s; w- R( G9 d# j  C8 O
    //-----------------------------------------------------------------------------
    ! e4 J/ M. `; \9 r( t* Y3 @#define STRICT1 J) b$ G4 O$ X" d
    #define D3D_OVERLOADS6 ~) n$ m3 k7 i$ g3 x- i3 \
    #include &lt;windows.h&gt;8 P1 J( J$ U! @, a4 z/ U
    #include &lt;d3dx.h&gt;
    $ R% @5 }& h. q; N% N/ |#include &lt;stdio.h&gt;
    2 b- C+ d: R! N7 @9 K#include &lt;math.h&gt;/ L. A" e, h" [
    #include &lt;mmsystem.h&gt;; v/ k1 H0 {0 s% I( B4 e" [
    #include &lt;dplay8.h&gt;
    ' J! O9 e, h. b( m0 `' c. L* Q#include &lt;dpaddr.h&gt;
    - B+ L) E4 C+ M6 ~4 I) g#include &lt;dxerr8.h&gt;
    $ [& u- d5 k) I- a! E#include "DXUtil.h"* R5 d" l, D( j; T. c) g
    #include "MazeServer.h"1 ]+ }: n) R+ G) r
    #include "ackets.h"
    3 R7 f* a5 C7 h5 t#include "Maze.h"
    : t( b. t* J9 i- X$ q. P#include &lt;malloc.h&gt;
    # }' V8 \, ^; W. M7 q' `#include &lt;tchar.h&gt;</P>* N0 d' B" L3 q- {

    ( V2 u$ U8 z. ~; j7 t6 D<>//-----------------------------------------------------------------------------
    : f; ^) z( e: F& [// Name:
    / w- o. m/ J0 v5 d0 K3 U// Desc:
    : P' q( l: y6 s" \7 X) t' Q. ]//-----------------------------------------------------------------------------
    - w3 e# Z# T! qCMazeServer::CMazeServer()8 `/ s$ [9 p7 k' j! ?! F
    {
    3 U) i7 F4 ], H8 U. ]    m_dwPlayerCount         = 0;
    + H, r2 @) t& |. d    6 U% k, B, O6 e: t. x9 [
        m_wActiveThreadCount   = 0;& k$ ~) z4 H6 _
        m_wMaxThreadCount      = 0;
    6 y( C: c# p/ u6 A, e9 w: c; |# _    m_fAvgThreadCount      = 0;
      Q; r; j6 h/ z& _% n6 A    m_fAvgThreadTime       = 0;6 K3 Z) A, N- }. M
        m_fMaxThreadTime       = 0;</P>7 ^# C0 P( A- L4 |2 v
    <>    m_dwServerReliableRate  = 15;
    0 |3 p/ X, Y& i    m_dwServerTimeout       = 150;
    : r$ I8 D! ?- G7 b  o, _1 T    m_dwLogLevel            = 2;: d9 S5 {9 S1 [8 @0 m- @) n
        m_pMaze                 = NULL;</P>
    ( x9 d# u1 e+ Q# X<>    m_ClientNetConfig.ubReliableRate = 15;/ W' X1 ?0 H: R; p/ `  s
        m_ClientNetConfig.wUpdateRate    = 150;
    2 I! e+ D, e$ n; v    m_ClientNetConfig.wTimeout       = 150;</P>
    ( Z2 d/ k5 _; x2 u4 F; H<>    m_ClientNetConfig.dwThreadWait = 0;</P>
    3 D& t3 }6 R  ^. B<>    m_ClientNetConfig.ubClientPackIndex = 0;
    5 \3 _" r4 i5 Y# k    m_ClientNetConfig.ubServerPackIndex = 0;
    : p: r* T7 s" _% F6 n: X( V    for(WORD x = 0; x &lt; PACK_ARRAY_SIZE; x++)  {% U8 H0 K; S' {
        {9 X2 \1 Z8 ?  T" \# y0 T5 T5 s
            m_ClientNetConfig.wClientPackSizeArray[x] = 0;; X5 l; A! r; v' {0 H
            m_ClientNetConfig.wServerPackSizeArray[x] = 0;5 h' y6 t+ F  H+ }
        }
    & U/ d* c- W3 f}</P>
    2 z7 v; i& T5 F2 C3 f. B1 T/ p
    . H) h5 G. t% U. b; f<>
    5 Y$ {' v- p' g- _//-----------------------------------------------------------------------------& ~7 s& Z; U% C
    // Name:   d. J$ M, ~2 q* r; ?
    // Desc:
    3 E2 U" H7 C/ F* y2 o# X  P* P//-----------------------------------------------------------------------------
    ) W) Y! q4 o0 ^) X  T! Y( ^  I2 WHRESULT CMazeServer::Init( BOOL bLocalLoopback, const CMaze* pMaze )& u- C9 Z. `. Y' h) u" N; \
    {* A- G. i* r% s1 L5 z
        m_bLocalLoopback = bLocalLoopback;+ R7 @7 o, g. _( W3 D% g5 C
        m_pMaze = pMaze;# g* B8 U% Z5 C, k( L! z
        if( m_pMaze == NULL )
    ; b; N2 O8 F, Y6 |8 P        return DXTRACE_ERR( TEXT("aram"), E_FAIL );</P>0 M& `. J  K3 x$ m. A* ]0 F( f8 x; L
    <>    // Grab height and width of maze
    8 j1 e+ J6 W) C  X& L; \' a! q% E    m_dwWidth = m_pMaze-&gt;GetWidth();
    ' F, R5 Q( W: W1 d2 x    m_dwHeight = m_pMaze-&gt;GetHeight();</P>
      Q; O( W( ^7 P1 F( j5 o6 k<>    m_ClientNetConfig.dwMazeWidth  = m_dwWidth;
    8 R* N/ y- j9 C8 A. Y. L' H    m_ClientNetConfig.dwMazeHeight = m_dwHeight;</P>/ J% `9 [$ H8 n
    <>    // Validate size. Must be a power-of-2 times LOCK_GRID_SIZE. Compute the shifts.4 U: l4 \5 [1 i9 i
        if( m_dwWidth &gt; SERVER_MAX_WIDTH || m_dwHeight &gt; SERVER_MAX_HEIGHT )3 b  z( N$ B. u. f6 ?! c$ d+ G% }
            return DXTRACE_ERR( TEXT("Maze height and width need to be less than 128"), E_INVALIDARG );
    ) g3 B/ r+ D" U/ i4 U1 @4 I    if( (m_dwWidth % LOCK_GRID_SIZE) != 0 || (m_dwHeight % LOCK_GRID_SIZE) != 0 )+ ]2 E3 ^/ b' z" O% \; {3 L( u: P
            return DXTRACE_ERR( TEXT("Maze height and width need to be divisable by 16"), E_INVALIDARG );</P>
    ! r; J: j) P3 I( h2 d7 k<>    DWORD scale = m_dwWidth / LOCK_GRID_SIZE;
    ) @& P) M1 z9 R$ T9 |    m_dwMazeXShift = 0;
    ( t. k+ h+ A; t5 L    while ( (scale &gt;&gt;= 1) )
    * r' F) }% Y! B, s; [7 u& [) T+ q        m_dwMazeXShift++;</P>
    4 }" P+ g2 H. s<>    scale = m_dwHeight / LOCK_GRID_SIZE;: E6 A5 v; ~( V6 |0 {+ \, g
        m_dwMazeYShift = 0;
    ' N2 M* o7 S' @# F1 @    while ( (scale &gt;&gt;= 1) )
    ' U/ p; v+ ^6 A' q2 Z0 c        m_dwMazeYShift++;</P>! ^5 g  ]% f7 ]4 g: \! F
    <>    if( ((DWORD(LOCK_GRID_SIZE) &lt;&lt; m_dwMazeXShift) != m_dwWidth) ||
    , {+ @7 S; J% H9 O9 z$ |        ((DWORD(LOCK_GRID_SIZE) &lt;&lt; m_dwMazeYShift) != m_dwHeight) )
    ' L* c' `  k! U7 F2 Q) r        return DXTRACE_ERR( TEXT("Maze height and width need to be power of 2"), E_INVALIDARG );</P>
    / O5 I- P% Z5 U2 _/ F' T1 D<>    // Initialise the player list
    ; \' o& a0 @# S: m+ T$ B    ZeroMemory( m_PlayerDatas, sizeof(m_PlayerDatas) );, N. H$ w! E: A! I. K7 X
        m_pFirstActivePlayerData = NULL;
    7 A7 r+ M! Y" ~# \) \* ]& R    m_pFirstFreePlayerData = m_PlayerDatas;0 U! ?" w9 S6 y' z4 U: n
        for( DWORD i = 1; i &lt; MAX_PLAYER_OBJECTS-1; i++ )
    - o& ~; @+ t( D- ^6 @- O- |    {0 c7 t7 M3 J! l6 {
            m_PlayerDatas.pNext = &amp;m_PlayerDatas[i+1];
    7 ?; {) t6 ^* @0 W- Q/ ^2 T        m_PlayerDatas.pPrevious = &amp;m_PlayerDatas[i-1];
    3 K4 E8 I' n( u# y    }</P>
    ) c- F  n- S- a* [+ I<>    m_PlayerDatas[0].pNext = &amp;m_PlayerDatas[1];7 E* M- J3 I2 O; V: r% g
        m_PlayerDatas[MAX_PLAYER_OBJECTS-1].pPrevious = &amp;m_PlayerDatas[MAX_PLAYER_OBJECTS-2];3 _# q. a" f( v# O; C) [0 }7 ^3 O
        m_dwActivePlayerDataCount = 0;
    3 C4 v( z, }. A/ S# D& h    m_dwPlayerDataUniqueValue = 0;</P>
    6 W1 r, o& x& I* i( ~( y7 C<>    // Initialise the cells* d/ ?8 W, x9 U
        ZeroMemory( m_Cells, sizeof(m_Cells) );
    / T* }8 r4 P" _$ T# x: b& K    ZeroMemory( &amp;m_OffMapCell, sizeof(m_OffMapCell) );</P>9 \6 G% f+ C' o: E5 \
    <>    return S_OK;
    # w9 G  {, d2 ~  p1 Y}</P>+ t6 X, i$ A, j) s" r: G5 r

    ' }% n2 }2 Z. M' _7 ?6 q7 \4 r<>1 e- j- D* i5 Z% {0 n1 F9 |8 D
    //------------------------------------------------------------------------------ \3 H5 X; t% T! c: g9 ?
    // Name: 0 S( T- ?: T+ {8 b% r& O& c7 |5 g
    // Desc: , {0 ]4 D0 }1 t( j# h! b
    //-----------------------------------------------------------------------------, A) L( ]1 D: S/ h& |
    void CMazeServer::Shutdown()
    . Z& ^/ _( L% w% w. p{
    * I& v$ J! `) Y5 E}</P>
    2 B2 G* H1 K3 f& b, h% U% d& o: l* E* l  E/ g" C
    <>
    . M; v; v* @8 R4 S//-----------------------------------------------------------------------------; Z/ ]5 G/ W6 d3 s& z. A
    // Name: " L. D0 D' J3 I* u( b
    // Desc:
    7 C. l4 X6 P8 U//-----------------------------------------------------------------------------
    & e/ ^1 k* ^% L2 Q, Z0 [1 Rvoid CMazeServer:ockRange( DWORD x1, DWORD y1, DWORD x2, DWORD y2 ): O1 J. z# C( c) Z& f4 |8 \9 c
    {& ], C0 a( C) ?+ o! J
        m_LockGrid.LockRange( x1&gt;&gt;m_dwMazeXShift, y1&gt;&gt;m_dwMazeYShift ,6 U8 a- `4 I0 \0 G" Y. a  e+ H
                              x2&gt;&gt;m_dwMazeXShift, y2&gt;&gt;m_dwMazeYShift );
    5 B. V/ P/ g9 n1 A7 m}</P>
    9 r, T$ L/ d8 @6 V& y! L. `; {# y* y( X: Y% \3 r
    <>
    6 U8 Q; c8 W5 [' ~* J/ c& \//-----------------------------------------------------------------------------2 q4 A1 u$ o* z4 S9 z: o# ~2 I
    // Name: 3 e: \) r7 I; Y# J
    // Desc: ) W* H  ?4 t; i! m, G0 U! K4 u; i
    //-----------------------------------------------------------------------------' {; ]6 ~& \5 h
    void CMazeServer::UnlockRange( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )) R. F' o* l) ?/ d# |
    {& q! i, w$ ?  t
        m_LockGrid.UnlockRange( x1&gt;&gt;m_dwMazeXShift, y1&gt;&gt;m_dwMazeYShift ,  ?9 a1 d8 e8 _  B' j6 v/ T& |1 A1 }
                                x2&gt;&gt;m_dwMazeXShift, y2&gt;&gt;m_dwMazeYShift );: h- u4 D8 ]; ^5 o  c
    }</P>4 I& m8 ~/ _) }

    # v! b$ f1 z7 p<>
    - R8 w, V1 z0 V//-----------------------------------------------------------------------------
    ; w9 X$ b4 u3 H! U// Name: 7 t. F+ h' }9 C" P0 g* j' N& b
    // Desc: " j5 v; L- \, x4 B7 D. }4 ]
    //-----------------------------------------------------------------------------( |" X) L9 u8 @4 h8 v1 ~) d
    void CMazeServer:ockCell( DWORD x, DWORD y )+ p/ s: X; o; o6 m9 s5 {" }/ y0 h) F
    {* K! ~6 f9 R" P8 z7 A1 V
        if( x == 0xffff ): |& s0 @0 N" r; f; H! m
            m_OffMapLock.Enter();9 ]( L6 i1 y& a
        else
    + M. H1 A" {+ F% g/ h        m_LockGrid.LockCell(x&gt;&gt;m_dwMazeXShift,y&gt;&gt;m_dwMazeYShift);
      l  f3 ?: f5 E0 {}</P>2 I# T' `5 ~, h; i* g- b
    0 p6 B/ }7 }1 |
    <>8 F, K( f- @* u0 t9 Q% ]
    //-----------------------------------------------------------------------------6 m1 m. r. ]8 o
    // Name:
    6 l. h8 E) a6 Y+ u* t0 `" t// Desc:
    ) G2 K9 G- w& v: j8 V7 E; P' h//-----------------------------------------------------------------------------
    7 s) R0 ~% E$ o) @: @5 B: J$ k# Qvoid CMazeServer::UnlockCell( DWORD x, DWORD y )
    ( B3 v* [: |/ _$ j{
    0 Z. N$ L& v# |  a; Z% L; u    if( x == 0xffff )/ n* J' F$ P, U9 O8 W- M% ?
            m_OffMapLock.Leave();6 ?2 n0 @/ s- O
        else- S: y% H) X% O" y- Y* ?, M
            m_LockGrid.UnlockCell(x&gt;&gt;m_dwMazeXShift,y&gt;&gt;m_dwMazeYShift);
    $ N- k# g- H+ _4 X2 J5 i}</P>- v$ x% ?' w; k0 N4 k) x1 [
    / H5 |8 A6 f8 s" x. K1 V
    <>
    1 ^4 t' u" b2 M9 k//-----------------------------------------------------------------------------
    & f! t- }/ j% Z$ R// Name:
    ' {5 i8 H( j' w: W( w# i; |! C// Desc: # T6 J0 \- {' F) W
    //-----------------------------------------------------------------------------
    ; P* V# k' C" W% rvoid CMazeServer:ockCellPair( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )
    % _! L/ F- i4 g( X' v( c{7 B& b8 o( H8 N# m7 m
        if( x1 == x2 &amp;&amp; y1 == y2 )
    " q* p9 W. S8 s# w    {6 _  M! j) V% s8 }+ n
            if( x1 != 0xffff &amp;&amp; y2 != 0xffff )- X; U/ p  Z( g( e% ~2 {
                LockCell( x1, y1 );' B$ Y% p& G3 D
            else: A; n1 @, P' c& S5 f8 A2 T
                m_OffMapLock.Enter();</P>
    ) o* S" C$ ^' o7 Y0 F5 B- n<>        return;4 Q6 ~' K% b& C/ b- {5 V
        }</P>/ @7 w. {8 W3 P
    <>    DWORD x1shift = x1&gt;&gt;m_dwMazeXShift;0 D4 ~% c: n8 a; }* x
        DWORD x2shift = x2&gt;&gt;m_dwMazeXShift;
      t0 ^  Y( G7 P1 B    DWORD y1shift = y1&gt;&gt;m_dwMazeYShift;  d( r  n6 b  ~$ S! W$ G) R2 w3 E: m
        DWORD y2shift = y2&gt;&gt;m_dwMazeYShift;</P>
    & d; g1 k& {, m, {8 d# }% o<>    if( x1 == 0xffff )
    ) v# Y9 I: [1 ?9 Z* W! N# _) y% n+ {    {8 x. R0 K6 A, k+ q1 W4 u, @
            m_OffMapLock.Enter();
    % Y( g. D2 I( q. d        m_LockGrid.LockCell(x2shift,y2shift);8 U- l! F* u5 ]
        }1 U' Z) D9 f1 |! Q, v  v
        else if( x2 == 0xffff )
    : `6 o8 w: o4 e8 m( U9 k    {
    ( v  @/ q8 k' ?! y        m_OffMapLock.Enter();, Y: f/ e# h* s6 d5 V
            m_LockGrid.LockCell(x1shift,y1shift);% R) Q) K  G9 ^* W4 n
        }
    $ K& R9 D% {! [: `: c1 \    else
    ) L1 S6 Z$ w8 W* S5 d3 G! T    {
    5 x" }! n0 ]' \& t. ]: t9 v        m_LockGrid.LockCellPair(x1shift,y1shift,x2shift,y2shift);7 t$ p, G. A) H% Q
        }
    5 a' f8 i/ J% a6 i* h* d}</P>" x1 d& x( ~  r
    ) b0 d" l" J- d/ K( r9 }" q, P
    <>+ n7 x* f- |$ k; N5 M
    //-----------------------------------------------------------------------------3 n* z* p0 \1 m& A4 z3 m( h. m
    // Name:
    ' L) V4 y- G$ R: ?' U// Desc: 7 W" F! S4 u. G
    //------------------------------------------------------------------------------ h2 J6 E2 G! @9 n" B
    void CMazeServer::UnlockCellPair( DWORD x1, DWORD y1, DWORD x2, DWORD y2 ): [$ O( E' B$ _2 ^- b
    {
    - @  r; f1 E1 J7 Y0 q/ l  Q: z, i    if( x1 == x2 &amp;&amp; y1 == y2 )
    4 B% U# W+ m# |7 d, L1 {% q$ C% y0 W' a    {: a1 {" @1 Q0 `  A& v7 Q& y/ T
            if( x1 != 0xffff &amp;&amp; y2 != 0xffff )) b% k/ F5 K9 f: x$ t5 o
                UnlockCell( x1, y1 );+ D9 L* ^. G+ ^/ \3 C( V  S
            else
    6 F2 l& d& c" B1 P            m_OffMapLock.Leave();</P># d4 ?; {6 ]9 @  C
    <>        return;
    : `- v8 \8 `0 y2 N+ r    }</P>
    0 B. m$ W& z1 T* m% l& y& }/ R% ~<P>    DWORD x1shift = x1&gt;&gt;m_dwMazeXShift;+ L! l  H# h6 \) j/ D1 @* V0 [
        DWORD x2shift = x2&gt;&gt;m_dwMazeXShift;6 r! |4 r1 J5 e  J- N! o
        DWORD y1shift = y1&gt;&gt;m_dwMazeYShift;, T) }/ v# Y$ x( y+ y8 S% ]1 w
        DWORD y2shift = y2&gt;&gt;m_dwMazeYShift;</P>6 `, ~( Q- _& p) M4 C
    <P>    if( x1 == 0xffff )8 c9 n% \) a% [' n- ]
        {
    1 E+ T$ x8 d6 v5 J! ~) U        m_LockGrid.UnlockCell(x2shift,y2shift);
    ! l$ I6 l. L7 |! P& ~9 S: ^        m_OffMapLock.Leave();
    ! Z8 L; k7 N0 ^0 v    }+ j; q1 D* `) n6 S
        else if( x2 == 0xffff ): c5 H: P2 @5 Q7 {* w. c
        {+ w$ T: G& B. D5 p" A
            m_LockGrid.UnlockCell(x1shift,y1shift);
    + V5 N4 o: D& G" E* |( g7 g1 B        m_OffMapLock.Leave();/ z) I+ v( v8 G2 F9 o
        }! d8 @4 z  m! L
        else % y* Z4 |5 L9 J5 U
        {
    " f; [0 s7 W8 e- g7 ^" w- H0 E        m_LockGrid.UnlockCellPair(x1shift,y1shift,x2shift,y2shift);
      `; K+ g8 |$ v( ~/ {8 @; Z    }+ `5 Y. @" y2 ]* {# R$ E) T
    }</P>
    ' O. {: O  H+ X0 }7 t+ y6 |& S
    + ^# x" O  r: X+ o6 X/ ]% D<P>
    ! f! d4 g+ P2 H1 Y& V//-----------------------------------------------------------------------------% g% ^3 e5 l! b7 p; p- ]
    // Name:
    - e2 M" v9 z7 ~6 i; s' m' [// Desc:
    2 e$ y! ~& g& k( \, t  s$ A( o! d//-----------------------------------------------------------------------------. m0 s2 G/ Z" [: _$ c9 g- x
    void CMazeServer::OnAddConnection( DWORD id )
    ; o( @! D  C( k  f! V+ c. ^{
    . f0 n6 c: {+ H    m_AddRemoveLock.Enter();</P>
    0 b1 \- j0 P) g' D6 r<P>    // Increment our count of players
    , `, H0 [: u$ ~" n: I+ }0 o    m_dwPlayerCount++;
      M' E; J6 T( U    if( m_dwLogLevel &gt; 0 ): i! j; }; o- S5 V/ i
        {
    , d' T, D7 V1 Q* y2 m        ConsolePrintf( SLINE_LOG, TEXT("Adding player DPNID %0.8x"), id );
    , y* R1 H0 L  _/ P        ConsolePrintf( SLINE_LOG, TEXT("Players connected = %d"), m_dwPlayerCount );0 _; G( g% j2 l) u, M- i) d' G
        }</P>
    # \+ d( H6 v$ n  M, D<P>    if( m_dwPlayerCount &gt; m_dwPeakPlayerCount )
    9 Y: |% ?" c. @        m_dwPeakPlayerCount = m_dwPlayerCount;</P>
    6 ^' E& [' ?; e0 x& t( p/ P3 u$ u<P>    // Create a player for this client4 A. b2 r0 M6 s2 X2 H
        PlayerData* pPlayerData = CreatePlayerData();
    , C* i& X. P) }    if( pPlayerData == NULL )
    7 d) l. P  K1 B7 c; r    {
    ; F6 T% X# T8 ]- B! K        ConsolePrintf( SLINE_LOG, TEXT("ERROR! Unable to create new PlayerData for client!") );
    * Y! q/ ^# _* V/ F        DXTRACE_ERR( TEXT("CreatePlayerData"), E_FAIL );* E3 e' N& v2 Y0 K0 ?, @
            m_AddRemoveLock.Leave();8 g) E/ {: n# ^# i0 E
            return;
    . h$ d3 C+ E. e+ ?; ~9 u5 g& X3 m& X    }</P>
    7 L9 v$ T$ U1 y3 V& `. M: ]* H<P>    // Store that pointer as local player data& v8 W' y1 x: u7 U! W
        SetPlayerDataForID( id, pPlayerData );</P>
    ' j, \/ |% J& I<P>    // Grab net config into to send to client6 c: K, e3 f  G+ V* i  u, F' c- }
        m_ClientNetConfigLock.Enter();
    . J6 v$ C' X; G0 u! u    ServerConfigPacket packet( m_ClientNetConfig );
    - n0 y4 N# M1 K7 ^8 j) C    m_ClientNetConfigLock.Leave();</P>
    ( c/ M% w  a: e2 R0 S<P>    // Send it4 F) R* |/ W5 t/ K/ p' z3 ?" V2 ~
        SendPacket( id, &amp;packet, sizeof(packet), TRUE, 0 );</P># E& `+ F  P# [; m
    <P>    m_AddRemoveLock.Leave();
    + C1 _+ G! G* e, v& i0 \}</P>0 P- T$ g, b7 D+ M; N

    # e6 T; w, Q2 k" \<P>
    ( q, e0 @3 W. i//-----------------------------------------------------------------------------
    , Z0 {" h  Y* j. r// Name:
    - t6 `' `  ]& |& |// Desc:
    6 p6 b! N* O  H//-----------------------------------------------------------------------------
    1 ~. T7 b, l" U0 a6 X+ mvoid CMazeServer::OnRemoveConnection( DWORD id )
    6 A" v% e0 S; t9 y{$ C/ o# _* a& M; `$ w3 ^: V  Z/ n( w
        m_AddRemoveLock.Enter();</P>
    8 P8 Z( D: J% h9 P& _. K<P>    // Decrement count of players4 Q: d0 ~# l1 l' p+ ?
        m_dwPlayerCount--;</P>
    0 F+ u8 U* m7 j0 A3 R0 J0 ~<P>    if( m_dwLogLevel &gt; 0 )) d+ \: H4 G$ T0 c# h2 q
        {
    0 b. ]* Y6 Q- u  u( ^2 y5 @/ i# Z        ConsolePrintf( SLINE_LOG, TEXT("Removing player DPNID %0.8x"), id );- P1 v8 d" B0 _2 A
            ConsolePrintf( SLINE_LOG, TEXT("Players connected = %d"), m_dwPlayerCount );' p* f/ P& Q# o
        }</P>
    / I9 H5 l( U, H% k<P>    // Find playerdata for this client
    % H0 d& d9 I5 n$ [& j    PlayerData* pPlayerData = GetPlayerDataForID( id );
      u& Q: |) K! s" H/ X8 x    if( pPlayerData != NULL )
    ( D; p0 `1 r$ n- @! K! L    {$ O, `( _# Z! \
            // Destroy it
    3 [9 s( b. i" J        RemovePlayerDataID( pPlayerData );
    # U- @* r0 `3 m7 P        DestroyPlayerData( pPlayerData );' l# V: C8 d7 i
        }</P>
    " |% J* L6 ^. o+ t" E<P>    m_AddRemoveLock.Leave();
    & [, ]1 c" B; m. X9 G* G}</P>
    , w1 V( l9 P  ^/ X6 y8 k3 k6 x& {- }
    <P>
    ) W8 C; c: p9 a1 u//-----------------------------------------------------------------------------
    - p9 U) D! b' o( u2 `9 k# B// Name: # K$ x. L: K% W; A
    // Desc: 8 X7 D' p, ^( b$ s$ S
    //-----------------------------------------------------------------------------
    $ r3 T$ i! q/ Y' K% }HRESULT CMazeServer::OnPacket( DWORD dwFrom, void* pData, DWORD size )- G8 {' W8 r1 b( V* h3 z  G8 ~$ u" D
    {4 z5 c( U2 G5 B6 G2 u. Z3 h6 |: _- s
        BOOL fFoundSize = FALSE;</P>0 [$ |% k+ B: E' B9 T: _2 |1 t
    <P>    // Increment the number of thread we have in this process.
    5 j$ j' W2 B0 N- c, k    m_csThreadCountLock.Enter();</P># O: ?$ M, q* \4 k  @" p" k1 I
    <P>    //Get the start time of when we entered the message handler.2 v6 d6 D6 U* X8 X1 t
        FLOAT   fStartTime = DXUtil_Timer( TIMER_GETAPPTIME );</P>
      s2 {, T8 k7 b' D* I<P>    m_wActiveThreadCount++;
    ) u" j& k( J1 e8 |3 d4 R$ B- q    if(m_wActiveThreadCount &gt; m_wMaxThreadCount)4 m. L# B8 O) ]  l9 K8 k. i; R
            m_wMaxThreadCount = m_wActiveThreadCount;
    2 d0 z! C% V& k, t9 [; G  R/ b    $ q8 h" W1 \  u5 {; [1 M1 q
        // Calculate and average.) [( N/ r* a  K
        FLOAT fdiff = m_wActiveThreadCount - m_fAvgThreadCount;
    $ b' ]3 s6 O( w( U! a: K    m_fAvgThreadCount += fdiff/32;
    % }) K+ q' U2 t   
    ( s2 [. w- `, E1 @1 E    m_csThreadCountLock.Leave();</P>: b/ }. ]( A& s
    <P>+ \% q, d. J1 W, T8 d
        ClientPacket* pClientPack = (ClientPacket*)pData;( O* B) b: p, f; `' v, _
        switch( pClientPack-&gt;wType )' D: j3 k- G; t1 C/ H6 Z8 G
        {1 L, |9 o4 Y9 j! [' n% B
            case PACKETTYPE_CLIENT_POS:& C& b$ {! E: n/ y, E6 _! f1 i; c  k
                6 R" f, J' J9 o$ k! p' ~
                // Check to see if the packet has a valid size. Including ( ^7 x: G  C; R0 y
                // the custom pack size.! w/ H: |, W4 a
                if( size &lt; sizeof(ClientPosPacket))
    7 Z, v( s) r( `  G0 Q& N+ W" ]                fFoundSize = FALSE;+ q0 D5 ~7 z0 t  ^- f; y
                else if( ! IsValidPackSize(size - sizeof(ClientPosPacket)))
    9 F$ H- [) h% ?                fFoundSize = FALSE;
      T& G" n, d6 P            else2 C. l( [% _8 f6 q3 z$ G: i0 |
                    fFoundSize = TRUE;</P>4 }  L( S# t6 Y* ^  o6 U$ M+ T
    <P>            // If valid sized packet, handle the position.; R$ N, J9 X' ?& {9 _. i
                if(fFoundSize)9 q' i! L' ~% @" B; \/ @8 e
                    HandleClientPosPacket( dwFrom, (ClientPosPacket*)pClientPack );
    * @+ c5 N$ |+ E. j            else+ B# e% F. i. T2 y
                    m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );</P>, q6 u  X0 ?5 @/ b7 ]- f9 B- E6 o
    <P>            break;</P>
    ! @: k, {, z% S$ t5 G/ v% s* c<P>        case PACKETTYPE_CLIENT_VERSION:2 t6 _8 x( \/ |; K
                if( size == sizeof(ClientVersionPacket) )2 ^7 p* S' x5 E: R, g
                    HandleClientVersionPacket( dwFrom, (ClientVersionPacket*)pClientPack );
    ' x: n  [+ R. C) }5 a            else
    ' ~/ _8 M& Y0 ?' c5 D                m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );
    7 l8 D' c$ e1 T3 ^5 D% @8 I) L" j" V            break;</P>; a1 l' o( i( m
    <P>        case PACKETTYPE_SERVER_CONFIG:</P>
    5 X6 p/ @3 j# P5 P. C$ g<P>            // Server config packet sent to all users (including server). Just ignore and continue.</P>' B2 E& N& F9 T9 `  P# h! R
    <P>            break;
    4 A* x" b5 j" Y7 \        default:2 q1 e  i1 ~/ p. H0 O9 ^2 N* r$ L
                HandleUnknownPacket( dwFrom, pClientPack, size );
    ' \2 k: H* A; d/ O. M1 k- e9 m            break;
    - L# F1 d9 h( r9 F: I    }</P>
    - v& B% X% A8 D' X/ M: R/ V<P>    //If the user wants to hold the thread, Sleep for given amount of time.
    8 W3 p! b) ?+ G! }4 h9 w! _    if ( m_dwServerThreadWait &gt; 0 )
    & X, `8 K* R0 M& r" t% T    {
    + }- R: q/ I4 [/ d        Sleep( m_dwServerThreadWait );2 @0 D, F# P6 \" X! t. \5 ~4 A5 E
        }2 P+ z; b& i$ T( b
       
    6 N( x4 j# T/ e/ |- q9 B    // Retrieve thread data for this process.3 J- N  ^/ b7 N: k5 g3 _
        m_csThreadCountLock.Enter();</P>
    0 r: l* P) u) a- V5 M<P>    m_wActiveThreadCount--;</P>
    . t6 E, `# I) z( ^5 {<P>    FLOAT fDiffTime = (DXUtil_Timer( TIMER_GETAPPTIME ) - fStartTime) - m_fAvgThreadTime;
    ; e* ?% {$ Y$ }# U+ _5 m9 w8 w% r    m_fAvgThreadTime += fDiffTime/32;</P>) H! w9 t) b7 `8 P# k: B
    <P>    //Get the Max time in the thread.
    : J! V9 }' e; W9 Z8 n- P. l    if ( fDiffTime &gt; m_fMaxThreadTime )
    $ s% P9 U* v0 g3 V5 z( ?    {
    1 K3 _  i) C+ F7 F2 ]: P        m_fMaxThreadTime = fDiffTime;
    ! a6 g$ V0 C9 ?! o/ s    }</P>* l' T4 s6 i  v8 X9 ]7 C
    <P>    m_csThreadCountLock.Leave();</P>9 t0 p" n+ M+ w" W% o( C* C# l4 n
    <P>    return S_OK;  ?* {' s. y. n0 e% \
    }</P>
    % `7 k3 t9 j7 I6 F' F6 u4 t4 P$ K
    ) R5 ]5 k/ m1 B  p! J$ ^; E<P>//-----------------------------------------------------------------------------5 q# K; a! D2 O# s7 w# S: U) d
    // Name:
    5 A. C& q- M5 t& z' {" @// Desc: & H* J2 ]" T% Z+ p
    //-----------------------------------------------------------------------------
    % ^: U4 c  ]: T3 i6 N5 lBOOL CMazeServer::IsValidPackSize( DWORD dwSize )
    9 F" X/ R. V& m1 r/ _) ^8 m. _5 ?{
    $ y' `$ l7 o; T5 a+ c- V* u    BOOL fFoundSize = FALSE;
    / p$ P7 h5 S7 w* I1 L# a9 I    BYTE ubPackLocation = m_ClientNetConfig.ubClientPackIndex;/ p" _, Z, I6 B
        ! \; \. b+ n/ i" n
        // Check through the array of valid pack sizes.5 S0 j5 P+ j+ p
        if(dwSize != m_ClientNetConfig.wClientPackSizeArray[ubPackLocation])5 F& I+ v- d( ~8 \: i
        {
    % q' d% _' p, y  C8 n        for( --ubPackLocation; ubPackLocation != m_ClientNetConfig.ubClientPackIndex; ubPackLocation--)3 z* u* v* R1 b5 ~, g5 A
            {3 Q% S6 \) U: y5 k
                if(dwSize == m_ClientNetConfig.wClientPackSizeArray[ubPackLocation])
    ) F! t' ?; @. }% O            {4 s& o# D6 R/ C: Z; L
                    // Found valid size in the array.
    3 B- n1 m* Y; w- g: x" L  b                fFoundSize = TRUE;& Y8 F* p7 e5 N4 n# l8 _/ {
                    break;
    7 C8 L% Z% B1 v' V/ W4 W  }8 J( y7 m            }
    ) Y5 O" s5 V! M& c            if(ubPackLocation &gt;= PACK_ARRAY_SIZE)  ubPackLocation = PACK_ARRAY_SIZE;  //Wrap the array.
    & G8 U: f$ q6 w4 K  B- i- a3 }        }8 e% `% a) ^8 {1 R$ W. m+ G
        }
    $ ~' k" m9 }! y8 [* s    else
    $ c' O; J" M! {1 @$ k    {% E6 E9 @* A3 V" x
            fFoundSize = TRUE;
      N+ O8 x3 |% z& x7 V7 I% X4 q1 b    }</P>' D, V, _. z) W
    <P>    return fFoundSize;
    0 {+ b; P, E1 K1 S}</P>: r/ D" w+ m# F4 j
    <P>7 J# I1 u8 T+ Z/ d: W. ?
    //-----------------------------------------------------------------------------
    1 n& ?/ L4 y" c1 {# u7 q4 Y1 a// Name:
    ; N+ r0 c) [" i) X5 c( A// Desc: ; ~( ], X( A/ q% `; D3 s
    //-----------------------------------------------------------------------------. e* F9 t: P8 R. A7 O. ]
    void CMazeServer::OnSessionLost( DWORD dwReason )
    6 p- o3 m( F2 y2 |+ Z) p{
    ; g# l4 \' A% ]6 |+ T6 z    ConsolePrintf( SLINE_LOG, TEXT("ERROR! Session was lost") );
    + y$ Y, J7 u# Y( v. y}</P>/ d4 O" ?; W. G! e  ~: F7 {
    / Y6 E6 F4 \; O
    <P>
    * C$ q/ D) F- z8 B2 f2 {4 ^//-----------------------------------------------------------------------------
    8 R* ^3 v0 g$ m, n: S# m// Name: ; o0 e. g: E& z$ f( A% p, P1 _8 j
    // Desc: 2 a6 F& V# M) ^7 z" e0 H
    //-----------------------------------------------------------------------------
    2 ?0 J9 p/ }% S( o. _5 ^/ IPlayerData* CMazeServer::CreatePlayerData()/ R2 v1 q. y0 a) y+ K& b# G
    {0 a/ |2 ^3 S( f9 u' j3 f/ T
        m_PlayerDataListLock.Enter();</P>5 ]+ B8 z4 x% B
    <P>    // Grab first free player in the list
    5 o5 Z- ]* ^3 b0 t    PlayerData* pPlayerData = m_pFirstFreePlayerData;</P>  U5 b) Y) p" I3 h, C: Q
    <P>    if( pPlayerData )
    ' d) s! _% X: b9 P    {
    0 f& g- T/ |! H5 b& _% O        LockPlayerData( pPlayerData );</P>
    " p9 `3 B  U$ r5 I<P>        // Got one, so remove it from the free list
    3 V  [0 I/ g3 r5 Z+ e' g4 X8 i        if( pPlayerData-&gt;pPrevious )5 S0 b& L5 R' ^# o6 \
                pPlayerData-&gt;pPrevious-&gt;pNext = pPlayerData-&gt;pNext;/ ?  ?1 T& S6 k8 W, m: _
            if( pPlayerData-&gt;pNext )
    2 P5 W; ?7 h/ r+ L, J            pPlayerData-&gt;pNext-&gt;pPrevious = pPlayerData-&gt;pPrevious;
    ) W9 R$ y4 b* R0 I        m_pFirstFreePlayerData = pPlayerData-&gt;pNext;</P>% {& ~# {/ H! v: Q8 |
    <P>        // Add it to the active list& T" B. G% i7 I8 E
            if( m_pFirstActivePlayerData )
    & U5 w; c/ c! L9 ?; D0 U* x( u( ~            m_pFirstActivePlayerData-&gt;pPrevious = pPlayerData;) U# z7 I; T( O6 f' }
            pPlayerData-&gt;pNext = m_pFirstActivePlayerData;
    8 k" P3 E! E( O% B        pPlayerData-&gt;pPrevious = NULL;
    6 a! k+ o1 I  ^9 \1 Q        m_pFirstActivePlayerData = pPlayerData;</P>8 c' f) t& ^  L$ ?
    <P>        // Update count of players
    0 e/ e$ F1 L& r        m_dwActivePlayerDataCount++;</P>
      f. ]4 x3 F! Q+ G* b* k<P>        // Generate the ID for this player
    0 f& g( h& X1 G% a        m_dwPlayerDataUniqueValue++;5 d( ]9 F& `+ {6 o2 @
            pPlayerData-&gt;dwID = (DWORD) ((pPlayerData-m_PlayerDatas)|(m_dwPlayerDataUniqueValue&lt;&lt;PLAYER_OBJECT_SLOT_BITS));</P>1 C% C. m  c: l; |! S4 B& [6 E
    <P>        pPlayerData-&gt;pNextInIDHashBucket = NULL;
    $ `3 ^0 t* Z) s9 \9 ^        pPlayerData-&gt;NetID = 0;  p; \7 o3 ]2 k
            pPlayerData-&gt;dwNumNearbyPlayers = 0;</P>
    : s7 h( k4 B' Q3 \0 {<P>        // Insert into the "off-map" cell
    & B' V8 r: Z/ V# t' b0 y6 E/ x        pPlayerData-&gt;fPosX = pPlayerData-&gt;fPosY = -1;
    9 N8 {( n. A" Y+ T5 u' J( g4 }        pPlayerData-&gt;wCellX = pPlayerData-&gt;wCellY = 0xffff;- {2 r% h1 |$ y1 v! y+ Y
            m_OffMapLock.Enter();! T1 ]; r. C# ]* d7 T
            pPlayerData-&gt;pNextInCell = m_OffMapCell.pFirstPlayerData;2 }( i9 h6 }! t6 `$ E' ]1 Q
            m_OffMapCell.pFirstPlayerData = pPlayerData;/ L' n* D5 F  Y& ?$ k# n7 \) a! a
            m_OffMapLock.Leave();</P>. v6 ~! v9 j  c5 O5 g6 ]! V
    <P>        // Mark as active' T! g. G; C- a0 f( m9 q
            pPlayerData-&gt;bActive = TRUE;</P># ?9 @5 E% }! x7 s
    <P>        UnlockPlayerData( pPlayerData );
    8 _, @7 K- A" D! v: B5 O    }</P>
    7 C7 Z1 h4 n( \<P>    m_PlayerDataListLock.Leave();</P>
    ! z' j* m, h1 t  o& k/ B# N8 f, |<P>    return pPlayerData;
    / B/ |, b8 Y6 y2 N5 O$ i1 P# S}</P>
    # A) j! C. @7 V) P% M& M) r! W0 }; e: W5 C5 C/ W5 E& J
    <P>' q5 B* P$ p4 [
    //-----------------------------------------------------------------------------0 E3 t# ~& u2 q0 p
    // Name: 7 L, G! F0 i, [0 N- M  _) G5 s! w
    // Desc: ' Z" a. u4 N, _: z# m& k
    //-----------------------------------------------------------------------------$ G% F) K1 r8 A5 ^, V0 _
    void CMazeServer:estroyPlayerData( PlayerData* pPlayerData )' f$ H" h& G* r7 o# {4 i8 N
    {7 B: g+ A0 e/ i5 z5 `* d, Q
        m_PlayerDataListLock.Enter();+ ~0 s7 H' L0 t: g: o+ \& x" J
        LockPlayerData( pPlayerData );</P>2 X- W0 k) p7 t8 `# x6 g1 n
    <P>    // Remove the player from its cell0 E; {. H/ a1 N
        RemovePlayerDataFromCell( pPlayerData );</P>; Q3 S" E; [0 p% a$ S* ^) \; z) t1 H
    <P>    // Mark as inactive9 k( h7 e- _& G
        pPlayerData-&gt;bActive = FALSE;</P>
    6 w0 S4 I' R' j7 |% L5 s6 s- a<P>    // Remove player from active list( V& a6 z; b- o" j; Z
        if( pPlayerData-&gt;pPrevious )
    0 g- I4 m+ j# G9 D% W& `2 D' @* |        pPlayerData-&gt;pPrevious-&gt;pNext = pPlayerData-&gt;pNext;* X9 s3 S, E! v4 f: C: l
        if( pPlayerData-&gt;pNext )) i3 y4 T2 d! a2 F
            pPlayerData-&gt;pNext-&gt;pPrevious = pPlayerData-&gt;pPrevious;</P>, M' t7 t; ~& ?
    <P>    if( m_pFirstActivePlayerData == pPlayerData ); c) |: ?4 v4 a
            m_pFirstActivePlayerData = pPlayerData-&gt;pNext;</P>" r$ A4 V8 ~) a5 b" M& [
    <P>    // Add it to the free list. O* R2 c; e6 o5 Q) D
        if( m_pFirstFreePlayerData )
    . z1 h' Q$ I! V5 G        m_pFirstFreePlayerData-&gt;pPrevious = pPlayerData;
    + T+ f. W) y8 j- `- O& \    pPlayerData-&gt;pNext = m_pFirstFreePlayerData;0 m4 u- Z) O  E( Y
        pPlayerData-&gt;pPrevious = NULL;
    " o9 O3 |8 X5 H9 m    m_pFirstFreePlayerData = pPlayerData;</P>1 o" U( {$ I" d
    <P>    // Update count of players( t3 G/ v, E. f/ P) @' W8 j
        m_dwActivePlayerDataCount--;</P>$ o; s; {. x1 Q+ P
    <P>    UnlockPlayerData( pPlayerData );
    0 x! R. \0 o7 @1 U# a& D2 v    m_PlayerDataListLock.Leave();$ b5 t: q" a; m% q/ O, `: K7 {( Z
    }</P>* [/ f  h' G( m* Y8 [( E+ o2 V
    1 I! j9 N: o  \' F3 Y
    <P>, \, Q& K" ~* o5 ]
    //-----------------------------------------------------------------------------
    # d8 j! P5 h! q9 @// Name: 4 B! G) f; ]) f
    // Desc: 2 A) ]+ W: v& y! J6 ~; \2 G1 X# e3 K
    //-----------------------------------------------------------------------------! Z4 Q" N% z: }" t6 v* t
    void CMazeServer::RemovePlayerDataFromCell( PlayerData* pPlayerData )' B8 X% C" o6 a. x) y- b7 Q
    {8 {' `3 ]+ c4 T: G' H' q
        // Lock the player
    0 R+ |$ l( F- d0 H4 F5 w( ~    LockPlayerData( pPlayerData );</P>
      x/ f& ?7 F, r7 H  q<P>    // Lock the cell the player is in% \5 v! C6 F3 X) s# {/ e
        ServerCell* pCell;
    % V9 ~  C1 a% L0 y1 ?8 Q, C# u  c) U  p- g    if( pPlayerData-&gt;wCellX == 0xffff )( q8 x8 k6 G* Z& `! S8 {+ Y
        {
    / G+ X: z* ]  t# U0 v. v2 ]+ }        m_OffMapLock.Enter();- b: _: f) j  ^9 x0 l& t
            pCell = &amp;m_OffMapCell;- i2 u5 ]7 L$ [. Z+ I
        }6 ]/ g7 N2 a/ O, V  h5 X
        else
    1 G: ^& I- z) l5 R- ^0 g/ P( O    {: ~/ j9 r$ G, K7 V4 v& S
            LockCell( pPlayerData-&gt;wCellX, pPlayerData-&gt;wCellY );
    * F- F' `9 ?; ~& A5 c# j+ X" v, m        pCell = &amp;m_Cells[pPlayerData-&gt;wCellY][pPlayerData-&gt;wCellX];+ I$ M3 r; ^2 F9 Z! g0 a
        }</P>
    ; A/ P8 Z/ O, g: J<P>    // Remove it from the cell
    & [4 J; t1 e+ k- ~# a    PlayerData* pPt = pCell-&gt;pFirstPlayerData;
    2 [/ w* u* j+ x. {    PlayerData* pPrev = NULL;! m8 _6 K. I# G  |# N) D' C
        while ( pPt )
    - q, D+ S: R# _5 u* q9 T4 @    {
    3 Y! Y" E5 s( r8 [) |        if( pPt == pPlayerData )5 i& M/ M- A- \) {
            {( c9 g7 _4 r7 g+ l1 u- I% L
                if( pPrev )( A5 m  k4 L0 Q) N& D
                    pPrev-&gt;pNextInCell = pPlayerData-&gt;pNextInCell;3 [. k* N) M6 Y1 x- }, e6 P! [
                else
    6 x* H* H  t& U; ^5 i  G                pCell-&gt;pFirstPlayerData = pPlayerData-&gt;pNextInCell;</P>
    / ]2 V, G; n7 ]7 b. B# y" N<P>            pPlayerData-&gt;pNextInCell = NULL;
    % M& z1 I* L( D5 z- I6 E            break;9 K+ Y& j9 d0 F6 X: r0 M4 T
            }3 V. v  y( p8 h
            pPrev = pPt;
    5 a9 f/ J. G" I0 _0 H, s7 u        pPt = pPt-&gt;pNextInCell;) U. U4 F+ v% b# i8 w0 ~/ `
        }</P>
    , ]/ u2 N( O2 B. ]+ |<P>    // Unlock the cell& n, M- M+ T# M+ J
        if( pPlayerData-&gt;wCellX == 0xffff )
    ' l# i* q5 {/ B  l& T+ t        m_OffMapLock.Leave();
    & c( M$ W: R, k& Q( A    else
    0 ?# a  i1 I0 Q( e. ~        UnlockCell( pPlayerData-&gt;wCellX, pPlayerData-&gt;wCellY );</P>
    8 w& p6 Z, P! U* C& N<P>    // Unlock the player$ [9 l9 r- u/ Y9 ~
        UnlockPlayerData( pPlayerData );
    5 [! k8 b4 m$ j+ P  C3 T1 `}</P>
    & a: C" i) K9 c+ p9 A3 J' K( M' ?, i2 i* |8 M! x
    <P>
    ( d" ]. d/ |8 J% D//-----------------------------------------------------------------------------
    3 o' a- y$ X) a+ f% P8 R" R// Name:
    ; Q( x* I- a: f& n5 x1 K// Desc: 9 m& X9 `1 i! R
    //-----------------------------------------------------------------------------! Z' O5 y& W+ C5 }  a0 _2 i  l1 K5 F
    void CMazeServer::UnsafeRemovePlayerDataFromCell( PlayerData* pPlayerData )0 t. }- c* l! O8 _3 @  \: ^
    {
    ( y5 I- j5 C  e/ w    ServerCell* pCell = GetCell( pPlayerData );
    ) q! H% I; C5 Q, E" w    PlayerData* pPt  = pCell-&gt;pFirstPlayerData;
    4 W5 k) z1 U% u: {: `' ^( ^+ T    PlayerData* pPrev = NULL;
    # A. F% w6 X3 j7 }- ?    while ( pPt )
    + g. u: F8 {8 l% n, G, a    {
    ! Y# x" Z1 x1 t: ^2 U, h( G# k        if( pPt == pPlayerData )
    , K9 j) w" z8 M. q3 ]6 b4 X        {0 W* D6 M! f3 c: c' o0 q
                if( pPrev ): E2 Z  W: }5 L
                    pPrev-&gt;pNextInCell = pPlayerData-&gt;pNextInCell;
    , l# z3 h( \4 F, \3 v2 S            else) ?8 K+ s) g( y# Z2 C
                    pCell-&gt;pFirstPlayerData = pPlayerData-&gt;pNextInCell;
    * F6 L  k, J6 @0 y5 y# d# d2 c            pPlayerData-&gt;pNextInCell = NULL;
    + V* T6 w. o1 `7 i( a            break;
    5 \" v+ U7 j- d        }$ g9 J& i" g, k" K5 C! O5 b; ?
            pPrev = pPt;
    ' v! y& E( Q: m! e  ]5 J3 j) t; g        pPt = pPt-&gt;pNextInCell;$ O4 o5 N3 N( n
        }9 J) k8 v1 |! U1 U) W
    }</P>0 ^- m* r0 ]" ~7 w- e

    8 |! Z' T3 R9 D" y<P>
    ) U3 [' X) o2 z1 V7 y+ D//-----------------------------------------------------------------------------. b: Y2 s; P  e3 G3 p
    // Name: 8 T; |; @( x+ H; h- R) {( Q: |0 W
    // Desc:
    / m' S* y5 Q. l4 ^: J//-----------------------------------------------------------------------------
    ; n* ]1 Q5 k7 Z: u9 @void CMazeServer::UnsafeAddPlayerDataToCell( PlayerData* pPlayerData )! q. z& U2 b$ P) e0 M1 Q! _4 |. I
    {
    ) u+ Z4 Y7 B9 ^: u5 C    ServerCell* pCell   = GetCell( pPlayerData );% `. i8 s3 U, H$ P, b' `3 n
        pPlayerData-&gt;pNextInCell = pCell-&gt;pFirstPlayerData;" l4 R7 B2 ?" R. e0 i
        pCell-&gt;pFirstPlayerData = pPlayerData;
    # l& n- L( V. v- Z: G2 \}</P>
      {) q8 l$ m- j9 u( M" v
    6 |3 h+ Z5 Z0 o% Q! ?* u. t1 Z2 m<P>% l! D# t* |$ Z
    //-----------------------------------------------------------------------------7 n1 q$ ]  g4 l# f( b
    // Name:
    ! G6 u- k2 n8 W+ }9 Y& E// Desc:
    * Z9 ~4 b/ S2 ?1 z& _//-----------------------------------------------------------------------------: G0 O" d- ~* z* L3 ^
    void CMazeServer::HandleClientPosPacket( DWORD dwFrom, ClientPosPacket* pClientPosPack )
    & K# r* v% j. s2 q! q{
    % r7 D# z) ?! [" S    // Grab player for this client and lock it5 i0 u; F; J, h# Q/ p
        PlayerData* pFromPlayer = GetPlayerDataForID( dwFrom );
    - ?/ _9 V: g; j6 @: ^: o* K    if( pFromPlayer == NULL )
    , V6 _3 }1 Q. i* T6 D' V    {
    + o; r7 e2 g7 L/ g" h& {        if( m_dwLogLevel &gt; 1 )) c3 L+ r8 e7 m# Z( b$ A5 t& R* D
                ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Could not find data structure for this player"), pFromPlayer-&gt;NetID );1 @6 m6 I5 f0 d9 B
            return;
    . d  l  @# N  s4 c9 ^5 {2 p! H    }</P>1 I7 f/ `* x8 B, H+ g5 N' U) e. f; j
    <P>    LockPlayerData( pFromPlayer );</P>7 Y6 x' B1 R& |  r, d8 A
    <P>    if( FALSE == pFromPlayer-&gt;bAllow ). t, W8 \4 S% f0 a$ c( s& C
        {7 Q" |2 T0 ]: {' |# o
            if( m_dwLogLevel &gt; 0 )8 I' o- S# Q6 K5 S$ D3 b
                ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Got position packet from bad client.  Rejecting client"), pFromPlayer-&gt;NetID );</P>
    , b. ]- _- N0 M( c6 H<P>        m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );
    3 k5 B2 F" P3 ^3 b3 e( H1 z; t        UnlockPlayerData( pFromPlayer );
    + b* i  C) X8 z! I3 l        return;. h; T& y" [) Z
        }</P>
    2 F* k: o4 J* n0 B<P>    // Compute the cell the player should be in now
    8 E' A* }+ ?1 G# u( D% r    DWORD newcellx = int(pClientPosPack-&gt;fX);
    $ U* Y. q& i; t5 Q3 r. R    DWORD newcelly = int(pClientPosPack-&gt;fY);
    : ]6 R' R$ q1 J( ?+ ]# l6 b: O7 S    DWORD oldcellx = pFromPlayer-&gt;wCellX;$ a  j: [( d3 _% i
        DWORD oldcelly = pFromPlayer-&gt;wCellY;</P>
    . l; V5 a8 `0 N2 i0 ~<P>    // Have we moved cell?7 {, a  X$ V2 @) O5 c! Z! ?' ]7 p
        if( newcellx != oldcellx || newcelly != oldcelly )/ U% c' k9 o5 ?
        {8 E" R( A# g# Z3 K8 u8 X
            // Yes, so lock the pair of cells in question5 p, b2 H" N' h* b9 l  c
            LockCellPair( oldcellx, oldcelly, newcellx, newcelly );</P>
    # {, S6 s( h, U  Y  x$ K" F' K<P>        // Remove from old cell and add to new cell5 K4 V# t* I7 w6 M
            UnsafeRemovePlayerDataFromCell( pFromPlayer );2 o8 x& d$ U7 f
            pFromPlayer-&gt;wCellX = WORD(newcellx); pFromPlayer-&gt;wCellY = WORD(newcelly);
    : u9 K% J( p1 C* _. p0 k3 I        UnsafeAddPlayerDataToCell( pFromPlayer );</P>
    ; ^! Z2 ^* [. n<P>        // Unlock cells5 C% V* O! |$ i
            UnlockCellPair( oldcellx, oldcelly, newcellx, newcelly );, E& E  X/ F! L+ K4 ], t/ z
        }</P>8 v+ n$ U# T7 l6 P8 A, j& r  l
    <P>    // Update player position
    % ^  N0 \/ H! F( M' D2 b' \' ]    pFromPlayer-&gt;fPosX      = pClientPosPack-&gt;fX;- M- B; `5 }) r) J: J+ ~6 r
        pFromPlayer-&gt;fPosY      = pClientPosPack-&gt;fY;
    , N: c, N4 c) ?  a    pFromPlayer-&gt;aCameraYaw = pClientPosPack-&gt;aCameraYaw;</P>
    ) A4 Q) d3 T' S1 E5 r9 F- g. j/ O<P>    // Allocate space to build the reply packet, and fill in header
    9 u& q/ j* a# f" D    DWORD dwAllocSize;
    ! I) z; f( Z! G    ServerAckPacket* pSvrAckPack = NULL;</P>" ]% U. ^& _! |2 A- R" c
    <P>    // Begin by allocating a buffer sized according to  }2 N# L% w& O: M6 o" |+ a! e
        // the current number of nearby players + 4.  This will give ( W$ J& a1 S7 Y" T
        // a little room for more players to come 'near' without resize
    0 k' X* ]  V- r5 U    // the buffer.
    " `4 m' C$ U' g$ f$ O4 C1 J    DWORD dwMaxPlayerStatePackets = pFromPlayer-&gt;dwNumNearbyPlayers + 4;</P>
    7 _0 c  B8 e8 G/ d: t<P>    dwAllocSize = sizeof(ServerAckPacket) + dwMaxPlayerStatePackets*sizeof(PlayerStatePacket);' f% h+ X# D+ b' s# `6 |0 X
        pSvrAckPack = (ServerAckPacket*) realloc( pSvrAckPack, dwAllocSize );
    & P6 U8 `+ R; J  V* D    if( NULL == pSvrAckPack )! K" A# u* l  D2 l9 j% W7 J8 x# k
        {
    7 S: ?4 J! A$ y0 `        // Out of mem.  Cleanup and return
    . y: G3 e: d3 {5 @9 j+ B' i# J! h) b        UnlockPlayerData( pFromPlayer );
    / ]5 c0 T3 ]( [8 v4 W5 ?& a' i        return;       , n) W7 \( P/ K' q9 t. L; n
        }
    ) B# v2 l$ K" e# x* T3 X    ZeroMemory( pSvrAckPack, dwAllocSize );</P>
    9 X' x" E6 O# w6 W<P>    *pSvrAckPack = ServerAckPacket(m_dwPlayerCount);
    ! Z/ t& N1 _( P0 z8 A! {9 c/ L    pSvrAckPack-&gt;wPlayerStatePacketCount = 0;
    % ?5 z* j* o# ]7 o    PlayerStatePacket* pChunk = (PlayerStatePacket*)(pSvrAckPack+1);</P>1 ?+ g- {7 j* E5 P- m& n
    <P>    // Compute range of cells we're going to scan for players to send8 X  W0 e8 h: \) C$ ~
        DWORD minx = (newcellx &gt; 7) ? (newcellx - 7) : 0;; U# |/ h( c+ `/ G3 k$ G
        DWORD miny = (newcelly &gt; 7) ? (newcelly - 7) : 0;% O* W, X5 ]2 b; m; A/ }- f& S
        DWORD maxx = (newcellx+7 &gt;= m_dwWidth) ? m_dwWidth-1 : newcellx+7;
    " x# }( W6 n, K, M    DWORD maxy = (newcelly+7 &gt;= m_dwHeight) ? m_dwHeight-1 : newcelly+7;</P>8 r* D/ R% l. \2 H
    <P>    // Lock that range of cells( l" T1 W2 ~  l
        LockRange( minx, miny, maxx, maxy );</P>
    * B6 O# E! W5 D! Q! A<P>    // Scan through the cells, tagging player data onto the end of* s* |) G4 \8 a% \* K8 T; s
        // our pSvrAckPacket until we run out of room
    " n8 a$ h* s# M" B8 B3 T  x    for( DWORD y = miny; y &lt;= maxy; y++ )- F, O4 {) ^8 ?: g. r2 i
        {- G( P# J! ~/ s7 o- M. C
            for( DWORD x = minx; x &lt;= maxx; x++ )
    / j7 I/ O5 p5 O" w2 y3 ]% ^        {
    - A9 o% h5 e% _0 \            PlayerData* pCurPlayerData = m_Cells[y][x].pFirstPlayerData;6 ^1 a. H) T4 U$ q* f' ?- x
                while ( pCurPlayerData )6 e& |+ g6 x: G, K+ j$ I
                {, L! g) ]. m1 p2 \
                    if( pCurPlayerData != pFromPlayer )) Y# @% ~/ H0 L2 a1 o7 K. q& u" W
                    {. X4 Q! Z8 P' B; s) f
                        if( pSvrAckPack-&gt;wPlayerStatePacketCount &gt;= dwMaxPlayerStatePackets )5 e) \; |0 C# `! Q6 M
                        {; e$ L$ T* m; D5 Y$ R! W
                            // Make sure pChunk is where we think it is
    7 V) {6 i: T7 }6 {3 y% l9 ]                        assert( (BYTE*) pChunk == (BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket)) );</P>
    ( A9 d8 W3 y$ N; m3 A/ N" n<P>                        // There are more than just 4 new nearby players, so resize the $ n7 R2 h+ x3 r
                            // buffer pSvrAckPack to allow 16 more PlayerStatePacket's.
    : H0 A; t9 v5 b6 A                        dwMaxPlayerStatePackets += 16;
    7 W8 _' n+ ~# @$ J                        dwAllocSize = sizeof(ServerAckPacket) + dwMaxPlayerStatePackets*sizeof(PlayerStatePacket);
    7 h) F" R6 ?, Q5 j                        ServerAckPacket* pNewSvrAckPack = NULL;
    + q3 P3 n9 l. h                        pNewSvrAckPack = (ServerAckPacket*) realloc( pSvrAckPack, dwAllocSize );6 t, b9 ?: c: y1 E  @
                            if( NULL == pNewSvrAckPack )- n! A; G" @2 z, M' A* W1 N) O6 P/ \
                            {
    2 v) {5 I. G% S$ a  r                            // Out of mem.  Cleanup and return* B6 p9 A' X6 _- R
                                free( pSvrAckPack );8 f# U2 ?1 r. }3 j: M* C2 v, y0 U! c& p
                                UnlockRange( minx, miny, maxx, maxy );
    ( }7 p2 `/ D2 [                            UnlockPlayerData( pFromPlayer );7 w  N! y0 D8 z) ~/ f9 C: v
                                return;      
    8 E# x& N7 ~! `9 \) m                        }</P>& @) H4 a! x$ l0 f& e5 w, o( z4 ?( b
    <P>                        pSvrAckPack = pNewSvrAckPack;$ \! F% m) B& J7 F3 ^6 w
                            pChunk = (PlayerStatePacket*) ((BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket) ) );</P>2 H( x/ _; o# ]
    <P>                        // Make sure pChunk is still where its supposed to be& U) C; p& [- m3 [% E  ~( `
                            assert( (BYTE*) pChunk == (BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket)) );2 `$ d  G( g1 J2 G" k
                        }</P>
    ' r* P! V" g2 M7 |: z% s% I6 V<P>                    pChunk-&gt;dwID       = pCurPlayerData-&gt;dwID;% B3 A0 k" \; J& U, p9 j8 ^- u5 Q, E
                        pChunk-&gt;fX         = pCurPlayerData-&gt;fPosX;8 ]3 i( \4 d- a9 T& t) D
                        pChunk-&gt;fY         = pCurPlayerData-&gt;fPosY;9 u4 Z% A" h/ a( K9 I
                        pChunk-&gt;aCameraYaw = pCurPlayerData-&gt;aCameraYaw;
    5 K  n$ Z7 A. i. t5 i                    pChunk++;) F  ^: W2 t4 U, r+ K" I6 J/ ]
                        pSvrAckPack-&gt;wPlayerStatePacketCount++;: ~) A, `' e- v1 w  B# i
                    }. O! M7 o! u/ @! R! X# u, R) ^2 D
                    pCurPlayerData = pCurPlayerData-&gt;pNextInCell;
    ! Y) E! B# Z/ {  M! ~            }
    3 M2 m0 L; K- R9 }  i; H        }
    * N, n/ m+ M9 [. E6 h# n    }</P>
    % E9 Z7 y  I; i3 r. z8 J7 Y8 l; t<P>    // Update the dwNumNearbyPlayers for this player
    4 s7 j5 u% K# y+ a    pFromPlayer-&gt;dwNumNearbyPlayers = pSvrAckPack-&gt;wPlayerStatePacketCount;</P>" S% N( o- @$ Q
    <P>    // Unlock range of cells9 t& y$ [8 |2 G3 t
        UnlockRange( minx, miny, maxx, maxy );</P>
    ! w( g1 {5 E0 c4 f$ e& P5 w! R<P>    if( m_dwLogLevel &gt; 2 )/ D8 w3 _; y/ O, X8 R( F
        {3 m1 }0 V* y! B3 B+ z8 C
            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Position is (%0.2f,%0.2f)"), pFromPlayer-&gt;NetID, pFromPlayer-&gt;fPosX, pFromPlayer-&gt;fPosY );
    8 D5 B3 _, f4 ^8 b1 K    }
    8 S6 M9 ?7 l7 }" o/ e8 M    else if( m_dwLogLevel == 2 )
    * i) U! J* F0 r    {
    ! U6 S3 J& e: Y) L        FLOAT fTime = DXUtil_Timer( TIMER_GETAPPTIME );( }2 N$ j  n- K& e2 a/ \$ S
            if( fTime - pFromPlayer-&gt;fLastDisplayTime &gt; 60.0f )* Y- _# B9 j. V* ]& q
            {* J# D3 o& F% `$ I4 |+ |. M! B5 q
                ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Position is (%0.2f,%0.2f)"), pFromPlayer-&gt;NetID, pFromPlayer-&gt;fPosX, pFromPlayer-&gt;fPosY );
    , k$ e* i6 E* {9 O) }+ {. Y            pFromPlayer-&gt;fLastDisplayTime = fTime;
    ! F& |1 K7 T  b! {        }
    % ^1 F* i5 t, D. M% T    }</P>
    $ Q# e' {! K! k/ n; W<P>    // Unlock the playerdata
    7 ?# ]/ G) ^/ N/ P" T: P    UnlockPlayerData( pFromPlayer );</P>
    * [1 Z" S# K/ U6 {! [  g6 U. r6 u<P>    // Send acknowledgement back to client, including list of nearby players
    ) Z6 y& o1 c/ T$ M    DWORD acksize = sizeof(ServerAckPacket) + (pSvrAckPack-&gt;wPlayerStatePacketCount * sizeof(PlayerStatePacket));: r$ k: _+ {! b( r5 H
    " r( ~3 x. u1 X" _
        // Pack the buffer with dummy data.* [5 J( I8 x" A' n
        if(m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex] &gt; 0)
    : U; ^" H( O- [$ ^" n: J- f! I    {, @! d7 Y% P9 h4 }. j; F
            DWORD   dwBufferSize = acksize + m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex];
    9 c$ o3 C" n  }/ g" v( p        VOID*   pTempBuffer = 0;</P>
    1 x6 f: b) X% i7 R8 D<P>        pTempBuffer = malloc(dwBufferSize);1 s( Y8 ^) i+ h4 i" N: Z( a% k! h' R
            if( NULL == pTempBuffer )
    $ f8 ~4 O" w" |/ ~        {
    ; G7 N4 F7 v" }/ l# ~            //Out of memory, [" f; q# t1 Q- I; R
                DXTRACE_ERR_NOMSGBOX( TEXT("System out of Memory!"), E_OUTOFMEMORY );
    6 D3 o& B+ G9 u) j; e, h6 ~' v1 _            free( pSvrAckPack );
    2 O7 e* f1 A5 f2 x            return;" z* b- e) Y* X# G, C
            }</P>
    , g! ]% O: P; W3 G5 d$ G& |5 W<P>        FillMemory(pTempBuffer, dwBufferSize, 'Z');, `5 X* x! r* R2 M4 b
            memcpy(pTempBuffer, pSvrAckPack, acksize);</P>6 J9 _- E5 b& Z! g
    <P>        SendPacket( dwFrom, pTempBuffer, dwBufferSize, FALSE, m_dwServerTimeout );/ b, }1 y4 \) u
          D0 q- A" g8 k; X0 G" Q
            free(pTempBuffer);
    5 C0 T  G" T6 B0 C    }   3 K" E% a6 Y9 {# b
        else; F7 z* Q0 J1 o+ w# F& s& d6 r
        {* M5 ^3 E) X! g' ^2 h  [
            SendPacket( dwFrom, pSvrAckPack, acksize, FALSE, m_dwServerTimeout );( p% ]& m( m5 [* {
        }</P>+ R: k$ b5 h) d% o; u6 p
    <P>    free( pSvrAckPack );</P>
      l! L5 d# q) T<P>}</P>- ?* r4 u8 D& K8 Q+ {* V
    7 o8 z1 a- C  C+ w, K7 W
    <P>" k: i: ~  l% V4 q
    //-----------------------------------------------------------------------------6 b- x7 @* l2 }# f0 ]' Z, h; f
    // Name: ( [( j9 E8 _4 W$ [! D8 c
    // Desc: ) T" y- u4 ]8 `" Y+ x
    //-----------------------------------------------------------------------------& |9 }  W# i8 u# G* N
    void CMazeServer::HandleClientVersionPacket( DWORD dwFrom, ClientVersionPacket* pClientVersionPack )
    1 r/ g2 ]% z3 s$ q{. p. X+ }5 {1 G* R8 G
        // Grab playerdata for this client and lock it8 b+ @: P! @+ N( W
        PlayerData* pPlayerData = GetPlayerDataForID( dwFrom );
      ?& \; P0 I5 T7 Y! a4 I, r* P1 e, Z! l    if( pPlayerData == NULL )
    0 B! |, X6 h+ l4 C7 ^" M        return;
    ( j4 V8 e9 {& e5 i. o+ i    LockPlayerData( pPlayerData );</P>9 I6 q3 j2 D7 T+ d# v
    <P>    // Record the version number $ e  z. F7 T+ ~. I$ Y
        pPlayerData-&gt;dwVersion = pClientVersionPack-&gt;dwVersion;</P>
    * F$ W4 g6 p, o. Q<P>    if( m_bLocalLoopback ), _- `; M9 a$ t' ?4 F
            pPlayerData-&gt;bAllow = TRUE;
    0 A% l, y9 T0 R* z, e' K8 R    else% C- |' G* S2 I0 p. D
            pPlayerData-&gt;bAllow = IsClientVersionSupported( pClientVersionPack-&gt;dwVersion );</P>
    $ e( X8 }! a- o/ S<P>    if( m_dwLogLevel &gt; 0 )/ V- b( ^+ P$ I' V3 Q
            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>. L7 {0 N8 m2 G6 o! s- \
    <P>    if( FALSE == pPlayerData-&gt;bAllow )6 @# s; q) b. C( m# H% P! A) C
        {
    8 C, `5 U( s/ G  l        if( m_dwLogLevel &gt; 0 ): C7 K# k- d# m- X+ A! Z$ d% L3 |( \
                ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Rejecting client"), pPlayerData-&gt;NetID );</P>6 h# o! P% T! h
    <P>        m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );4 C% ]; V2 T  S; q/ P* i' {" M! X% I
            UnlockPlayerData( pPlayerData );" z6 e7 g% _% q
            return;
    " ~5 T; R3 c2 @6 J5 j% q    }</P>, ], \) C7 @5 e9 C/ _4 N: ]& p  ]9 m
    <P>    // Unlock the playerdata8 l  l( z% \" Y
        UnlockPlayerData( pPlayerData );</P>. i8 }3 ]5 S. s
    <P>    // Send acknowledgement to client that the client was either accepted or rejected3 w+ Q% X1 l* D) j7 H& E
        ServerAckVersionPacket packet( pPlayerData-&gt;bAllow, dwFrom );+ S- N. w: n, e- [% w# H
        SendPacket( dwFrom, &amp;packet, sizeof(packet), TRUE, 0 );
      O1 V2 i' u& n# T$ d6 C, _, N% o}</P>
    8 d* N. k0 n4 z% a' A5 U/ r7 Y" g' F; j
    <P>' K0 y+ ?, o+ u4 n" o
    //-----------------------------------------------------------------------------
    : K3 I8 O- Y  \" @3 ~! |// Name:
    2 e- J9 {: Z' u9 ?4 K5 {// Desc:
    2 l" B8 l$ n" v9 {5 h//-----------------------------------------------------------------------------" X! h$ V; o0 h( z
    BOOL CMazeServer::IsClientVersionSupported( DWORD dwClientVersion )
    * S$ U! B: \- Y1 ^. z) K{$ v. m6 L& ~" p* I* s9 c7 V. Q
        switch( dwClientVersion )6 c% U$ @) w) O9 W
        {
    & m2 s& u: ~2 i, H        case 107: // only v107 is supported
    # c; J' O+ S  m, E3 s+ [/ a) F; ?8 @            return TRUE;, F5 B6 L; F5 x! V  f. r
            default:& r( h+ G5 |9 m  d
                return FALSE;
    $ ~+ M- L$ s% T+ h) d    }
    . u  h' I+ Z5 }7 y' U9 n' l$ E}</P>
    $ k0 e" j0 ?) m* n
    % E2 A* S' e' H6 s# ]<P>, j; Z* u+ Q# D3 Q0 @, ~( j( |9 O
    //-----------------------------------------------------------------------------
    / ]& ?9 T8 D; t: Y: a// Name:
    , ^4 B9 u" Y' H; n// Desc: $ H6 u( J. L# {) X
    //-----------------------------------------------------------------------------* Y) e8 x% c6 h0 d2 _
    void CMazeServer::HandleUnknownPacket( DWORD dwFrom, ClientPacket* pClientPack, DWORD size )
    4 i+ z& T6 |6 Q$ |! {  k  x{
    # i" b1 ~, O/ x) d    if( m_dwLogLevel &gt; 1 )9 e8 n1 A. `, h2 H  O' D" j0 y# ~
            ConsolePrintf( SLINE_LOG, TEXT("ERROR! Unknown %d byte packet from player %0.8x"), size, dwFrom );</P>( U7 @0 L) s2 J  A- X, C6 Z: t2 x
    <P>    m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );
    9 {, ?6 K- E, H+ B# {7 ^! Y: Y}</P>. i; E' J/ i3 a' W) F6 z
    & H! [' i8 o. u: q2 o( m/ }( n
    <P># |3 i6 ~& b: O' d' n! P- f% G" @7 Z
    //-----------------------------------------------------------------------------
    . F  o4 ~# x* ]8 e2 Q( M, Q// Name: : [* y$ M+ e! D( q: c0 G
    // Desc:
    ; d; J0 y2 \0 p4 g. p//-----------------------------------------------------------------------------
    , u4 N0 g5 a9 L) F# `- XDWORD   CMazeServer::IDHash( DWORD id )4 y# R6 r% \+ r. M+ R( c
    {. R8 L2 G# R; Z/ \1 r$ v) v
        DWORD   hash = ((id) + (id&gt;&gt;8) + (id&gt;&gt;16) + (id&gt;&gt;24)) &amp; (NUM_ID_HASH_BUCKETS-1);- `5 G$ f" l/ X% N6 t% K
        return hash;
    * A( f# a  V( z9 [, H0 R  y6 b}</P>! t% h/ ~! M# F% h. B# \
    4 W  ~; I4 o. P; c& I$ W
    <P>
    ! r- P8 F" o$ B6 p3 F//-----------------------------------------------------------------------------' W' o) d3 e, T4 C, Q& {
    // Name:
    & Z5 s$ V) k# D& E9 c// Desc:
    3 r+ R- E1 k/ F8 X. [9 z$ R//-----------------------------------------------------------------------------
    3 C9 `& `# w. B; C# ^9 v4 v8 X, Svoid CMazeServer::RemovePlayerDataID( PlayerData* pPlayerData )
    ) q$ t0 J7 X5 b1 O{# [7 }7 ^1 p) q6 }! w
        // Hash the ID to a bucket number
    , N7 s! n' Q" ?    DWORD   bucket = IDHash( pPlayerData-&gt;NetID );</P>
    ; b/ a. l0 t3 k( S/ \<P>    // Lock that hash bucket/ ~( M% H* u- j. h9 O) V$ _
        const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;
    4 j* S0 P* t, I* Y4 Z* t1 \8 g    m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>
    2 g$ N  r& ?) {- M; a/ h<P>    // Loop though players in bucket until we find the right one% w" U* r9 I) N9 ^$ J+ X
        PlayerData* pPt = m_pstIDHashBucket[bucket];
    3 |8 r( K. q/ ?( O% w    PlayerData* pPrev = NULL;
    + A* \+ S# B+ Z1 W. g0 \9 A/ y1 b( _    while( pPt )6 x3 K( n. o5 ?5 y) S) E9 d- ]' \+ X% @
        {1 F* B1 ?# e; x1 w' D
            if( pPt == pPlayerData )
    ) F( S4 L$ ?3 P            break;9 N4 b/ \& b# W7 s: r5 Y, B' ^
            pPrev = pPt;
    3 b; @+ O! B! J( l2 |: i0 W7 q' t7 R        pPt = pPt-&gt;pNextInIDHashBucket;
    % X6 s+ b$ e) `! `7 ]: U. h    }</P>2 ~. Z* G1 O5 V9 |6 K2 P
    <P>    if( pPt )6 `2 z& \2 H, P0 N2 X
        {
    " ^0 q$ O8 H# F, t        if( pPrev )" f0 v5 U3 a* T2 a5 ?
                pPrev-&gt;pNextInIDHashBucket = pPt-&gt;pNextInIDHashBucket;
    & i7 r7 |: y4 l! Z+ T' J* |2 f        else
    . a7 x3 T' @$ P' x' h            m_pstIDHashBucket[bucket] = pPt-&gt;pNextInIDHashBucket;
    - w+ C" E' S8 h/ p3 g: M: {/ q        pPt-&gt;pNextInIDHashBucket = NULL;0 g' Q* S/ @5 ~5 V
        }</P>
    & v5 y9 z1 u$ T9 |% R' ?/ r) v<P>    // Unlock the hash bucket
    8 I  b: f! R  s8 V5 ]- M; G    m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();, ~  @6 g/ M1 X
    }</P>
    : l* V3 N6 F# |; r  k9 E
    ' p- g, L* ]+ b<P>" n2 S% w- n! p3 S- e5 Y  d6 v, r5 N
    //-----------------------------------------------------------------------------
    6 m* p- a, [. \9 E# ^9 m// Name:
    . P! z5 ^2 D) I0 G! n% {' J// Desc: / m/ H/ D1 d: J1 Y  ]
    //-----------------------------------------------------------------------------
    ! F9 ]3 W6 U* `1 Q, m9 F9 jvoid CMazeServer::SetPlayerDataForID( DWORD id, PlayerData* pPlayerData )
    5 h: w1 R* q& u{
    ( Q1 u/ e4 h# V+ X, R% N8 ^    // Make sure this player isn't added twice to the m_pstIDHashBucket[]' P' f  ~8 A2 a. j1 T' f9 _
        // otherwise there will be a circular reference$ x6 Y% B) y! Q$ `9 Z& w* ]  q
        PlayerData* pSearch = GetPlayerDataForID( id );
    4 T5 V9 B6 d& ]) ~! ^5 h& C2 v    if( pSearch != NULL )& P. m. |. Q) B! ^1 `
            return;</P>4 c/ s" f# f* j: H, h) o3 ^; @0 ]
    <P>    // Hash the ID to a bucket number
    9 U! {( \. l/ s: ^4 a    DWORD   bucket = IDHash( id );</P>/ I6 P' G6 H6 W8 |
    <P>    // Lock that hash bucket" q8 F. L6 B3 W4 T7 E1 r" l  n
        const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;
    3 i/ p9 F* U& r8 _2 \0 \' j+ k    m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>5 {# F. e+ r- t& [: v1 u
    <P>    // Add player onto hash bucket chain
    : I/ E( L2 E0 \& A4 S6 {    pPlayerData-&gt;pNextInIDHashBucket = m_pstIDHashBucket[bucket];& w+ A% T) O) ]1 l9 I+ J
        m_pstIDHashBucket[bucket] = pPlayerData;</P>: y. i- g& b& Q# G: q4 O
    <P>    // Store net id in player
    : I3 v! e8 R& k4 `$ {5 X* f    pPlayerData-&gt;NetID = id;</P>9 Y# `2 L) Z( ~% u5 Q
    <P>    // Unlock the hash bucket' R: j" G! u: m/ `
        m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();3 j; J2 ]* w4 D3 I1 j
    }</P>
    + Y% [/ U3 l. P" w
    # S9 O& l% i6 T3 R: }8 N5 p<P>
    & M2 j: \0 S5 Q- t! T. e8 w//-----------------------------------------------------------------------------* X8 W/ v. L. e
    // Name: ) [2 Y& o5 I7 n8 X
    // Desc:
      A' F4 [2 U+ f! m; H! ^6 t' v//-----------------------------------------------------------------------------# ^8 n  d: P* ?% d! F& D
    PlayerData* CMazeServer::GetPlayerDataForID( DWORD id )
      P' P- ~- \0 e7 W1 k& P! Z2 h{' x% y* ~* a! R: t8 }3 m: |
        // Hash the ID to a bucket number
    ( d4 ]& Y4 A' i( R    DWORD   bucket = IDHash( id );</P>
    9 k8 ~+ L; Q9 }# ]7 O$ }# B<P>    // Lock that hash bucket
    4 p- S. b# m) ?; \  Q/ V    const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;$ c1 Z5 B  m! T' a- N! V
        m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>
    ' l# F8 M4 V7 @6 ~# c, N<P>    // Loop though players in bucket until we find the right one
    2 r* P% m9 S) F; S6 a9 g: V7 m    PlayerData* pPlayerData = m_pstIDHashBucket[bucket];
    , `, L- f. }9 j    while ( pPlayerData )
    0 v) Q7 N5 a8 F- c. K7 ?    {6 R4 O& y4 G# h6 L- x. V
            if( pPlayerData-&gt;NetID == id )
    * ?0 t- @9 W9 O$ D$ G            break;
    - X6 Z' W9 n  G7 M2 N: g        pPlayerData = pPlayerData-&gt;pNextInIDHashBucket;+ p" W+ w) P6 a' R9 a2 Q7 O
        }</P>
    $ Z9 h( L3 y" |' ^3 ?! |* ]% G<P>    // Unlock the hash bucket
    / H% V, T1 r: q3 T0 Z    m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();</P>
    - [9 ]- R8 p2 c! f3 v/ `<P>    // Return the player we found (will be NULL if we couldn't find it); t( m% o: i  w& ?0 E" U# Y6 J
        return pPlayerData;  A5 F! f+ Y+ t- F, `
    }</P>
      Z# h7 t" O) ?' O1 N, \4 _) \: n% B& e8 m  O! V. ~
    <P>
    % t7 i  A% Z" m$ Y* [6 ]//-----------------------------------------------------------------------------5 ?. b5 m. f! M" Y4 C) i
    // Name: 8 {# @* P" ?* O7 u' h$ P
    // Desc: calls DisplayConnectionInfo for each connection in a round-robin manner8 B# l* M) v( q! W* Z. a! U( f
    //-----------------------------------------------------------------------------
    & _- s& `) ]! Z3 s0 p5 m9 Avoid CMazeServer:isplayNextConnectionInfo()& m& w9 }, A3 k3 `' Y8 F
    {
    ( {: e+ F! L4 [$ S5 O, |7 p4 d    if( m_pNet )- }+ R( z4 |: B1 \& V) U, w
        {3 S7 P$ q' b: ~5 {0 V
            // Find the player that was displayed the longest time ago, and display it.
    ' c0 j$ f( x2 a# J        FLOAT fCurTime = DXUtil_Timer( TIMER_GETAPPTIME );
    ' K% f2 R  U6 S6 _! J        PlayerData* pOldestPlayerData = NULL;- p$ o: a! B- b) ]7 i
            FLOAT fOldestTime = 0.0f;</P>0 R+ c9 H5 W- l# f6 B
    <P>        m_PlayerDataListLock.Enter();</P>
    8 E2 z/ X8 h1 Y! q( H<P>        PlayerData* pPlayerData = m_pFirstActivePlayerData;4 s2 l' h0 n; O
            while ( pPlayerData )0 r1 G3 S$ E  ^* `& K# r
            {$ L+ T2 n: A, L4 ]6 u
                if( fCurTime - pPlayerData-&gt;fLastCITime &gt; fOldestTime )
    2 r& D0 q3 X# W8 L1 u            {6 D! j" P  S  E; b: ~
                    fOldestTime  = fCurTime - pPlayerData-&gt;fLastCITime;5 p* d* B( _8 W) t5 N" X
                    pOldestPlayerData = pPlayerData;6 ?$ @- y/ c% i, U0 q6 h( b
                }</P>
    1 [. h# k; n9 o# N4 u8 y<P>            pPlayerData = pPlayerData-&gt;pNext;
    6 n' Z; E* t2 u, {1 e( c$ N" e/ ^: D        }</P>. p# m. l: R, c) t4 ^
    <P>        // Display the player with the oldest CI field, and update its CI field.
    , [6 p7 p- E4 b2 M/ [        if( pOldestPlayerData )0 n) H" Q9 a: ^$ I  K
            {* }; ?. s6 t) G5 T% L
                ConsolePrintf( SLINE_LOG, TEXT("Displaying connection info for next player") );
    ! z  {* |# D2 n, r            DisplayConnectionInfo( pOldestPlayerData-&gt;NetID );
    " ~, L) k0 ]% U# F- S, A! n            pOldestPlayerData-&gt;fLastCITime = fCurTime;
    : F# q$ @. H, @* H        }
    ( b& ?2 l( x- X* t2 L6 _8 N1 Q  ?        else
    0 _9 R" w  S1 Y# g- H2 w        {' I5 n6 _. m( e. n: r6 F; F, [1 g
                ConsolePrintf( SLINE_LOG, TEXT("No players found") );
    9 R8 h( T; e  V& V% k        }</P>
    8 ?) T1 e3 v) j+ x) W$ P<P>        m_PlayerDataListLock.Leave();% G* n2 ?  S+ u) k% ~
        }0 b. }- i/ H: U+ B# A5 G
    }</P>9 x3 h) A  |7 N3 `: y: k6 w
    8 N, m# u, O5 g& g& v/ M- C
    <P>
    ) T$ Y  o! v; b5 c3 T//-----------------------------------------------------------------------------+ N2 G, d7 E$ T5 `' ^4 H
    // Name: & |6 ]; l, O+ ~8 x' e2 E9 x" U/ r: q
    // Desc:
    : ~/ H, E1 n: [, F! E2 Y//-----------------------------------------------------------------------------* T- {- ~9 c9 ?) \8 M: _
    void CMazeServer:rintStats()5 l# Q: l! N; G  v# y9 o
    {/ {1 N6 n% \+ t6 B  t6 M5 U) T
        ConsolePrintf( SLINE_LOG, TEXT("Thread count: Active=%d Avg=%.2f Max=%d"), & s/ b: K3 N4 H0 e
                                        m_wActiveThreadCount, m_fAvgThreadCount, m_wMaxThreadCount );
    % [2 F; I$ I0 B    ConsolePrintf( SLINE_LOG, TEXT("Thread Time: Avg=%.4f Max=%.4f(s)")," v. a6 s+ a, M  \! q
                                        m_fAvgThreadTime, m_fMaxThreadTime );) P; M0 _# S1 S5 f8 v1 [1 y
        ConsolePrintf( SLINE_LOG, TEXT("Players online (not including server player): %d"), m_dwPlayerCount );
    - x; b8 b( i: A    ConsolePrintf( SLINE_LOG, TEXT("Peak player count: %d"), m_dwPeakPlayerCount );
    % L+ @" D7 j6 {}</P>
    3 x& c$ Q& P* {! f/ q  U
    1 g" U/ f3 D! o5 R- C" I/ p: {  Y7 b<P>
    8 i" p. U, [6 ]/ y4 x) H//-----------------------------------------------------------------------------
    0 V( F- u; Z: b- f0 n+ Y9 U/ n// Name:   H( ~$ n$ U. I
    // Desc: # c5 ]4 _7 C/ w
    //-----------------------------------------------------------------------------
    9 T& V8 }& K- f# B+ N8 uvoid CMazeServer:isplayConnectionInfo( DWORD dwID )
    0 e6 b# V0 s9 d3 J5 n/ {{5 T7 V) V" Y, ~0 \" [- n6 U9 j
        TCHAR strInfo[5000];
    4 ~6 N* N7 F. |0 e$ L; G4 L    TCHAR* strEndOfLine;$ G3 R( p4 |" w7 k3 L* M
        TCHAR* strStartOfLine;</P>
      i! P  G. }9 o<P>    // Query the IOutboudNet for info about the connection to this user4 @# C: A3 ]* l& F5 m
        m_pNet-&gt;GetConnectionInfo( dwID, strInfo );</P>3 h! @9 L* F  [1 M' K
    <P>    ConsolePrintf( SLINE_LOG, TEXT("Displaying connection info for %0.8x"), dwID );. C( X$ T; c! A7 Z& t
        ConsolePrintf( SLINE_LOG, TEXT("(Key: G=Guaranteed NG=Non-Guaranteed B=Bytes P=Packets)") );</P>
    % Q: S- n- U" n/ ~<P>    // Display each line seperately$ k+ o' Q9 w6 V- j2 q2 g4 h8 {
        strStartOfLine = strInfo;
    2 V8 ?  O+ t) ^5 l% o    while( TRUE )
    ( |8 b$ v5 u* p" N, {# B: H    {3 h) U/ i# P4 {7 q
            strEndOfLine = _tcschr( strStartOfLine, '\n' );
    ' m2 @& A: F- s! ^        if( strEndOfLine == NULL )% x! {! x1 z# t9 \
                break;</P>! I/ J4 i" A! ^" Q2 W& Z
    <P>        *strEndOfLine = 0;6 V, u5 Z0 V, e  D, g9 ?% l
            ConsolePrintf( SLINE_LOG, strStartOfLine );
    , M0 p4 c" A( w3 Z( A9 e        strStartOfLine = strEndOfLine + 1;
    + Q% p0 I: B6 M& s5 H" M    }
    - e, ?5 ~3 j! O' Q$ A/ P1 P0 c}</P>% }) b$ S2 D3 L& C5 ~

    7 G5 l7 H3 Q& T2 S7 _<P>0 N1 f4 P) g7 }3 P$ g# f$ K! H/ ]
    //-----------------------------------------------------------------------------
      j% ]3 R3 d( G) g  \! m// Name: ) e! u6 r% ?% w) _- H
    // Desc: ' y" R: H; V8 Q7 a' |$ z7 p/ t
    //-----------------------------------------------------------------------------
    1 |& F2 @- L1 p2 j7 ]' zHRESULT CMazeServer::SendPacket( DWORD to, void* pData,
    - \$ |+ K2 H1 B; }1 f/ F                                 DWORD size, BOOL reliable, DWORD dwTimeout )
    4 |( B+ `0 b, p+ |! E: c4 m  _{
    . [! y' V0 K4 E. g    // Chance of forcing any packet to be delivered reliably; n, b* G# r1 v7 [
        if( m_Rand.Get( 100 ) &lt; m_dwServerReliableRate ). K0 f8 H$ ?' B" |: }# C
            reliable = TRUE;</P>7 R* Z2 @5 w0 G* [1 [4 f1 a" N6 t
    <P>    return m_pNet-&gt;SendPacket( to, pData, size, reliable, dwTimeout );
    - U, P2 ]4 R# ^( O}</P>
    9 X3 o. \7 O$ c  s+ X+ j; @1 |# |
    # @4 x5 q3 b' b1 c" Z+ t<P>) m9 S  c% a2 b8 v
    //-----------------------------------------------------------------------------
    2 j  X, J0 f8 _// Name: ' }, ], X2 i: I: K5 f3 p
    // Desc:
    9 I3 S; }' z- w8 [; i4 n//-----------------------------------------------------------------------------7 D: L; N% b4 I1 U* H5 \' j
    void CMazeServer::SendConfigPacketToAll( ServerConfigPacket* pPacket )7 j! @' z7 j, b) ]: b; D- l! T) }& e
    {% g$ k# N& \/ O. s
        // If we're up and running, then send this new information to all clients) U# b3 _9 u  n4 `9 f
        if( m_pNet )4 ^& W; j) a4 T; x. f
        {
    ) {8 ^, m3 O' B        //Use the AllPlayers ID
    9 a7 o! ]3 r% `! P4 l9 |7 S4 L        SendPacket( DPNID_ALL_PLAYERS_GROUP, pPacket, sizeof(ServerConfigPacket), TRUE, 0 );! K/ `" Y# F9 D" S$ C  ]$ ?
        }1 o- V% I$ S. ~2 g8 {6 |
    }</P>6 B, i. ~# V9 E) f# Q9 h, ?- ?
    " U. {& b# C) H: b3 M7 s* B
    <P>+ X; G4 U" z' Y
    //-----------------------------------------------------------------------------" r* a* A+ ?, V' A0 p
    // Name:
    , L6 F/ B( e1 `, n% B$ a( U! X) f% l// Desc:
    ' l* C" c5 _: Z, \# F( ?: g, Z9 f//-----------------------------------------------------------------------------, H" E7 V* C# v/ J. B' b% U3 ?& D/ v
    void CMazeServer::SetClientReliableRate( DWORD percent )9 a% d( c+ P9 I: Q! _  {
    {
    % @! u7 E  J# d, M' C  p    // Update client config, and build packet containing that data3 M( y, w& l% d- r
        m_ClientNetConfigLock.Enter();
    # C! j* m( V  `    m_ClientNetConfig.ubReliableRate = BYTE(percent);2 w/ {2 q+ u; j7 ?6 P% Z. v0 W
        ServerConfigPacket packet( m_ClientNetConfig );$ n- B; x( j. b. X2 {
        m_ClientNetConfigLock.Leave();</P>
    # ]2 |: K8 U8 R' |% U<P>    SendConfigPacketToAll( &amp;packet );: T" u& R; r$ M' |3 N1 N0 C  t
    }</P>
    9 X' @" m- e: Q" y& u% E4 I  }3 m0 T9 h/ H; s+ k2 _. P1 U. k
    <P>& q  e" J* E( p9 L& U8 D2 l6 m
    //-----------------------------------------------------------------------------
    ) A- F, ]/ A. m' p! ?" a! V// Name:
    6 u1 Q+ Q- @5 I2 I0 e// Desc:
    : Q; g) T9 S( P9 B% O//-----------------------------------------------------------------------------
    , J  E5 |8 u: N0 ivoid CMazeServer::SetClientUpdateRate( DWORD rate )
    ) m! B- G, A5 t% N# X8 f{
    / r: j3 P6 J: P* \0 J    // Update client config, and build packet containing that data2 A5 r, i, h; d' u. s
        m_ClientNetConfigLock.Enter();5 m- I6 l/ B, D" u) X$ _# c
        m_ClientNetConfig.wUpdateRate = WORD(rate);
    & O* \2 M; d; Q    ServerConfigPacket  packet( m_ClientNetConfig );: ~/ W0 `+ y; v/ c% W; B: k
        m_ClientNetConfigLock.Leave();</P>
    ' [  I4 X& J' D) ^1 ?<P>    SendConfigPacketToAll( &amp;packet );4 r1 n" ]; Q0 T$ f" @; f
    }</P>9 P+ k+ E, g/ R
    3 @) Q/ n# S' q/ o; M( I/ N0 d
    <P>
    # \# x3 @; g1 ?& C) l//-----------------------------------------------------------------------------
    3 f% [3 S: A# I5 W& r* a  H// Name: + y8 c- ^3 n$ m9 p* H8 X- x
    // Desc: : m) u# E" a/ a; I! l
    //-----------------------------------------------------------------------------0 Q2 D9 q2 d  {' p, T! ?0 f, h
    void CMazeServer::SetClientTimeout( DWORD timeout )# s$ B0 o4 t, g) T$ v
    {' r. G$ A! p0 b8 [# v& B+ Q/ ~
        // Update client config, and build packet containing that data
    % [2 y- Q2 W, J- n    m_ClientNetConfigLock.Enter();
      V5 h4 S6 e( L8 H    m_ClientNetConfig.wTimeout = WORD(timeout);; F7 |' K$ s" ?5 p4 ^7 U
        ServerConfigPacket  packet( m_ClientNetConfig );1 w$ L0 n  z) U
        m_ClientNetConfigLock.Leave();</P>  U, \: y- l  M( S' J: T9 k( j
    <P>    SendConfigPacketToAll( &amp;packet );4 ?* P/ x3 M4 s
    }</P>" M* Y$ R. ~9 S6 b" X4 h
    " B- K7 K5 r# F3 C! W2 \" e
    <P>
    , B6 U/ S0 G) E( o, d; E& ^! D" F//-----------------------------------------------------------------------------
      R, r+ m6 b. R. H// Name: 3 ^. t- A: N0 H, e  D6 C
    // Desc:
    ' R+ R, X9 d4 _9 i7 g7 Y6 Q' ^//-----------------------------------------------------------------------------
    0 R8 @( ^' h% G( jvoid CMazeServer::SetClientPackSize( DWORD size )
    # A# ~3 u( g7 a9 e* m{
    $ P4 [& F+ H: E  }2 }0 L    // Update client config, and build packet containing that data
    $ r1 ~1 z# e; l7 x6 f, `% {    m_ClientNetConfigLock.Enter();
    # A# r; X+ I- t, W$ g+ H  k; o    ! n6 p' f6 _9 E) Y7 n0 B" r
        m_ClientNetConfig.ubClientPackIndex++; //Increase index and verify location in array.# `, l/ E% J+ Z; N
        if(m_ClientNetConfig.ubClientPackIndex &gt;= PACK_ARRAY_SIZE)   
    % ]' A& x" v* U6 W  k4 \        m_ClientNetConfig.ubClientPackIndex = 0;</P>. P5 }  h. U+ K! l. O/ }2 I
    <P>    m_ClientNetConfig.wClientPackSizeArray[m_ClientNetConfig.ubClientPackIndex] = WORD(size);
    / y+ n5 _7 z' l/ ~, d    ServerConfigPacket packet( m_ClientNetConfig );
    2 R: P8 f5 D! L3 W) S; k    m_ClientNetConfigLock.Leave();</P>* c/ E8 ^1 x( e/ Y( u- M
    <P>    SendConfigPacketToAll( &amp;packet );  J* w* _) L; L; |
    }</P>
    , B9 Z8 p) j" ^5 T& i8 D& W- _  Y; R
    <P>
    7 \6 ?5 A4 F; c//-----------------------------------------------------------------------------1 L+ c- e9 l5 @0 z: m' A- t
    // Name: & D0 P0 g, L2 j* k4 n/ a4 N, Z
    // Desc:
    8 ^0 O( s, A8 @5 k7 ^: {; G//-----------------------------------------------------------------------------
    6 u2 U) F2 T! H9 Rvoid CMazeServer::SetServerPackSize( DWORD size )
    + X1 m5 o$ G! E{
    4 U& D3 x; ~& n' Z6 }    // Update client config, and build packet containing that data
    # e, p4 R/ T2 G    m_ClientNetConfigLock.Enter();
    ( G; @- p8 Q- G: W9 G5 p   
    ) a  {! U" S; Y) M3 W6 M$ e' H    m_ClientNetConfig.ubServerPackIndex++; //Increase index and verify location in array.
    1 p5 h' [1 _. z- r1 o    if(m_ClientNetConfig.ubServerPackIndex &gt;= PACK_ARRAY_SIZE)   
    / h# t, `7 m0 F4 ]5 E; C. Y        m_ClientNetConfig.ubServerPackIndex = 0;</P>1 w% t$ W; D+ q* S
    <P>    m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex] = WORD(size);
    % s4 j* b; g% c$ P5 ^' s    ServerConfigPacket packet( m_ClientNetConfig );
    * j5 P6 j# x% D) ~1 x8 ?/ r$ I" t    m_ClientNetConfigLock.Leave();</P>
    ' E7 ?' I8 b3 t7 u" }# v- U6 H<P>    SendConfigPacketToAll( &amp;packet );; m' k# _0 C& i" `; L# C  x. R
    }</P>. Q1 ^: l6 u* F# w% I
    <P>
    & t4 g& h+ E1 J! u8 o) C" w$ z) {$ \//-----------------------------------------------------------------------------
    5 A. b/ V, `% ]5 k6 V; ~1 I. L3 ?// Name: ( F: r* ^5 x" b; n
    // Desc:
    % Y# F9 I2 i9 \' F) N7 C: b//-----------------------------------------------------------------------------
    . h& C  K% H6 O5 ivoid CMazeServer::SetClientThreadWait( DWORD dwThreadWait )
      x0 @% C% E7 A% ?5 [# K{" i  |) W; g+ P+ O0 b
        // Update client config, and build packet containing that data% e( H* F/ [. `5 J/ v5 H
        m_ClientNetConfigLock.Enter();  S  M2 M+ S! o  B  \- {2 x
       
    9 N! a: d4 K& V; k2 T" w* X    m_ClientNetConfig.dwThreadWait = dwThreadWait;
    3 P3 L7 v! h/ r+ k8 m! \    ServerConfigPacket packet( m_ClientNetConfig );
    : D7 H) l/ A& N$ x1 Z    m_ClientNetConfigLock.Leave();</P>
    ) p1 Z" R! |" c' J; P- a% A9 h<P>    SendConfigPacketToAll( &amp;packet );7 X# |1 ^# z3 B
    }</P></DIV>
    zan
    转播转播0 分享淘帖0 分享分享0 收藏收藏0 支持支持0 反对反对0 微信微信
    您需要登录后才可以回帖 登录 | 注册地址

    qq
    收缩
    • 电话咨询

    • 04714969085
    fastpost

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

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

    蒙公网安备 15010502000194号

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

    GMT+8, 2026-10-8 09:31 , Processed in 0.561548 second(s), 51 queries .

    回顶部