QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 4187|回复: 0
打印 上一主题 下一主题

[分享]MazeServer源码示例

[复制链接]
字体大小: 正常 放大
ilikenba 实名认证       

1万

主题

49

听众

2万

积分

  • TA的每日心情
    奋斗
    2024-6-23 05:14
  • 签到天数: 1043 天

    [LV.10]以坛为家III

    社区QQ达人 新人进步奖 优秀斑竹奖 发帖功臣

    群组万里江山

    群组sas讨论小组

    群组长盛证券理财有限公司

    群组C 语言讨论组

    群组Matlab讨论组

    跳转到指定楼层
    1#
    发表于 2005-1-31 11:52 |只看该作者 |倒序浏览
    |招呼Ta 关注Ta
    <DIV class=HtmlCode>
    2 t4 W9 C. ?. F6 t8 v: j# R' ]/ X0 A<>// File: mazeserver.cpp
    * ]6 j: A5 J" i4 d0 D! k& S, r//
    : f4 Q8 ^6 u; S7 F) ]// Desc: see main.cpp
    ! O( W3 \, N: \$ k5 ?" |! k' y//: O( N& {, C" b/ V! z5 f! P! j
    // Copyright (c) 1999-2001 Microsoft Corp. All rights reserved.# O2 y' }; d; V9 r
    //-----------------------------------------------------------------------------
    : x9 L' }8 w) Z) O9 Z0 V#define STRICT4 D( I  B# j) E
    #define D3D_OVERLOADS
    4 D* m9 X6 R, C* c) i1 ?0 D#include &lt;windows.h&gt;
    8 c+ {; i; {& ~" P6 \  u#include &lt;d3dx.h&gt;
    7 Q9 m; _  P* |* M$ z& b#include &lt;stdio.h&gt;' h0 x  [4 @& M3 y9 R/ B( \
    #include &lt;math.h&gt;& d! @9 l3 E7 K) \8 R$ O( z
    #include &lt;mmsystem.h&gt;
    6 `3 t" @( W& r  y#include &lt;dplay8.h&gt;
    & Y! Q. ?9 [8 [% E! m#include &lt;dpaddr.h&gt;3 e, h( x5 e/ G2 l  S8 s) [
    #include &lt;dxerr8.h&gt;
    # P- ]8 O9 a- K/ j5 V5 t( A#include "DXUtil.h"& {' b  b6 ^1 I# W! W! H
    #include "MazeServer.h": b* O' [) _( q* Z' [. U- r
    #include "ackets.h"- T+ k, l4 t0 k" a$ A
    #include "Maze.h"
    ; a1 i% q$ W1 B#include &lt;malloc.h&gt;& Z3 O% v. r* u* `5 L/ ~" w
    #include &lt;tchar.h&gt;</P>
    / z1 ?/ a" E6 p! `2 |- _. X, q
    ; P% u$ _3 x; W% \) Q<>//-----------------------------------------------------------------------------
    + q$ s( X, E; _2 l' N# W, w// Name:
    ! K# Q! a! I* b8 i1 C// Desc:
    3 g5 b; E. D6 j//-----------------------------------------------------------------------------! g. Y  C7 C, ^" V0 }
    CMazeServer::CMazeServer()0 S2 N$ _4 K0 s, q& r  u5 @
    {9 h' M, F% {0 x" z! f+ L
        m_dwPlayerCount         = 0;  I* ]: ^6 G; }
        ! X1 z9 d. Y' l! H  ?2 t1 R
        m_wActiveThreadCount   = 0;. V: b! J6 r" l& r  W
        m_wMaxThreadCount      = 0;
    7 N, g- A9 W0 T    m_fAvgThreadCount      = 0;; h/ ^. G! _" r$ h, A, T
        m_fAvgThreadTime       = 0;! K2 d  K' Y6 x5 a
        m_fMaxThreadTime       = 0;</P>
    & @" ~* d* R& Z( \0 n5 l<>    m_dwServerReliableRate  = 15;3 o7 k2 W+ c0 m' v
        m_dwServerTimeout       = 150;5 H9 A: }' J/ v
        m_dwLogLevel            = 2;
    : C4 j- d' U2 {5 e    m_pMaze                 = NULL;</P>7 b6 B% C+ ~! N# v' B: T
    <>    m_ClientNetConfig.ubReliableRate = 15;
    5 r, x# u" b+ Z( ?6 \    m_ClientNetConfig.wUpdateRate    = 150;7 Q9 E# p$ o. q; U; ]
        m_ClientNetConfig.wTimeout       = 150;</P>! `5 `7 D5 R- P
    <>    m_ClientNetConfig.dwThreadWait = 0;</P>
    1 E' |* A" \7 |( ~' D' K' ?<>    m_ClientNetConfig.ubClientPackIndex = 0;* c; A1 u3 Q8 Q- \
        m_ClientNetConfig.ubServerPackIndex = 0;
    " v! x7 G# g8 l3 ]    for(WORD x = 0; x &lt; PACK_ARRAY_SIZE; x++)6 M2 h5 K2 N  f; N" i  N- l8 w
        {
    $ n2 F$ M' }8 A; s6 O        m_ClientNetConfig.wClientPackSizeArray[x] = 0;* f; f3 s& R( I) g( f5 T
            m_ClientNetConfig.wServerPackSizeArray[x] = 0;
    & N" j) I8 N7 M( F2 T/ N; A" q    }6 ?* P, X6 _4 D& u, }& i) E
    }</P>* m" D+ k# s: Y6 w

    ) G4 [1 k+ j  X4 T  P0 Q<>& ?  k$ ?8 R" F4 _+ R
    //-----------------------------------------------------------------------------
    , G; i7 V+ h* s) w. @// Name:
    & h5 ]$ Z2 D4 k8 Q8 q// Desc:
    ; `9 _: l- P$ {% o1 o//-----------------------------------------------------------------------------" j6 c  Y& V3 Q3 J: L: f
    HRESULT CMazeServer::Init( BOOL bLocalLoopback, const CMaze* pMaze )
    - O* T' `4 u# \" y9 K: ^{) h1 p+ R- P' P9 @$ }
        m_bLocalLoopback = bLocalLoopback;. E1 g* d' G! z9 u( D
        m_pMaze = pMaze;4 ^$ q+ S2 s3 O* \4 t$ Y
        if( m_pMaze == NULL )" e9 o0 V5 k) n
            return DXTRACE_ERR( TEXT("aram"), E_FAIL );</P>
    7 B: g7 H# a5 @8 o<>    // Grab height and width of maze
    5 R# {% H& p  n+ D, ?    m_dwWidth = m_pMaze-&gt;GetWidth();: m& h& s! R. [, V
        m_dwHeight = m_pMaze-&gt;GetHeight();</P># d; ~; }. T- Y7 q' ]* J$ V' `
    <>    m_ClientNetConfig.dwMazeWidth  = m_dwWidth;
    1 G: C" D6 E9 ~/ M& k    m_ClientNetConfig.dwMazeHeight = m_dwHeight;</P>: d& C5 z% e' @" d0 f
    <>    // Validate size. Must be a power-of-2 times LOCK_GRID_SIZE. Compute the shifts.* L( P3 ^; w- j+ U
        if( m_dwWidth &gt; SERVER_MAX_WIDTH || m_dwHeight &gt; SERVER_MAX_HEIGHT )! D& A& K3 U: f! T5 d, f
            return DXTRACE_ERR( TEXT("Maze height and width need to be less than 128"), E_INVALIDARG );
    " k( E# u" e1 E- G    if( (m_dwWidth % LOCK_GRID_SIZE) != 0 || (m_dwHeight % LOCK_GRID_SIZE) != 0 )$ ~( K; g! O+ z
            return DXTRACE_ERR( TEXT("Maze height and width need to be divisable by 16"), E_INVALIDARG );</P>
    1 R! d# L- R1 w6 W: `<>    DWORD scale = m_dwWidth / LOCK_GRID_SIZE;& T8 K7 z8 c6 x" b) |' y
        m_dwMazeXShift = 0;
    $ T& k* A/ F7 q, V' K7 N3 Q! K    while ( (scale &gt;&gt;= 1) )
    8 V6 c  h/ A/ G2 d) q( G9 e' {* d! r        m_dwMazeXShift++;</P>
    ) T; n- r* M9 Q  O7 F* z- O<>    scale = m_dwHeight / LOCK_GRID_SIZE;" d& ^7 I& D3 M) ]
        m_dwMazeYShift = 0;
    3 P0 r# a4 p; M* T    while ( (scale &gt;&gt;= 1) ): B- x& m( h, i; X/ }- V
            m_dwMazeYShift++;</P>  y+ Y# @* X  A/ ^) `: D
    <>    if( ((DWORD(LOCK_GRID_SIZE) &lt;&lt; m_dwMazeXShift) != m_dwWidth) ||
    5 o4 z1 d) |1 O5 N1 K6 L        ((DWORD(LOCK_GRID_SIZE) &lt;&lt; m_dwMazeYShift) != m_dwHeight) ): n; S% C9 Z  P# @
            return DXTRACE_ERR( TEXT("Maze height and width need to be power of 2"), E_INVALIDARG );</P>! F) p# Q5 N! m3 ]6 T
    <>    // Initialise the player list
    8 a9 |! g( k" C, [* P    ZeroMemory( m_PlayerDatas, sizeof(m_PlayerDatas) );) Q) q2 T! E  k  @- N, b& g  E* O
        m_pFirstActivePlayerData = NULL;
    # n. \. L! s8 Q9 b& |6 f    m_pFirstFreePlayerData = m_PlayerDatas;
    , o0 K3 ?8 K6 h" R9 y9 n* }    for( DWORD i = 1; i &lt; MAX_PLAYER_OBJECTS-1; i++ )
    $ F1 ^' F4 U! J  V2 {: z# r    {
    ( L& b5 @3 [3 b2 ^; N9 ~        m_PlayerDatas.pNext = &amp;m_PlayerDatas[i+1];
    5 Z6 a: t6 Z, Q6 T0 _* _        m_PlayerDatas.pPrevious = &amp;m_PlayerDatas[i-1];
    - c9 s/ ~5 Q% [. f- M    }</P>  y- W$ \# z7 r# f
    <>    m_PlayerDatas[0].pNext = &amp;m_PlayerDatas[1];( R9 }) x/ p% m
        m_PlayerDatas[MAX_PLAYER_OBJECTS-1].pPrevious = &amp;m_PlayerDatas[MAX_PLAYER_OBJECTS-2];8 F: q" q# y" S" I
        m_dwActivePlayerDataCount = 0;
    4 c5 r  F' C* x3 d5 |5 c6 y    m_dwPlayerDataUniqueValue = 0;</P>  n6 H4 `+ E! N$ B  m
    <>    // Initialise the cells
    . j+ }' O( r. K; K    ZeroMemory( m_Cells, sizeof(m_Cells) );) N* S8 g8 I* G. G% T
        ZeroMemory( &amp;m_OffMapCell, sizeof(m_OffMapCell) );</P>/ ]- H( z9 O* x6 ]5 G2 A  }' G
    <>    return S_OK;
    5 ^; D( V) |7 X* P}</P>
    4 [# a: u* t" {& Q3 @3 Y8 W( O
    ! V* q* q% N2 n* {. p<>! ^7 ~& H$ Q- c/ S  \
    //-----------------------------------------------------------------------------
    ; \4 j8 ~! [. O9 l7 H/ L  [* K// Name:
    $ `. K; l# d) y// Desc:
    * |+ s3 H* x( r1 r' R  ]7 y//-----------------------------------------------------------------------------# U  F& ^) P2 s- ^7 }) a
    void CMazeServer::Shutdown()5 G& C( o/ L$ J' w
    {
    1 b, H( l: F- ?: w! R}</P>$ v: H6 i: X7 {

    / ]' |1 L0 m/ [8 b- n$ U  c1 b<>
    , G9 S( T( k0 s& s1 i1 ~//-----------------------------------------------------------------------------
    . B; d8 I$ u/ {# H# D) I// Name: : D0 ]* ~, T2 ^% _2 ?8 X' b
    // Desc: " X$ n: h$ N0 X2 y
    //-----------------------------------------------------------------------------/ \7 Q# n6 ]! G
    void CMazeServer:ockRange( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )
    . g7 ^  j! I% ?{; b+ w4 s, @( m1 q) a8 @5 ]
        m_LockGrid.LockRange( x1&gt;&gt;m_dwMazeXShift, y1&gt;&gt;m_dwMazeYShift ,
    ! v& E2 U' M. l* E$ Q                          x2&gt;&gt;m_dwMazeXShift, y2&gt;&gt;m_dwMazeYShift );( ~% ]' Y( e+ t/ i5 y' \
    }</P>
    ; c2 [6 p3 n, ?7 e( i' y
    6 N% i5 s9 D0 y( V<>
    ; B7 {4 q5 w3 m/ ?7 M) g+ h+ C. P8 Z- i# {//-----------------------------------------------------------------------------7 x- N8 g- R* \# S/ b1 d: J9 d
    // Name:
    9 X0 D+ P& k3 [1 B// Desc:
      _9 E9 f' A$ y( R) N//-----------------------------------------------------------------------------" J3 Q, ^% P( H( v7 H6 M
    void CMazeServer::UnlockRange( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )
    3 Y, M  |  r& y3 f# g) I{
    , s9 K0 U  {/ X    m_LockGrid.UnlockRange( x1&gt;&gt;m_dwMazeXShift, y1&gt;&gt;m_dwMazeYShift ,
    ) \% s* P8 B7 }                            x2&gt;&gt;m_dwMazeXShift, y2&gt;&gt;m_dwMazeYShift );* F" F' b2 b( Y$ `
    }</P>% x. S: _# o+ o1 j9 `2 W

    + y% W3 ?1 o, Y' S; Y<>
    * c$ M" x% t/ V' n//-----------------------------------------------------------------------------/ Y- p/ L1 o& W; g0 e5 B  A
    // Name: " I; z" W# r- x: ]
    // Desc:
    " k0 q' c& I5 b) i//-----------------------------------------------------------------------------
    7 T/ L* x" L( n+ h% c' [void CMazeServer:ockCell( DWORD x, DWORD y )
    ( o! R& M- f' ^& Q* K6 u{
    % p) C. a8 c; o- i' E$ z    if( x == 0xffff )
    ! y) G- [9 S# G6 `5 S  p4 v        m_OffMapLock.Enter();
    1 t# B3 \+ z: C( c% F    else
    ! R' y( {2 X. K, g4 w8 R2 O5 P9 ^        m_LockGrid.LockCell(x&gt;&gt;m_dwMazeXShift,y&gt;&gt;m_dwMazeYShift);8 ?  ^" V* A( r0 V8 V: H
    }</P>
    1 ~9 `# G8 B2 K6 e- z( D
    9 o! z- X$ G- h  m- [! h6 }<>+ H0 s5 Q2 E2 P0 R- V5 b
    //-----------------------------------------------------------------------------0 ]: I2 ~7 ~# R' Q) g4 k; i5 `
    // Name: ; V9 |9 Y% [: i2 G+ ~9 k2 N3 g
    // Desc:
    7 T9 O# s' u7 ?  v: N* A  z//-----------------------------------------------------------------------------
    5 A! D. x1 I, l* v6 }  {/ V; X. Pvoid CMazeServer::UnlockCell( DWORD x, DWORD y )2 H. ]: ]6 _  _& r) |7 P
    {6 e9 b' E) M4 K3 v
        if( x == 0xffff )
    , Z: R8 d, c' @        m_OffMapLock.Leave();8 l  O9 h$ L; j9 w- I% H: m
        else, |" W  ]2 l7 y# r: }" s
            m_LockGrid.UnlockCell(x&gt;&gt;m_dwMazeXShift,y&gt;&gt;m_dwMazeYShift);
    0 w+ N1 F+ U' a}</P>
    7 B! N7 ~7 y; |1 ?, i( G9 l3 W5 u0 M% ~8 ]* |: W- K* t3 H9 g+ c, K( K
    <>
    . k$ b8 B' r+ w5 x4 ^* A9 T//-----------------------------------------------------------------------------7 L, ?* v  L% b$ N
    // Name:
    ' m* g3 t6 [. U. k7 ?* B& G4 A% j7 h// Desc: + j3 _; Y5 `6 n& E5 M9 A" a
    //-----------------------------------------------------------------------------
    ( |1 z1 J% e0 {5 u2 {4 \) Yvoid CMazeServer:ockCellPair( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )+ ]2 O, b( r& A$ O, K" t
    {
    % o1 P# m( }& }* f# G/ O2 [6 B    if( x1 == x2 &amp;&amp; y1 == y2 )
    ! O/ O1 s$ K5 k9 l& H; B    {
    % T9 G9 |9 ?% k) w$ Y  v7 a6 i        if( x1 != 0xffff &amp;&amp; y2 != 0xffff )9 R) m8 a  U8 }* ^, `
                LockCell( x1, y1 );. W" o+ Y+ I+ D( Q3 [$ i
            else% X, k$ c" C2 y) |8 s/ s
                m_OffMapLock.Enter();</P>
    * N6 A/ Z4 ^6 z- X) R7 x9 O& A<>        return;
    $ `' C6 x. G9 L0 H$ P5 }* A- ?    }</P>' |6 I4 z; }3 U  U  ?" R2 [
    <>    DWORD x1shift = x1&gt;&gt;m_dwMazeXShift;8 ?- A1 A  Q$ @8 Y: j
        DWORD x2shift = x2&gt;&gt;m_dwMazeXShift;
    : E. N, m6 I' v4 s6 d    DWORD y1shift = y1&gt;&gt;m_dwMazeYShift;
      w" s( Y( m' N% w: d5 n0 ~    DWORD y2shift = y2&gt;&gt;m_dwMazeYShift;</P>
    $ V; w  P, w1 v& b+ G! g: }* i<>    if( x1 == 0xffff )
    / L9 J" E+ b) R( A% ~) ^    {
    & Z2 o  ~; ~+ q: j7 x        m_OffMapLock.Enter();
    ! I, @; {7 T3 s5 @9 }5 t        m_LockGrid.LockCell(x2shift,y2shift);
    1 k4 z. C8 G/ ^6 j1 N' e" m    }+ `6 R& d, Z4 G
        else if( x2 == 0xffff )
    3 C7 d4 r, I- Z- p1 V+ z2 }, E6 {2 g! t    {
    1 v) W/ J* a# _% k, Z; k! B        m_OffMapLock.Enter();3 E  N% U" X1 C; X/ }8 P
            m_LockGrid.LockCell(x1shift,y1shift);
    * Y, P' e% b  [0 A    }
    % [" Q0 @" B3 @7 K: X    else 7 \6 @: \4 h% u( p& B/ o+ q. m+ L
        {
    ' y/ o! G% g; u        m_LockGrid.LockCellPair(x1shift,y1shift,x2shift,y2shift);
    ; l; Q( G7 ]/ Q  c9 L) q) K! `    }
    / y0 F. C. b5 Z. b. s}</P>
    5 n2 q. v; N* _# T' [: e0 S# [6 ]' H  r/ y+ W9 L1 }
    <>$ n" g) k' B- @  j  E
    //-----------------------------------------------------------------------------
    1 S% y4 \% R$ y! f8 y% d) M// Name:
    $ m' Z7 l& R; s3 _& p! s// Desc: 1 a# v- m8 e- j( V
    //-----------------------------------------------------------------------------3 w# j* A1 t% J% S3 ]! X8 H" o0 K. R
    void CMazeServer::UnlockCellPair( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )( S6 v0 Z' f, X& h" R: I' Y
    {
    ( @. t& ]1 ^+ y1 e  Z    if( x1 == x2 &amp;&amp; y1 == y2 )
    & Z0 U. g( ]0 t4 D    {
    $ C% N5 A# U5 e4 }- |& j! w        if( x1 != 0xffff &amp;&amp; y2 != 0xffff )$ f' A- x8 \+ j: X+ c7 z
                UnlockCell( x1, y1 );
    + T/ k; ?7 z- e4 _% I% t        else& N( i/ T% m1 `+ z
                m_OffMapLock.Leave();</P>
    $ P" }5 M* L9 o0 K/ U<>        return;
    * ?" Y/ \. F( q, {3 ~: F    }</P>
    6 ^) J" M( X2 m& V<P>    DWORD x1shift = x1&gt;&gt;m_dwMazeXShift;+ j% O8 E: N' {+ _7 x' {) I  r  E3 h/ M
        DWORD x2shift = x2&gt;&gt;m_dwMazeXShift;
    2 }" C& j( T* F4 U    DWORD y1shift = y1&gt;&gt;m_dwMazeYShift;
    # t) C8 F7 I$ A) s/ y( y    DWORD y2shift = y2&gt;&gt;m_dwMazeYShift;</P>
    ! C- M# ?; P4 U; `2 r' M<P>    if( x1 == 0xffff )4 M1 C4 W6 G9 u3 [" T
        {: l- @$ T1 W2 Y8 o) z# I
            m_LockGrid.UnlockCell(x2shift,y2shift);
    , a+ D. {. x# w        m_OffMapLock.Leave();+ [. C: n- o( ~% F# p7 `/ F* y
        }7 S0 ~1 n7 Y5 A# s
        else if( x2 == 0xffff )0 j9 \9 H0 G: e) \$ e0 W
        {
    ' A* H( ?4 I5 v1 W        m_LockGrid.UnlockCell(x1shift,y1shift);. a' I' l6 R  h5 e
            m_OffMapLock.Leave();
    ' j: c/ \( j3 z4 U8 m    }" V: \6 V* W8 q( B/ S# O5 t
        else
    - c, |0 D, ~% t8 _" i1 n  p& k    {# F& u0 x% F. v& x! B! I  [; I0 I
            m_LockGrid.UnlockCellPair(x1shift,y1shift,x2shift,y2shift);
    9 G% X- N; e- g' g7 l, K/ `5 Q    }
    ) R" @& ]5 F2 h, M! O- c  y4 w% _}</P>; j! I2 L/ @# N- W  q+ r

    0 t+ E2 w( R% L* _: f$ y, ~2 x<P>
    ) u2 z3 D) J2 t! O) t//-----------------------------------------------------------------------------
    ) H1 c+ O1 l( E3 t0 V// Name:
    ( x9 W' e* Z2 V# D" i// Desc: " L, G8 C8 L: J
    //-----------------------------------------------------------------------------8 Y- }, m( {, ?+ v7 y% P- v
    void CMazeServer::OnAddConnection( DWORD id )
    * F" y$ U" j. H{3 [- ^0 ^) k" }7 L) Z
        m_AddRemoveLock.Enter();</P>/ X) D5 g/ k- N* Z% {
    <P>    // Increment our count of players. b) x6 f; Y7 X9 E) e3 y) V
        m_dwPlayerCount++;
    ; T9 s+ U" E  u5 F    if( m_dwLogLevel &gt; 0 ). x: m8 l% u/ F8 C
        {
    . [+ W% Q+ C) i) G4 Q        ConsolePrintf( SLINE_LOG, TEXT("Adding player DPNID %0.8x"), id );, `! j+ \  E5 o! ?7 g: ]
            ConsolePrintf( SLINE_LOG, TEXT("Players connected = %d"), m_dwPlayerCount );
    ; U) F9 n3 q  l' {4 A    }</P>* {9 r$ S$ \) z) o4 W7 g. @
    <P>    if( m_dwPlayerCount &gt; m_dwPeakPlayerCount )& c/ [( h% T3 A$ y' U
            m_dwPeakPlayerCount = m_dwPlayerCount;</P>
    % z& p0 _; s1 X; U% k/ g<P>    // Create a player for this client
    + l; o, b  d8 b) t) w    PlayerData* pPlayerData = CreatePlayerData();1 Z& \6 [/ S0 i% @" L
        if( pPlayerData == NULL )
    + H$ d$ t7 ~- _    {
    & p1 d, ~: E5 A7 n, H        ConsolePrintf( SLINE_LOG, TEXT("ERROR! Unable to create new PlayerData for client!") );" _6 \6 m' n2 z# N/ _
            DXTRACE_ERR( TEXT("CreatePlayerData"), E_FAIL );
    , z1 ^. \: q8 d3 T" e8 m3 C. [2 N        m_AddRemoveLock.Leave();$ y* {6 G: \7 J' l: b
            return;
    3 c9 y9 o7 y- |& X; m4 {0 z    }</P>
    2 {0 U- r6 P7 b! g6 M<P>    // Store that pointer as local player data
    8 Q+ }  j9 i4 p1 {3 q* V: R    SetPlayerDataForID( id, pPlayerData );</P>  P1 N  g2 y0 B/ I
    <P>    // Grab net config into to send to client
    . x& C  r; k0 s    m_ClientNetConfigLock.Enter();: }3 |+ K- C: Y& H. g+ D  Q" V% D
        ServerConfigPacket packet( m_ClientNetConfig );$ A: e# s+ J/ G, c3 x+ o# k
        m_ClientNetConfigLock.Leave();</P>- u# O8 |5 t! S" W8 r; H, a0 d- L$ U
    <P>    // Send it+ w" k. y$ D) k9 T
        SendPacket( id, &amp;packet, sizeof(packet), TRUE, 0 );</P>
    4 V, L# ]& J, W% @$ x2 T' V4 V<P>    m_AddRemoveLock.Leave();9 O# j' v3 J9 o9 U! J$ }$ }
    }</P>, t: c# U. J' [! u# T2 H6 q
    - g% x, ~6 T& x' B/ P  S5 h
    <P>
    ' b$ k- s$ P& }/ j" U//-----------------------------------------------------------------------------+ ^" x( Y* x9 y# _$ u
    // Name:
    5 o! G& d0 D: H, j4 g8 ]// Desc:
    2 `' D* s6 U. Q) z4 P( T4 Z//-----------------------------------------------------------------------------4 I( j1 Q. H1 N+ }3 v  _
    void CMazeServer::OnRemoveConnection( DWORD id )
    8 E8 Q9 C% M+ h: M{
    % a5 w- v3 x5 U    m_AddRemoveLock.Enter();</P>
    3 {3 @+ P" |. ~4 Y<P>    // Decrement count of players
      d' L$ m0 d" c0 ]" b9 `    m_dwPlayerCount--;</P>
    ! N1 Z; P3 h- }<P>    if( m_dwLogLevel &gt; 0 )
    4 x8 e7 g5 k  @! Q3 d4 z6 O    {
      }: I+ r1 L; I; j, N        ConsolePrintf( SLINE_LOG, TEXT("Removing player DPNID %0.8x"), id );
    9 L1 z* y$ O7 j        ConsolePrintf( SLINE_LOG, TEXT("Players connected = %d"), m_dwPlayerCount );
    . |+ i, s* v" N* w0 |: E    }</P>
    ! H1 ^* R( p. n' Q<P>    // Find playerdata for this client7 {8 B4 [4 m& @3 @
        PlayerData* pPlayerData = GetPlayerDataForID( id );
    , J' ~6 }9 x0 d. f, j& T    if( pPlayerData != NULL )
    3 j# E  u/ B/ c4 P    {
    6 X- f" D5 B- M0 W2 o, O# B% q0 x        // Destroy it
    " ^- ^5 Q3 j) n1 R        RemovePlayerDataID( pPlayerData );" z) U7 Z' W  I/ C. _9 C
            DestroyPlayerData( pPlayerData );
    , k2 `+ v! S, m' j    }</P>0 C0 l5 R* r0 t( T) _
    <P>    m_AddRemoveLock.Leave();, G5 ]( t  n  ^# F/ t$ {
    }</P>
    ( O  a; h" D1 q- t" _0 I" e6 ~/ z% [. R' Z4 F, y/ |
    <P>. F; N, ?( c  d8 d* @. d% l, _
    //-----------------------------------------------------------------------------. I! T- c, }. K, O, S( \
    // Name: / A- e3 g( O8 \  {
    // Desc:
    % f& |7 Q/ R3 s; z; |' @: p$ J//-----------------------------------------------------------------------------; G! l  M! {$ o$ n
    HRESULT CMazeServer::OnPacket( DWORD dwFrom, void* pData, DWORD size )
    * @0 m& x6 z. \{' v" {$ F5 M7 t# [9 T! M
        BOOL fFoundSize = FALSE;</P>
      j, [" s; v& N2 {5 }<P>    // Increment the number of thread we have in this process.
    ; u/ h$ q  u  S3 D/ v! ?    m_csThreadCountLock.Enter();</P>
    5 T9 G: O% ^4 m% c- e<P>    //Get the start time of when we entered the message handler.8 L  I1 m" K$ m: b1 U8 Z
        FLOAT   fStartTime = DXUtil_Timer( TIMER_GETAPPTIME );</P>
    ( T( Z' ^! i; g<P>    m_wActiveThreadCount++;$ Y/ n" I* n, h6 }
        if(m_wActiveThreadCount &gt; m_wMaxThreadCount)
    , p% P) v4 z; L! H% X        m_wMaxThreadCount = m_wActiveThreadCount;: {$ ]. A+ Q- k
       
    1 A8 l+ x4 X, k' F# l    // Calculate and average.% T  m7 d6 ^( ]" l
        FLOAT fdiff = m_wActiveThreadCount - m_fAvgThreadCount;- D% h  B4 p4 q6 w$ h
        m_fAvgThreadCount += fdiff/32;4 h$ a, Y3 F( c5 t5 g
       
    7 ~# t$ z1 R# L" v& y    m_csThreadCountLock.Leave();</P>  y6 ^; ]/ ^$ H
    <P>
    0 c8 s% j$ n, o/ P4 U4 ]    ClientPacket* pClientPack = (ClientPacket*)pData;
    ; W8 t6 A, k! s, U: j    switch( pClientPack-&gt;wType )" b: Q4 ^; j! ~% q) |* p' D
        {
    + D1 Q& t; @* e  M! D        case PACKETTYPE_CLIENT_POS:
    % p5 @) y! V9 g! k% W            
    & i6 l* c& C8 |4 O/ X            // Check to see if the packet has a valid size. Including & J4 f8 Y/ W9 n( z
                // the custom pack size.- _2 |, ~. ]( E% ?9 J; M, a
                if( size &lt; sizeof(ClientPosPacket))% i6 T( L4 z* _$ W) Z4 v0 ], w
                    fFoundSize = FALSE;
    ) m& I3 T! e. G            else if( ! IsValidPackSize(size - sizeof(ClientPosPacket)))
    7 c& d$ _" ~5 f4 H* @9 S                fFoundSize = FALSE;
    + N% s5 a* s# ?; p            else# m+ B" I8 S* e$ f6 r: a' D
                    fFoundSize = TRUE;</P>
    3 v4 j7 q2 D! w6 @<P>            // If valid sized packet, handle the position.
    7 x' ^+ M" ~% b* N# n            if(fFoundSize)% g; E1 |# p1 z4 q$ \% G" P: L
                    HandleClientPosPacket( dwFrom, (ClientPosPacket*)pClientPack );, w0 R6 S# q2 v5 |, g7 h
                else
    % x2 Y! I& `9 p$ U( a7 x                m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );</P>
    , s% r7 y( X. V5 i# g5 Q<P>            break;</P>
    $ l3 C- n! w. ~: {/ `# d; G& @<P>        case PACKETTYPE_CLIENT_VERSION:
    . f) {+ b0 _9 W/ Z2 V' q            if( size == sizeof(ClientVersionPacket) )
    $ _; e* R# U3 e                HandleClientVersionPacket( dwFrom, (ClientVersionPacket*)pClientPack );  r  a( k$ G: u' p# m/ T5 Y% G
                else
    ! h2 T8 A8 k3 }                m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );
    7 E9 o0 w# _5 R' g$ M8 E2 B            break;</P>
    ! S' _4 ~( x* j1 O* @) b% ?% W<P>        case PACKETTYPE_SERVER_CONFIG:</P>
    . V5 ^: z! N& H9 _: b0 H5 j9 g<P>            // Server config packet sent to all users (including server). Just ignore and continue.</P>
    5 ~( |! }0 A( Z<P>            break;2 q- Y( U1 b1 d2 N' ]
            default:
    : P! |+ F" o( {3 P  J            HandleUnknownPacket( dwFrom, pClientPack, size );
    $ Q* ]8 W4 X4 e* z3 k            break;
    6 M4 S- m" Q8 I4 Y9 `    }</P>
    7 t5 r. T& k8 z! b9 o9 E5 W5 d/ U<P>    //If the user wants to hold the thread, Sleep for given amount of time.
    6 J( X: o, e6 G8 \    if ( m_dwServerThreadWait &gt; 0 )6 q8 K. D$ u8 k$ j& E% E
        {5 K0 Y! K, L9 ^4 Y; T
            Sleep( m_dwServerThreadWait );; Q$ k, ]7 X' k) g' ^. d% ~) l
        }2 {' ?1 N  \4 }: t
        8 {* t: F5 Y- L$ b2 P+ a5 D
        // Retrieve thread data for this process.
    4 P$ ^% a" f: \/ P; N7 h9 x    m_csThreadCountLock.Enter();</P>5 C  h: @3 S) \  T9 ]3 h8 `& R
    <P>    m_wActiveThreadCount--;</P>
    / ^: q. j$ i" _* w# b# d; i( q<P>    FLOAT fDiffTime = (DXUtil_Timer( TIMER_GETAPPTIME ) - fStartTime) - m_fAvgThreadTime;
    $ E6 S; M! d6 ^( P$ a4 E4 Z( D2 Z    m_fAvgThreadTime += fDiffTime/32;</P>
    . w1 @- H( K3 b! Z3 i<P>    //Get the Max time in the thread.$ `$ j5 P) z2 _2 k( n
        if ( fDiffTime &gt; m_fMaxThreadTime )
    6 k7 I/ W1 H  h, N: `4 \    {" r, l* G0 j" a- X
            m_fMaxThreadTime = fDiffTime;3 ~8 F$ r; d2 I7 f+ P1 {9 E* v4 S# N
        }</P>; b& o  Q0 {5 {
    <P>    m_csThreadCountLock.Leave();</P>) K( Y, w% A* a; G3 F
    <P>    return S_OK;
    + t, M! O  [' I0 o+ ]- s& s' J}</P>) J- t; e+ H# i
    % k: m- n9 j- y  S  k
    <P>//-----------------------------------------------------------------------------
    ; C/ c- |, |+ V5 o7 D! U. g// Name:
    ( V3 B! h, _/ d+ X6 \// Desc: # |: C) v) q% A' E0 V+ U0 I" @* ^
    //-----------------------------------------------------------------------------9 W0 I+ {; K7 x; C' i
    BOOL CMazeServer::IsValidPackSize( DWORD dwSize )
    " o% @2 t0 q. C; w3 S{
    0 f/ _! h* f- z" K    BOOL fFoundSize = FALSE;
    3 }2 i9 V& O5 i7 p, n    BYTE ubPackLocation = m_ClientNetConfig.ubClientPackIndex;
    4 q' R  j3 ?4 a3 G" e   
    8 p0 G, H& F. U( h    // Check through the array of valid pack sizes.
    9 V# W  B0 M% d! |+ Y! Z1 S/ l( {) O    if(dwSize != m_ClientNetConfig.wClientPackSizeArray[ubPackLocation])
    # r% Z& W3 j9 Y; j3 u+ F    {) E( b" p5 ?% E8 Z7 i2 L
            for( --ubPackLocation; ubPackLocation != m_ClientNetConfig.ubClientPackIndex; ubPackLocation--)5 d* s4 P9 p9 x# q+ R: s; J
            {* ?- F9 Z5 H; {' Z4 z  M
                if(dwSize == m_ClientNetConfig.wClientPackSizeArray[ubPackLocation])) \* u% K/ Q. z% {+ O  w9 }0 R
                {
    ; f! P$ \3 A  q1 y                // Found valid size in the array.
    , d7 a) ~, p5 b, Y$ T1 d                fFoundSize = TRUE;6 z% J8 j( y: f- a. E
                    break;8 b( g! E1 Y  @
                }8 U: t5 X  d2 ^/ B) ]5 l6 i& a
                if(ubPackLocation &gt;= PACK_ARRAY_SIZE)  ubPackLocation = PACK_ARRAY_SIZE;  //Wrap the array.
    5 ?, K% F3 F+ F4 M        }/ B! i: v+ q0 f
        }3 j; f. H0 u) Z$ i3 h5 V' a
        else
    2 k! g# y/ `' N, B% r) V/ D9 y% `    {4 K5 O$ |# Q- _& V  \5 s
            fFoundSize = TRUE;  k' b2 G) e) A) g$ v9 n  b
        }</P>) b/ `% i  [$ n& A3 U
    <P>    return fFoundSize;, S; H# a) p6 G( J3 R) v
    }</P>
    , h, K! N8 y1 B2 R- p( y: `<P>* m) u0 G( _/ A1 P+ ^4 t. X3 x
    //-----------------------------------------------------------------------------% k) G* f' o% \
    // Name:
    / V! Q9 A7 z- Q! v// Desc:
    7 r' q3 h5 s- \8 j8 j//-----------------------------------------------------------------------------9 S: w% j- {1 ^9 [4 D
    void CMazeServer::OnSessionLost( DWORD dwReason )
    7 e1 Z! c7 R! r1 a0 m{  x- q- z1 D* H3 |. |
        ConsolePrintf( SLINE_LOG, TEXT("ERROR! Session was lost") );
    3 Q, W) g) J8 `# b! B}</P># L+ v) Q! a  B: Y, r
    5 e1 y9 n; m" a, w& G" G; T
    <P>8 n% Z- g7 e, X8 s( V. t1 y0 W6 h* l
    //-----------------------------------------------------------------------------
    ) A% E! \$ H" t// Name:
    0 {, P/ A9 O/ c' \' ]. a6 ~& I// Desc: 9 O# I( {9 j5 y) P1 Q/ k# f7 p
    //-----------------------------------------------------------------------------
    8 _0 H  ^# C! }7 V/ {PlayerData* CMazeServer::CreatePlayerData()) d1 J1 m  q; I* Y' {
    {8 D! v3 \  k* Y9 ~( a7 i) d. g$ g
        m_PlayerDataListLock.Enter();</P>% l5 l+ i, t! Z9 ]& W& O7 e3 F, V; g8 R
    <P>    // Grab first free player in the list
    : \! z3 c& e  N/ `    PlayerData* pPlayerData = m_pFirstFreePlayerData;</P>  N% Q3 O8 K+ l0 O) r5 R# Q7 b  s
    <P>    if( pPlayerData )+ S' @5 u% m/ B5 B
        {
    + f/ d& z5 y6 T. S        LockPlayerData( pPlayerData );</P>$ f& |) J  n2 b" X* L
    <P>        // Got one, so remove it from the free list
    5 e% k( W2 d1 T! {4 x! e" K        if( pPlayerData-&gt;pPrevious )
    . k* q. S* v6 {            pPlayerData-&gt;pPrevious-&gt;pNext = pPlayerData-&gt;pNext;
    % \5 p6 m4 z& [3 S        if( pPlayerData-&gt;pNext )
    $ I8 C' ?3 B" c& B4 m8 m            pPlayerData-&gt;pNext-&gt;pPrevious = pPlayerData-&gt;pPrevious;  k: }% D. j2 B1 s& |
            m_pFirstFreePlayerData = pPlayerData-&gt;pNext;</P>' r5 Z  }! \0 ^% k! V& P4 |
    <P>        // Add it to the active list
    % k) a/ B8 O& h0 S5 y        if( m_pFirstActivePlayerData )
    ! V9 e0 y9 N/ _- r3 U; s0 o            m_pFirstActivePlayerData-&gt;pPrevious = pPlayerData;
    $ l6 X7 V8 Y, x7 m2 I9 ?        pPlayerData-&gt;pNext = m_pFirstActivePlayerData;
    7 _( k( `4 w) ]1 o) y& ]9 n        pPlayerData-&gt;pPrevious = NULL;
    , e* ^6 u7 B/ T: P! a( a; h        m_pFirstActivePlayerData = pPlayerData;</P>
    1 H6 l# M5 f, c0 f- ~8 ?<P>        // Update count of players' _) y7 z' z. d+ ]6 k
            m_dwActivePlayerDataCount++;</P>
    + j. r8 g- `2 b6 L<P>        // Generate the ID for this player" P, H/ ]% t! s  \' y
            m_dwPlayerDataUniqueValue++;, x4 f  s4 {7 r. E
            pPlayerData-&gt;dwID = (DWORD) ((pPlayerData-m_PlayerDatas)|(m_dwPlayerDataUniqueValue&lt;&lt;PLAYER_OBJECT_SLOT_BITS));</P>
    % Y" U& z9 T- j3 `<P>        pPlayerData-&gt;pNextInIDHashBucket = NULL;
    5 A; R& ]. ]) V' j        pPlayerData-&gt;NetID = 0;; u2 W7 N% i! M3 c# V- I) k6 y( E# f! U
            pPlayerData-&gt;dwNumNearbyPlayers = 0;</P>- r2 ~/ \- X' b) K# y
    <P>        // Insert into the "off-map" cell
    9 ~" ]! q# g( u' i- [4 u        pPlayerData-&gt;fPosX = pPlayerData-&gt;fPosY = -1;
      T/ N  A5 K9 R9 V        pPlayerData-&gt;wCellX = pPlayerData-&gt;wCellY = 0xffff;
    ) L. y4 G- X! m. ]. p5 f        m_OffMapLock.Enter();
    : d( w9 C, u  q' H# s        pPlayerData-&gt;pNextInCell = m_OffMapCell.pFirstPlayerData;
    4 [% y! Z! w2 e6 A/ t        m_OffMapCell.pFirstPlayerData = pPlayerData;, }' S* M# h* }  V4 ]# M
            m_OffMapLock.Leave();</P>
      o, s3 o& ]& {- S# N- r$ M<P>        // Mark as active  {: N3 O" n5 H  D
            pPlayerData-&gt;bActive = TRUE;</P>$ [/ S' e( A; ?. R( p, |
    <P>        UnlockPlayerData( pPlayerData );
    - g  ?9 d( T# [, l: h% W% D& v% S  ~9 ]    }</P>/ }3 V- ~& L: z0 g; }! c
    <P>    m_PlayerDataListLock.Leave();</P>$ M" s# W% W9 s! W7 X9 A
    <P>    return pPlayerData;3 a3 m2 X/ Z/ S$ w3 Z
    }</P>
    , A4 \) ?# v4 l8 C& `% J  R4 B
    6 ~3 }1 ]3 r* a<P>5 \7 f) Y2 z) D; ]5 |- v: E
    //-----------------------------------------------------------------------------
    3 F6 o2 `4 g$ p, M# y# A// Name: - D' k6 K# L/ U8 k* k
    // Desc: " P, @) e: |8 x( L
    //-----------------------------------------------------------------------------
    2 j6 i# @* k$ q6 X' Jvoid CMazeServer:estroyPlayerData( PlayerData* pPlayerData )7 |' a7 {  J4 ?, ?, D. e
    {
    & h+ R' ?9 a' L    m_PlayerDataListLock.Enter();) [4 i& u" ~2 \8 c+ _
        LockPlayerData( pPlayerData );</P>) C0 @0 h% p8 y, w% ^* ^) m5 u9 x7 {
    <P>    // Remove the player from its cell$ C' k: Y3 _6 ~; c( @
        RemovePlayerDataFromCell( pPlayerData );</P>( _9 v7 M+ T6 [4 I" J
    <P>    // Mark as inactive
    / C; i, `4 D: s/ q( \- H/ m    pPlayerData-&gt;bActive = FALSE;</P>) o- d" h: ?) @+ Y* E) ^
    <P>    // Remove player from active list4 o# Q  J+ p. c9 @+ u" X% _
        if( pPlayerData-&gt;pPrevious )
    9 S  v4 V3 {% G9 I# a4 Q        pPlayerData-&gt;pPrevious-&gt;pNext = pPlayerData-&gt;pNext;9 X. D  j0 B9 Y' _
        if( pPlayerData-&gt;pNext )- Z7 U1 b( {) x2 H0 R
            pPlayerData-&gt;pNext-&gt;pPrevious = pPlayerData-&gt;pPrevious;</P># n5 `# X$ D% D8 M% u# p! o
    <P>    if( m_pFirstActivePlayerData == pPlayerData )% O% G+ y+ ^, ~! B- Z# v) K5 w# \0 C
            m_pFirstActivePlayerData = pPlayerData-&gt;pNext;</P>
    - r2 O8 E1 a0 H5 }5 R6 b<P>    // Add it to the free list! O# ]* G1 H  N
        if( m_pFirstFreePlayerData )
    2 @2 o  c& M7 q6 b' e        m_pFirstFreePlayerData-&gt;pPrevious = pPlayerData;
    0 r; Q0 e; V1 x0 I2 u    pPlayerData-&gt;pNext = m_pFirstFreePlayerData;
    / P/ z2 V$ b+ e3 `1 F* r9 c1 \. Z    pPlayerData-&gt;pPrevious = NULL;
    * v4 P5 a* I  x1 }    m_pFirstFreePlayerData = pPlayerData;</P>& `0 v; q8 K, g  W
    <P>    // Update count of players$ I3 W4 O9 v: i8 N( S8 }7 l
        m_dwActivePlayerDataCount--;</P>
    , h8 B" b: w9 Z" K% |2 E<P>    UnlockPlayerData( pPlayerData );, r/ {8 u7 G% E1 b+ `
        m_PlayerDataListLock.Leave();# s: p' K1 O& P/ c
    }</P>3 i" t. ]! q. h0 @0 e4 U/ |! a3 o2 m) a
    : Q6 ]$ z, ?% u, J9 B
    <P>/ P/ i& i4 O' ^: E0 G
    //-----------------------------------------------------------------------------
    0 L* i7 x7 U4 T$ h// Name:
    4 B8 c# ?6 c; n% m4 [* j5 M  {, I// Desc: + W; @! p& L% o, g( r  ?
    //-----------------------------------------------------------------------------
      f: M  W; R$ h- B+ x0 q! Xvoid CMazeServer::RemovePlayerDataFromCell( PlayerData* pPlayerData )4 I! I& w* R8 N* |3 p, ^4 _
    {
    " ~* V" `( c2 V) G) a- Y    // Lock the player9 n& X, m* j* Y& j2 B( Q/ m* @
        LockPlayerData( pPlayerData );</P>% S! Z! r& V+ L- j+ U: Y
    <P>    // Lock the cell the player is in  y3 f! v" p8 }4 Q6 V8 q
        ServerCell* pCell;
    3 R" m" F# o5 L5 i# W$ o% f    if( pPlayerData-&gt;wCellX == 0xffff )" [) P$ B) \6 X) O
        {' r/ A5 m: @8 \
            m_OffMapLock.Enter();# T4 V, _, L: p! v+ i
            pCell = &amp;m_OffMapCell;7 G* `( U9 I! c) j; Y8 m) @% I" r
        }+ }! m( t  d; H7 R
        else: d5 K, n5 W. z% ]  e
        {+ x# [1 B/ J( g/ H* s, z1 A
            LockCell( pPlayerData-&gt;wCellX, pPlayerData-&gt;wCellY );
    5 V- _: S2 o" x9 f; r        pCell = &amp;m_Cells[pPlayerData-&gt;wCellY][pPlayerData-&gt;wCellX];
    % s0 |0 O$ j* ~2 n3 X9 l6 c    }</P>
    ) K, X2 Y! S* V2 k# \6 U2 W<P>    // Remove it from the cell
    % q' r1 M; c5 a' z5 w! e    PlayerData* pPt = pCell-&gt;pFirstPlayerData;
    3 ?' A; w2 j0 Q0 a" C1 m0 o    PlayerData* pPrev = NULL;
    " K6 a* c$ g& G, c    while ( pPt )$ f" k% D$ e4 x% z7 g" ~
        {# e( M/ N5 L( h
            if( pPt == pPlayerData )
    1 l+ i9 k- ?  Z; z% `        {" U9 b0 ], N! a! y0 V5 K
                if( pPrev )" ^8 O( h+ T& v6 S
                    pPrev-&gt;pNextInCell = pPlayerData-&gt;pNextInCell;
    . T4 e+ j8 s& T3 m, l+ {7 u' w( A( z            else' }# A2 P; p' z1 f- p
                    pCell-&gt;pFirstPlayerData = pPlayerData-&gt;pNextInCell;</P>, u: A: _1 m2 S
    <P>            pPlayerData-&gt;pNextInCell = NULL;
    7 L/ d; n6 H6 r$ h# i0 |' S            break;/ T. W- Q- V5 c8 j
            }
    $ r+ a" z9 P7 O        pPrev = pPt;( e  R: l. ]- G/ J3 V0 @
            pPt = pPt-&gt;pNextInCell;
    % I# X. r0 d# H6 J% k% o    }</P>- t3 n6 ~! T( S  v" Z# v( D
    <P>    // Unlock the cell" m( A0 R1 Q0 L: `/ i7 `( A
        if( pPlayerData-&gt;wCellX == 0xffff )! l8 ^$ O1 k4 s8 v
            m_OffMapLock.Leave();, X+ j. r; j2 a9 g
        else6 u8 t, s9 \0 W) ~: V
            UnlockCell( pPlayerData-&gt;wCellX, pPlayerData-&gt;wCellY );</P>
    # |; v7 C0 `3 h2 v0 w<P>    // Unlock the player/ w5 Q5 l, U! t# g
        UnlockPlayerData( pPlayerData );
    + c! m( \. S4 _# ?7 c}</P>
    - k: G/ E3 w! c' e, Q; y. Z) `6 `1 A, ^
    2 I0 i! H' a/ R- v<P>; x: v. q0 O( C# S
    //-----------------------------------------------------------------------------4 q2 W  j9 ?. i1 E) ^1 {0 A: h* J
    // Name: 8 p% P2 i/ t! e
    // Desc:
    : e& A% _- d" ^: \, x//-----------------------------------------------------------------------------8 z- D/ ~% k8 y( b( N( g6 ]
    void CMazeServer::UnsafeRemovePlayerDataFromCell( PlayerData* pPlayerData )
    4 D3 s* t: n' b, O- q{
    - j$ p1 \! Q! r6 A$ v* L5 P; P1 t. b$ k    ServerCell* pCell = GetCell( pPlayerData );
    ! q' H, m5 U7 G3 l3 m/ s  z    PlayerData* pPt  = pCell-&gt;pFirstPlayerData;, `# W" f$ y3 N& H5 @
        PlayerData* pPrev = NULL;
    # X$ `+ E" I+ k5 h% L  q3 P$ j- N    while ( pPt ); u4 l$ _5 K2 L7 t/ t. T. c8 U' S
        {& q- T- L& M/ t1 Q% j0 k8 ~4 \
            if( pPt == pPlayerData )' |, I: L3 t1 b, o; T2 T8 D3 u
            {
    $ B1 v" K6 C9 K9 o6 ]5 {  M; M            if( pPrev )/ Y+ S3 f. a/ R4 X
                    pPrev-&gt;pNextInCell = pPlayerData-&gt;pNextInCell;
    7 \' b3 ~: T  ?' b$ i            else
    ; Z2 I3 P4 v1 f9 |4 C  }' G                pCell-&gt;pFirstPlayerData = pPlayerData-&gt;pNextInCell;
    4 ~& A; w% u/ _3 ?3 U7 r+ c5 i( w            pPlayerData-&gt;pNextInCell = NULL;
    - v+ y6 z- _' _            break;
    ) U1 Z7 E! L! Y6 j6 t        }
    8 p4 s9 |9 c$ @6 \1 m. a        pPrev = pPt;$ A2 _  |% [7 p$ ^
            pPt = pPt-&gt;pNextInCell;
    3 S+ B/ n/ {( n4 r+ v( b; G5 C$ f; `    }5 g0 O# y) A# I
    }</P>* v; H2 e6 Q& S, b9 [+ \
      N% R3 h) b, ^1 O( I
    <P>& v* l1 b% t9 [$ _, L- e; Q
    //-----------------------------------------------------------------------------
    ' [! h% \( K8 F5 ]3 i% ^: l0 l! R// Name: * d  g/ H4 `6 {- \
    // Desc:
    " h5 R! O7 B# b. u  f5 A//-----------------------------------------------------------------------------
    4 h" C% L- _, B* Nvoid CMazeServer::UnsafeAddPlayerDataToCell( PlayerData* pPlayerData )8 M% R. {* g1 D
    {
    6 @' t, A8 ^4 ], }, Y4 o/ L# I; M    ServerCell* pCell   = GetCell( pPlayerData );6 S  b; O( U3 ]: x; F
        pPlayerData-&gt;pNextInCell = pCell-&gt;pFirstPlayerData;
    , ]8 I1 o' Q3 h* Q, Y* r: H" A: D    pCell-&gt;pFirstPlayerData = pPlayerData;
    $ c. P3 K" h& l! D6 J* V' h: p}</P>' R. g- Z/ A- }/ @! L' U
    : @8 a/ v4 f7 N+ c8 j) J
    <P>9 V" M# Q/ w  e+ V, D: b( V5 v5 m6 w
    //-----------------------------------------------------------------------------
    + I3 \( Q3 a4 ~" t. O// Name: $ Q; o3 ^$ a3 b& `$ G* C% X% F. j! h
    // Desc: 6 H& A: s8 K8 M3 X  b
    //-----------------------------------------------------------------------------
    4 k  q9 [/ @( q: V; h! ~; wvoid CMazeServer::HandleClientPosPacket( DWORD dwFrom, ClientPosPacket* pClientPosPack )
    / F/ l5 H3 [" A+ I- V{5 s, d5 ^/ H. b: ]6 Z7 j! K. I1 [/ T
        // Grab player for this client and lock it0 U/ ]9 |0 b# H
        PlayerData* pFromPlayer = GetPlayerDataForID( dwFrom );, h; b! G( V9 ]2 F" s( M
        if( pFromPlayer == NULL )
    ' S) b  [" j% P8 K% ]% {    {$ u- K2 |- w9 g( Z2 c
            if( m_dwLogLevel &gt; 1 )
    + I8 |. P7 C, h( j6 m, J9 P4 B. @            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Could not find data structure for this player"), pFromPlayer-&gt;NetID );
    " ]% P9 A+ X% P  E        return;
    4 A9 b; s/ l4 y& h    }</P>
    3 g9 @, w6 i3 `% W# |: {- }<P>    LockPlayerData( pFromPlayer );</P>
    % j8 @2 q# R8 u3 [& W( V  ]<P>    if( FALSE == pFromPlayer-&gt;bAllow )& `. C1 T/ {$ b8 F
        {3 O* j" e2 ^1 r( y: C* s
            if( m_dwLogLevel &gt; 0 )
    : ^: T$ i/ [" X" C+ T            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Got position packet from bad client.  Rejecting client"), pFromPlayer-&gt;NetID );</P>
    % \- l/ d- R$ b& _<P>        m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );
    7 f3 ~* ?" w* B* J/ D        UnlockPlayerData( pFromPlayer );7 S! }; p  y* Q8 s' v
            return;2 M8 w- \; g0 j5 U- W
        }</P>
    " K3 x" k" D+ K; T& F: W<P>    // Compute the cell the player should be in now
    7 H3 q/ y1 v8 G6 X. _" Y: k# b    DWORD newcellx = int(pClientPosPack-&gt;fX);
    - `, u! t- K' ]0 ~    DWORD newcelly = int(pClientPosPack-&gt;fY);
    & e8 k7 H6 W. F% R1 X5 Y. U    DWORD oldcellx = pFromPlayer-&gt;wCellX;
    8 K6 V9 J9 O! d3 B' b    DWORD oldcelly = pFromPlayer-&gt;wCellY;</P>
    8 ]9 Q1 U- }" x9 l6 P  S, A<P>    // Have we moved cell?
    1 P) Z& }! K" _( o1 Q    if( newcellx != oldcellx || newcelly != oldcelly )9 [4 w) X) K! R: z# o: `
        {. x3 K: h+ A) T0 n" X" }
            // Yes, so lock the pair of cells in question+ @9 _/ o' j& R+ L; m+ L
            LockCellPair( oldcellx, oldcelly, newcellx, newcelly );</P>
    1 G; I. w! ~/ X<P>        // Remove from old cell and add to new cell. u* R, v/ D: `  O5 @' {0 q
            UnsafeRemovePlayerDataFromCell( pFromPlayer );2 A7 `* W) ?6 t4 m/ K
            pFromPlayer-&gt;wCellX = WORD(newcellx); pFromPlayer-&gt;wCellY = WORD(newcelly);! E7 z# v: J- `1 z
            UnsafeAddPlayerDataToCell( pFromPlayer );</P>$ s  N2 f9 p) ~- {
    <P>        // Unlock cells
    $ l! `0 ^. I) w, v$ N        UnlockCellPair( oldcellx, oldcelly, newcellx, newcelly );( }& T$ l" x7 ]: }, e9 R
        }</P>
    , A  W+ |' B: [; |, ?<P>    // Update player position* y% t* P: m$ i/ I  B7 ?' T
        pFromPlayer-&gt;fPosX      = pClientPosPack-&gt;fX;4 m9 X9 i% ?* [) Y- @3 ~
        pFromPlayer-&gt;fPosY      = pClientPosPack-&gt;fY;
    & G! c$ x8 T+ f! r    pFromPlayer-&gt;aCameraYaw = pClientPosPack-&gt;aCameraYaw;</P>2 X+ H4 M  A$ U# A; F# h
    <P>    // Allocate space to build the reply packet, and fill in header
    4 U& v. ]+ q8 z7 D$ L( \    DWORD dwAllocSize;( z6 R1 I6 k" {) C5 d- x; p
        ServerAckPacket* pSvrAckPack = NULL;</P>2 Z3 z. P9 W8 H# m9 R
    <P>    // Begin by allocating a buffer sized according to
    " m) N5 U( h/ e/ {2 ]: e0 D) o: F' W" {    // the current number of nearby players + 4.  This will give 6 z- h, e' Q8 P' B" y( K+ P( h
        // a little room for more players to come 'near' without resize# `6 _$ J, d1 e# X' D
        // the buffer./ n* r0 `& f$ h! B( k
        DWORD dwMaxPlayerStatePackets = pFromPlayer-&gt;dwNumNearbyPlayers + 4;</P>
    2 k- j" |7 ^7 \* o( A3 B<P>    dwAllocSize = sizeof(ServerAckPacket) + dwMaxPlayerStatePackets*sizeof(PlayerStatePacket);
      N' O  T9 a# L( l* R! p    pSvrAckPack = (ServerAckPacket*) realloc( pSvrAckPack, dwAllocSize );7 Z; `2 |5 {1 U0 {& K
        if( NULL == pSvrAckPack )
    6 A. B8 \* A- D5 u; P" ?( Z- a+ N* Y    {
    / l1 A# U" A% |# E% T2 r$ ~        // Out of mem.  Cleanup and return
    8 h: m4 k! M% O. b        UnlockPlayerData( pFromPlayer );7 l3 l) x' |9 C
            return;      
    7 {, L  g+ j& Y5 h    }# k* t6 B; J- k) O% \2 j
        ZeroMemory( pSvrAckPack, dwAllocSize );</P>) \% y2 p9 U$ ]( j
    <P>    *pSvrAckPack = ServerAckPacket(m_dwPlayerCount);4 L  b+ D  G  ~7 \; x- j9 x8 {% |
        pSvrAckPack-&gt;wPlayerStatePacketCount = 0;( [. o6 U3 s+ V7 F- W* ^
        PlayerStatePacket* pChunk = (PlayerStatePacket*)(pSvrAckPack+1);</P>
    * U4 U" \3 V0 r+ D  S- I" t<P>    // Compute range of cells we're going to scan for players to send
    ) R! Q! H* Q2 F! x    DWORD minx = (newcellx &gt; 7) ? (newcellx - 7) : 0;. g$ P* C0 q5 n( `) z; C7 p
        DWORD miny = (newcelly &gt; 7) ? (newcelly - 7) : 0;5 o% H& O% M2 M; f1 V
        DWORD maxx = (newcellx+7 &gt;= m_dwWidth) ? m_dwWidth-1 : newcellx+7;# W& W1 \3 G: f) p
        DWORD maxy = (newcelly+7 &gt;= m_dwHeight) ? m_dwHeight-1 : newcelly+7;</P>" Q0 X4 G7 q+ K9 W6 h
    <P>    // Lock that range of cells: s" I6 F* p( p. t/ Q
        LockRange( minx, miny, maxx, maxy );</P>6 O9 L8 q2 H- j; O: S
    <P>    // Scan through the cells, tagging player data onto the end of3 e/ W& b4 ~* U" _  Q  X
        // our pSvrAckPacket until we run out of room; c' s1 m  @0 H+ J$ A; m2 R0 W
        for( DWORD y = miny; y &lt;= maxy; y++ )
    ( l( m$ @( R  b" w* ~+ H0 S    {
    6 e1 o! m$ ^+ O$ k0 X6 h0 X        for( DWORD x = minx; x &lt;= maxx; x++ )8 Q3 L0 L; a7 N
            {9 A4 Q% R) `2 h! Z7 u+ X; Y
                PlayerData* pCurPlayerData = m_Cells[y][x].pFirstPlayerData;
    6 W' s: n2 P% b% s8 U+ t; L            while ( pCurPlayerData )7 W) k- }5 j$ l- a5 r( i% B  u
                {  N, `, K1 Z4 {2 l  X
                    if( pCurPlayerData != pFromPlayer )
    5 B$ w" X- J3 p) J7 C                {
    7 Z8 k+ M) _, @, N5 \- x                    if( pSvrAckPack-&gt;wPlayerStatePacketCount &gt;= dwMaxPlayerStatePackets )
    , O& r' K3 h+ B0 h3 U- O                    {
    # Q9 c* c; n8 I9 F" z* p                        // Make sure pChunk is where we think it is( @7 _( g6 Z- i3 x
                            assert( (BYTE*) pChunk == (BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket)) );</P>
      f" N, i4 F2 K<P>                        // There are more than just 4 new nearby players, so resize the 4 }7 B" Z7 L! L$ R; u# N0 ?2 v
                            // buffer pSvrAckPack to allow 16 more PlayerStatePacket's.
    0 K. G# k' `0 G. Q" L* ?% r& F                        dwMaxPlayerStatePackets += 16;
    4 S/ L% J; G: q                        dwAllocSize = sizeof(ServerAckPacket) + dwMaxPlayerStatePackets*sizeof(PlayerStatePacket);
    % R" R- s, A( t$ O: n( G                        ServerAckPacket* pNewSvrAckPack = NULL;
    8 g2 l7 j& c, I                        pNewSvrAckPack = (ServerAckPacket*) realloc( pSvrAckPack, dwAllocSize );$ A+ U0 S& w* t
                            if( NULL == pNewSvrAckPack )
    ! z; B+ ]+ C8 s; X' R/ Z                        {- G' b: o9 |$ \8 Y% @! s5 t
                                // Out of mem.  Cleanup and return1 i, n3 H* c: Y3 Z/ L( }
                                free( pSvrAckPack );+ T5 O% P1 e5 G3 z  [- t
                                UnlockRange( minx, miny, maxx, maxy );0 y8 E! z8 V; W: d( j7 c9 V# p
                                UnlockPlayerData( pFromPlayer );
    ( ]" k- ~7 g4 |+ ?; c4 w                            return;       ( R* T* [8 X& f2 @' d
                            }</P>
    5 i; v/ h( b, p8 @# t: ~5 b$ y- o<P>                        pSvrAckPack = pNewSvrAckPack;- `% n# h0 y4 }
                            pChunk = (PlayerStatePacket*) ((BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket) ) );</P>
    & S/ D4 ^, N& J: H6 b' K" e<P>                        // Make sure pChunk is still where its supposed to be: j3 Z# Q9 g; l
                            assert( (BYTE*) pChunk == (BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket)) );
    0 }& V7 H0 p/ S! X; R+ q5 G5 F* _                    }</P>- r* |6 }' p1 k4 x4 q: g
    <P>                    pChunk-&gt;dwID       = pCurPlayerData-&gt;dwID;
    : _7 v; r! ]) a9 Q9 D                    pChunk-&gt;fX         = pCurPlayerData-&gt;fPosX;
    / H( o. M  y* C' w( A, {% m                    pChunk-&gt;fY         = pCurPlayerData-&gt;fPosY;
    . [) S" _, \7 G# X) t! o' H                    pChunk-&gt;aCameraYaw = pCurPlayerData-&gt;aCameraYaw;
    + p0 ], L* j8 I0 @                    pChunk++;
    ! A, V1 a7 o7 E: ?                    pSvrAckPack-&gt;wPlayerStatePacketCount++;
    - D3 m" `$ |6 m0 s" _% S                }
    : C2 J% ~6 L; ]* V+ Z" Y" v                pCurPlayerData = pCurPlayerData-&gt;pNextInCell;, y) D& V' `  _# M1 V; r6 C
                }1 C/ {1 T3 x* D& Y, v! X) _
            }
    # m: X& V$ z3 U* @7 x7 |. Y* |    }</P>
    2 P; x6 v  b: y$ H; T  g8 Q" s<P>    // Update the dwNumNearbyPlayers for this player( r5 O* c0 D' N0 t! n
        pFromPlayer-&gt;dwNumNearbyPlayers = pSvrAckPack-&gt;wPlayerStatePacketCount;</P>) {0 U( E1 |; `& w# Q2 _
    <P>    // Unlock range of cells& O: l5 }9 t, j+ ]: a: s6 t' S
        UnlockRange( minx, miny, maxx, maxy );</P>6 a$ P) d3 d- n) j" M5 H
    <P>    if( m_dwLogLevel &gt; 2 )
    " y- K: L5 L6 f8 l) F' B" q    {
    ( n5 i9 w9 {  J+ `- j+ c, _        ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Position is (%0.2f,%0.2f)"), pFromPlayer-&gt;NetID, pFromPlayer-&gt;fPosX, pFromPlayer-&gt;fPosY );
    , l, @6 O' F8 C0 z/ ~    }
    ( H, B* w+ C; L  B    else if( m_dwLogLevel == 2 )1 t6 j0 N0 b. e8 H6 L; c+ I! s$ x
        {
      G: j1 R9 e2 L6 N+ Y; K% G        FLOAT fTime = DXUtil_Timer( TIMER_GETAPPTIME );5 w- u% f: k1 H" d- ^/ v$ x' a
            if( fTime - pFromPlayer-&gt;fLastDisplayTime &gt; 60.0f )! o  H. h# |0 o. |
            {
    7 H! l8 D, {  S' z. b; X            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Position is (%0.2f,%0.2f)"), pFromPlayer-&gt;NetID, pFromPlayer-&gt;fPosX, pFromPlayer-&gt;fPosY );
    ' C4 S1 ]( ]; L( b) l! p6 y6 Y            pFromPlayer-&gt;fLastDisplayTime = fTime;9 ~# r) i: a& Y  d- f( A' t. D9 e
            }$ B1 D3 m8 M6 i, A5 N
        }</P>& A4 [: R" f7 v7 n, W+ P7 _6 N
    <P>    // Unlock the playerdata9 _2 r0 O: m3 ^" z# x; B
        UnlockPlayerData( pFromPlayer );</P>
    $ m! n& I* E3 J, Q+ ^- i7 J<P>    // Send acknowledgement back to client, including list of nearby players
    7 W* z! {/ ]0 y/ Q" k$ u9 @( E" i    DWORD acksize = sizeof(ServerAckPacket) + (pSvrAckPack-&gt;wPlayerStatePacketCount * sizeof(PlayerStatePacket));
    : d% u; y: ^. B; z
    9 s0 U& ~: V: I    // Pack the buffer with dummy data.
    4 U3 Q4 f! n, x7 A' m    if(m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex] &gt; 0)5 b* `6 p6 r6 F) y) c
        {
    - s) F0 K3 A# {. F5 t, \        DWORD   dwBufferSize = acksize + m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex];
    9 q* `$ x0 k- _9 ~2 k        VOID*   pTempBuffer = 0;</P>
    ( z& y0 t6 g/ H  b# V<P>        pTempBuffer = malloc(dwBufferSize);; u! Y8 Y: o7 p% S
            if( NULL == pTempBuffer )/ r8 ]  u+ G2 q( A- d
            {
    * ~' ?3 I* Q$ r$ e. q% d6 j            //Out of memory
    / E: U/ G3 I  v& ?4 Y4 p1 Q& F            DXTRACE_ERR_NOMSGBOX( TEXT("System out of Memory!"), E_OUTOFMEMORY );
    4 [' a3 T! a' e+ Q5 Q            free( pSvrAckPack );2 C$ O- f  \! A$ D& I$ f
                return;- P2 c, ?9 j7 H9 ^7 o: V
            }</P>5 o) D3 A$ C" Y
    <P>        FillMemory(pTempBuffer, dwBufferSize, 'Z');8 k/ `- ]* N# ?9 F' ?# N
            memcpy(pTempBuffer, pSvrAckPack, acksize);</P>
    0 y3 f! R7 B- j) Z+ ~: n<P>        SendPacket( dwFrom, pTempBuffer, dwBufferSize, FALSE, m_dwServerTimeout );+ [( V  J. C( u! i
        3 V7 x, W( G, t% a, `: R' Y+ d' a+ P
            free(pTempBuffer);4 S) ~" z) m8 |) c
        }   " b, y8 u. ^4 j1 @
        else: E' Z+ _  C% D5 s9 [
        {- o0 _) u( ^5 W; s, ]$ V$ F
            SendPacket( dwFrom, pSvrAckPack, acksize, FALSE, m_dwServerTimeout );
    4 i# n- D7 Z2 u! i4 P( r    }</P>
    * h5 k& d5 x" k- B" R9 t<P>    free( pSvrAckPack );</P>( G$ B  o& ^0 x2 ?4 w
    <P>}</P>
    , g* A- d) z  ~0 Y; n* l0 G1 p) e  i$ ?4 Z3 G  d
    <P>. R3 n& C& @9 u
    //-----------------------------------------------------------------------------
    3 n3 O2 _# P- N2 }// Name:
    ( r+ \% I4 a1 z( w5 m: i// Desc: 0 s8 \" r+ x  r% E
    //-----------------------------------------------------------------------------
    ; Y' j; a4 Z( l" k% i" dvoid CMazeServer::HandleClientVersionPacket( DWORD dwFrom, ClientVersionPacket* pClientVersionPack )
    3 f  {1 {' C7 C3 S8 f) B& |9 A{
      F& |6 A. x2 d* L# `& G( w" p/ Z    // Grab playerdata for this client and lock it5 a, a" @! C& n! a4 O  T8 O
        PlayerData* pPlayerData = GetPlayerDataForID( dwFrom );# Q! y) h3 e; E8 ~9 q9 s+ [
        if( pPlayerData == NULL )
    6 x: A# Y  P# R2 R# C        return;
    . {8 k: R: ^- N* W- T/ v    LockPlayerData( pPlayerData );</P>' j( D5 _' J/ `' J( f+ r
    <P>    // Record the version number 2 p; P$ y/ P* Z7 d2 o/ l
        pPlayerData-&gt;dwVersion = pClientVersionPack-&gt;dwVersion;</P>
    1 `6 N* M+ E. k8 D+ w<P>    if( m_bLocalLoopback ). F; I+ c- z) M
            pPlayerData-&gt;bAllow = TRUE;9 J0 h: L( E4 @7 w- a
        else
    - k0 @/ y% O/ X& Y. K' F        pPlayerData-&gt;bAllow = IsClientVersionSupported( pClientVersionPack-&gt;dwVersion );</P>
    2 V6 X) J- v+ n* d& ?- `<P>    if( m_dwLogLevel &gt; 0 )
    4 o/ m: m7 d" X) B: ?9 D( b9 J        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>7 w* w) ^9 ~+ [/ H, T9 ]  {  L
    <P>    if( FALSE == pPlayerData-&gt;bAllow )
    . u$ k* R  V6 C7 q. S    {4 O1 o" B3 h; K9 e9 |, f
            if( m_dwLogLevel &gt; 0 )
    / [1 l3 b' Z2 I9 Q# X. v' w            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Rejecting client"), pPlayerData-&gt;NetID );</P>
    3 J4 y& u6 s! ]5 o* F/ A- E<P>        m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );  _# Z# s  H5 Y: ^" O4 A
            UnlockPlayerData( pPlayerData );
    : p# `4 Y( J5 L        return;
    ! Q, Q/ S6 X" A7 w# C7 q+ E    }</P>
    ! S' u' G% ?6 H: |# l9 m<P>    // Unlock the playerdata8 W$ i* a9 Z, x. H4 W7 _5 ?
        UnlockPlayerData( pPlayerData );</P>' `% e4 j6 ~& ~  k6 C- K
    <P>    // Send acknowledgement to client that the client was either accepted or rejected# {1 ]- O$ _: X* K9 _# {
        ServerAckVersionPacket packet( pPlayerData-&gt;bAllow, dwFrom );+ e6 A4 O* O3 e/ x
        SendPacket( dwFrom, &amp;packet, sizeof(packet), TRUE, 0 );
    2 j* `( H# L% e& H( J}</P>
    $ U! G/ k; ^6 ^# `1 @
    " H( e. O# n1 m' y8 Y<P>5 s, E. U5 V$ T: M
    //-----------------------------------------------------------------------------
    : D( n2 X9 t3 S3 u! }& Q// Name:   j7 e% _9 z0 T: B( Z) J% T
    // Desc:
    : ?: Z( r0 a/ U' H# G& Q6 V//-----------------------------------------------------------------------------" w& [3 g  J4 ^
    BOOL CMazeServer::IsClientVersionSupported( DWORD dwClientVersion )
    / P6 X6 f( w8 N' `{
    / S$ o4 P5 Q" U9 N    switch( dwClientVersion )
    ; _* u  F& v  P$ Q/ p5 T    {9 E% M% Q* b' C$ h/ z
            case 107: // only v107 is supported
    % f% T4 G2 r% `/ p0 Q1 M( U) S            return TRUE;% _! b) }/ }' j8 I
            default:- ]1 X1 Q8 D$ z' ], r- X
                return FALSE;
    9 v  A3 k' @* D6 S    }& u0 z8 Y% ~+ y1 \1 t% H" I0 c) l
    }</P>; V. A8 K+ n/ K+ x# ?  X
    $ B' t5 \0 o( K3 j$ b- Y
    <P>! M8 ~7 u8 d0 X( @0 @
    //-----------------------------------------------------------------------------  U4 a  V1 S9 r# F2 q2 `3 n
    // Name: ! T3 N2 L' K6 U: P, c0 e+ ]2 R
    // Desc:
    , H1 E3 t4 e! ~+ L: ^//-----------------------------------------------------------------------------
    7 g2 H; V  b, _void CMazeServer::HandleUnknownPacket( DWORD dwFrom, ClientPacket* pClientPack, DWORD size )
    6 ^- c' O& |/ z* S/ Z% {{6 t/ N- F* R& ?
        if( m_dwLogLevel &gt; 1 )
    + G$ X6 [( L( f3 a0 l( y1 @        ConsolePrintf( SLINE_LOG, TEXT("ERROR! Unknown %d byte packet from player %0.8x"), size, dwFrom );</P>
      l0 s, J; G3 i3 ?$ v<P>    m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );
    . W6 c2 v2 J, I! n  f}</P>
    4 A5 [+ i1 l9 I( \% k( N. b. u4 F, \5 C) b
    <P>
    6 @5 ^' ~7 ?: e: q0 {//-----------------------------------------------------------------------------5 j: U$ _  H& i: l$ h5 \, L
    // Name: " w0 a% C! G: X' L# N5 e
    // Desc: # J" J$ \0 H! {4 _" _
    //-----------------------------------------------------------------------------
    5 e) C6 k* Q1 `* s! Q: q+ F# e9 kDWORD   CMazeServer::IDHash( DWORD id )
    - N! L1 p: A+ Z! w{5 E7 A- O3 [# u3 ]6 z. n( I  x( @
        DWORD   hash = ((id) + (id&gt;&gt;8) + (id&gt;&gt;16) + (id&gt;&gt;24)) &amp; (NUM_ID_HASH_BUCKETS-1);* v( M" w! L9 u8 h1 \1 s
        return hash;2 Q- f+ m; D8 C+ q
    }</P>$ }( E7 f% t7 Z# N8 H2 M
    " A; w! J" G! r3 }* W
    <P>0 q8 ?7 V, K6 ]4 y8 z
    //-----------------------------------------------------------------------------
    2 j/ z4 U4 ?. K2 m* Z// Name:
    # s7 X% c! Z! c& {: q1 v% S// Desc:
    + H% @8 j7 w0 P' p& z//-----------------------------------------------------------------------------
    6 g. u  [1 F% }void CMazeServer::RemovePlayerDataID( PlayerData* pPlayerData )
    9 l" V6 i4 R7 z+ h; [! u8 G{
      k  [0 b" S) k) L8 o' b' I    // Hash the ID to a bucket number
    4 n( i) ]3 ~5 Y# d4 p    DWORD   bucket = IDHash( pPlayerData-&gt;NetID );</P>
    , @8 q3 [! K5 E* W<P>    // Lock that hash bucket
    " x% }6 ?# p, s) r) R* ]. ]    const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;
    3 `6 C& [2 U' m# _8 s    m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>; o3 I' \9 s  i# W8 \) T6 @
    <P>    // Loop though players in bucket until we find the right one
    7 F+ m' j2 }6 J: H    PlayerData* pPt = m_pstIDHashBucket[bucket];1 _2 s/ i/ x2 }8 Y  {2 E& T5 A
        PlayerData* pPrev = NULL;& _- f  ?0 R4 c5 d, O
        while( pPt )
    ; F2 ]" [+ y; [. W% W* Z    {+ p4 j3 g3 I$ T+ t! ]) {4 Z
            if( pPt == pPlayerData )* e1 @1 d5 i4 b. M! V7 n3 w
                break;: a, @& G- C3 s/ r6 }7 f7 ]
            pPrev = pPt;+ m* `$ `/ S, x7 Q
            pPt = pPt-&gt;pNextInIDHashBucket;1 _# d4 p4 u+ H: }0 l8 {- P- j
        }</P>
    , Z2 q. l# [: M# b! Q( e  t<P>    if( pPt )/ c% c/ C; n/ E, N! l3 l2 ^  y
        {
    0 w" O$ E& s0 V) q1 G" |. p        if( pPrev )
    , n' _3 ^) X7 J7 ]! N7 p            pPrev-&gt;pNextInIDHashBucket = pPt-&gt;pNextInIDHashBucket;2 u  V& J4 `& g0 \2 ]
            else
    + N/ o5 M+ K4 r+ x            m_pstIDHashBucket[bucket] = pPt-&gt;pNextInIDHashBucket;
    ' Z( W/ ]6 L9 `6 r$ U( F  C: d4 \        pPt-&gt;pNextInIDHashBucket = NULL;
    5 \& l; J0 o- q    }</P>
    ( N9 l% S) ^! {6 O<P>    // Unlock the hash bucket2 K3 K# t! b. K) Y  E  x4 q8 j  D% w
        m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();
    , \: R3 U5 X) _# F3 l# e" q}</P>
    ; g# o; [. s1 h! x3 l5 Z+ B. \7 _" ~6 B& r$ Q& e, [6 y
    <P>2 C) Y$ L1 X6 t) {. `& Z0 z! f6 i/ [
    //-----------------------------------------------------------------------------
    3 g0 e9 [8 F7 _// Name:
    7 _# c/ L, R" C* v% g// Desc:
    5 \  M; X1 A! Z2 @  O9 m//-----------------------------------------------------------------------------
    + c* _4 l4 H5 Q- D9 K7 c, Uvoid CMazeServer::SetPlayerDataForID( DWORD id, PlayerData* pPlayerData )
    2 K$ b, p" \$ |! x/ R. E6 L# b{# P, X$ l; B9 J8 F' D
        // Make sure this player isn't added twice to the m_pstIDHashBucket[]
    : g" P4 v4 l0 w5 H. F    // otherwise there will be a circular reference# L" |# M' o4 y, K& i2 ?
        PlayerData* pSearch = GetPlayerDataForID( id );' m/ \) [5 C; {  V! [/ X* ]
        if( pSearch != NULL )8 u( I1 d5 S% C/ M
            return;</P>9 r5 ^4 [6 a+ w1 `" y
    <P>    // Hash the ID to a bucket number
    - \3 m* z4 Y) @' ]    DWORD   bucket = IDHash( id );</P>  m8 y! Y7 w' q8 s/ ~
    <P>    // Lock that hash bucket1 ~. z* a3 |) V1 t5 I% d3 f
        const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;+ _6 [) ^2 C7 o/ w. `
        m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>
    , c; M! z' v# o<P>    // Add player onto hash bucket chain
    " D& B2 r) M+ z* O    pPlayerData-&gt;pNextInIDHashBucket = m_pstIDHashBucket[bucket];, i& T, a' m7 V) H% P8 t; c8 y
        m_pstIDHashBucket[bucket] = pPlayerData;</P>' w3 ^& ?$ @; s2 o
    <P>    // Store net id in player0 P0 w& f3 I2 Z, U1 f
        pPlayerData-&gt;NetID = id;</P>7 @( p% W& y- n; p7 k6 [
    <P>    // Unlock the hash bucket( F, ]/ v) T% r
        m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();
    2 h" _, b$ F" A+ [* K}</P>- f7 ^! b1 W: f. \2 U" U
    . F  M$ J: G; U1 g4 S
    <P>
    6 `0 g9 x1 d; ^4 u3 |7 H0 ?) Y//-----------------------------------------------------------------------------: A5 ^+ Y* ?& j0 k0 }3 H9 h* m
    // Name:
    ' I( i5 \6 F, Y. \; c// Desc:
    - M/ {* m8 h+ D6 l/ a4 K" U/ w//-----------------------------------------------------------------------------
    . R; l1 `# M* ^  C: m9 ^4 T( BPlayerData* CMazeServer::GetPlayerDataForID( DWORD id )
    8 k2 E- I3 ~3 v{
    + t; W1 a& o) _/ W! W" J, N; D    // Hash the ID to a bucket number
    , `, R, B* ?4 x4 U8 K; D4 [3 l    DWORD   bucket = IDHash( id );</P>0 d; m+ z" u$ b1 s' R
    <P>    // Lock that hash bucket. ~. R5 S( j6 d% O
        const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;
    % @" u6 b6 d7 K4 v' S. P    m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>2 K' g9 ]2 ^8 Q
    <P>    // Loop though players in bucket until we find the right one
    7 S+ J! \' b' T    PlayerData* pPlayerData = m_pstIDHashBucket[bucket];
    6 s) Q) a0 T/ a5 s: T$ ~    while ( pPlayerData )
    0 e1 y7 i0 h. o% E    {% e+ X3 t4 c( b1 e
            if( pPlayerData-&gt;NetID == id )
      p* E6 d, @0 a) q6 k- J% ^$ c            break;
    ) y$ g: s$ k4 i4 _+ l2 T; L' U        pPlayerData = pPlayerData-&gt;pNextInIDHashBucket;8 y# z# a, F. Y- P/ r% f
        }</P>, K6 @9 c4 O/ f- P6 I
    <P>    // Unlock the hash bucket4 w3 \5 m& f4 X& i3 d, F
        m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();</P>
    - }' G; }0 o5 |8 V( |<P>    // Return the player we found (will be NULL if we couldn't find it)
    9 `3 s3 d/ S; {3 t3 e    return pPlayerData;
    2 g0 Z% \8 \$ ]! N5 ~}</P>
    , a: Y+ D$ i2 \& n' s( m7 T( t* H( v1 P: C
    <P>& W9 l4 Q$ E3 W1 f# u3 e. X! x
    //-----------------------------------------------------------------------------# k# `9 X5 a$ C1 |1 H/ l2 [
    // Name: 5 M0 N" m/ t' S8 }& U
    // Desc: calls DisplayConnectionInfo for each connection in a round-robin manner" M+ `: {1 a3 J6 L4 Q+ B/ B
    //-----------------------------------------------------------------------------
      ^) j7 F6 P/ D. c" rvoid CMazeServer:isplayNextConnectionInfo()0 T6 Q' u/ _  M4 `+ }$ f+ k6 {
    {1 u0 v8 U/ _8 C" ~. M. l7 |
        if( m_pNet )6 ]0 p# x8 S2 _  d1 K
        {6 Y" L7 I4 S" M. @
            // Find the player that was displayed the longest time ago, and display it.
    . Z$ m! J, B7 Y        FLOAT fCurTime = DXUtil_Timer( TIMER_GETAPPTIME );$ X4 q2 R1 G! x5 ]# K8 a
            PlayerData* pOldestPlayerData = NULL;
    ( O2 Y! T! `& E$ v1 g% f        FLOAT fOldestTime = 0.0f;</P>/ P8 ?* c; K5 o$ T, T1 A8 D
    <P>        m_PlayerDataListLock.Enter();</P>
    2 K/ z8 @' m1 C<P>        PlayerData* pPlayerData = m_pFirstActivePlayerData;
    + |3 c3 `2 h- x) J: F        while ( pPlayerData ); ?  Z6 T" F% A  ~
            {
    2 s5 t* ^, ?8 Z" K- e            if( fCurTime - pPlayerData-&gt;fLastCITime &gt; fOldestTime )7 F/ l0 R0 a9 b/ a, W. A9 s
                {
    + ]! {8 e: P1 e6 g  P) g4 W                fOldestTime  = fCurTime - pPlayerData-&gt;fLastCITime;
    # L/ l9 G. d0 F, ~; f3 y0 w                pOldestPlayerData = pPlayerData;
    : b1 j3 G1 {2 Q            }</P>- j+ Y2 H. l( y
    <P>            pPlayerData = pPlayerData-&gt;pNext;. h- X8 v( t2 R. Q
            }</P>* V$ N2 U1 F0 r2 g& ]7 P+ j6 D. l
    <P>        // Display the player with the oldest CI field, and update its CI field.
    8 \( Z  Q3 F/ l3 _6 Y        if( pOldestPlayerData )+ F' b8 @1 R7 d$ c3 Z9 i
            {# G2 r) J6 U& ^& \8 I, Z
                ConsolePrintf( SLINE_LOG, TEXT("Displaying connection info for next player") );
    $ Q/ N# J7 T: y            DisplayConnectionInfo( pOldestPlayerData-&gt;NetID );
    ( T7 f* w0 R/ N( `            pOldestPlayerData-&gt;fLastCITime = fCurTime;$ F6 h% E! z: _+ C  L" c
            }9 M2 A  y" [* G# ]  j  v$ Y# T
            else
    " d' F4 M, R; i" X; j9 n0 r        {
    7 X$ w5 s* p+ l% T: B5 B            ConsolePrintf( SLINE_LOG, TEXT("No players found") );+ |# p$ M$ k' F" B
            }</P>
    # \9 u& f: S8 k& H  w<P>        m_PlayerDataListLock.Leave();5 y3 x& S% o1 l7 y: U
        }) m4 U, R0 g8 d/ A1 W
    }</P>" _$ m% x9 @- m& t2 e* e5 k
    0 C6 U* n8 i/ X1 m
    <P>
    ( o& U- z3 V( w//-----------------------------------------------------------------------------( E6 w" \1 w4 d% J: Y9 @% n8 C
    // Name:   V" ]  }  _$ L4 r; t$ l" h+ _
    // Desc:
    ; a7 V) B" J! }4 O1 s* z! M) s//-----------------------------------------------------------------------------
    ! U( _  h2 \- d- h" u! d6 O+ O' Hvoid CMazeServer:rintStats()4 D2 k7 V& s1 l* R6 x- i
    {
    , `$ m4 q1 @% i$ w- X% |- l    ConsolePrintf( SLINE_LOG, TEXT("Thread count: Active=%d Avg=%.2f Max=%d"),
    ; K$ ~! j" U" k* w$ }6 Y) J& Z                                    m_wActiveThreadCount, m_fAvgThreadCount, m_wMaxThreadCount );
    + T2 Z3 |6 }6 a9 @* k& Q    ConsolePrintf( SLINE_LOG, TEXT("Thread Time: Avg=%.4f Max=%.4f(s)"),- J9 M5 ?* _# c8 X; X
                                        m_fAvgThreadTime, m_fMaxThreadTime );
    * \+ a/ [( s5 C    ConsolePrintf( SLINE_LOG, TEXT("Players online (not including server player): %d"), m_dwPlayerCount );
    2 ]# D/ I8 U' i/ M0 a# d    ConsolePrintf( SLINE_LOG, TEXT("Peak player count: %d"), m_dwPeakPlayerCount );
    $ D3 V" \: d8 A' f3 e; U3 Y}</P>6 s  a! J) y2 h+ \0 n8 O- i

    " j6 W4 E  e) T9 U<P>) T+ O, Q; u, @
    //-----------------------------------------------------------------------------
    . h& e. M3 ?% [0 w, P! m// Name: , l+ v$ @6 |- \
    // Desc: , @) g) ^% G3 v3 m
    //-----------------------------------------------------------------------------
    % u; u/ ~! ?" x6 l2 ^6 t$ Mvoid CMazeServer:isplayConnectionInfo( DWORD dwID )
    ) C4 h3 g8 F" o" \& q{6 d6 T4 [5 d" B' J: ?+ h
        TCHAR strInfo[5000];
    3 B0 Y7 I- P5 x+ }    TCHAR* strEndOfLine;% h7 E/ s" i9 n# k
        TCHAR* strStartOfLine;</P>
    0 ~7 y! R" u9 d, p6 _3 T<P>    // Query the IOutboudNet for info about the connection to this user
    # O2 M2 g6 n1 L& M6 D    m_pNet-&gt;GetConnectionInfo( dwID, strInfo );</P>$ A5 g% [2 P) m7 [) ?; |- c: r+ P
    <P>    ConsolePrintf( SLINE_LOG, TEXT("Displaying connection info for %0.8x"), dwID );
    ! T# m. L! a; K6 s% g  P" l* h' E    ConsolePrintf( SLINE_LOG, TEXT("(Key: G=Guaranteed NG=Non-Guaranteed B=Bytes P=Packets)") );</P>( B& S# |  i) J4 B2 z- Z  H
    <P>    // Display each line seperately8 M6 h3 p( h6 C, x3 w6 U& }& J: _
        strStartOfLine = strInfo;
    3 U8 P( ]' o4 l+ @0 u/ u: V    while( TRUE )& s9 v/ S. x# c* P4 f
        {- h, R1 e$ J" R! Y; I  j% i: J
            strEndOfLine = _tcschr( strStartOfLine, '\n' );4 o" @( V$ P# ~% k' i# @/ y& I* \+ w
            if( strEndOfLine == NULL )( A+ U0 ?* ?0 s* ~
                break;</P>/ P( g1 R7 y. p
    <P>        *strEndOfLine = 0;
    8 Q) M4 J/ \* g# S8 r# z- ?        ConsolePrintf( SLINE_LOG, strStartOfLine );
    4 R( w9 @1 y6 R8 ]+ E$ ?+ Y6 K        strStartOfLine = strEndOfLine + 1;. E+ R5 z  F, }% l# s* L- s1 a
        }
    . t/ A$ o. ?3 y7 Z; @$ i( A+ H! `}</P>, _3 g' D' h/ }2 Z% J+ n8 O) m
    ' ?5 N+ x5 i* a; b
    <P>
    / D! Q* Z/ Z3 X* t$ H//-----------------------------------------------------------------------------
    ) S3 m$ l2 E: y0 T' l5 M// Name: 6 w) p# Y& K- q: _, C
    // Desc:
    4 U3 {  B. E% p! v% z: D* T//-----------------------------------------------------------------------------
    $ u% Y1 W# w. V1 V8 eHRESULT CMazeServer::SendPacket( DWORD to, void* pData,
    2 g" M# H, n, }6 W" g# o                                 DWORD size, BOOL reliable, DWORD dwTimeout ). S. X. v0 \  k9 ~
    {
    ! }2 u9 ]. K1 n" A4 u: N2 z    // Chance of forcing any packet to be delivered reliably
    # [) S* n0 _! p5 e2 D0 n' r( N    if( m_Rand.Get( 100 ) &lt; m_dwServerReliableRate )$ }# v: L7 E1 Q* `' m
            reliable = TRUE;</P>0 n( ~5 f) M  o0 n) E, \; ?
    <P>    return m_pNet-&gt;SendPacket( to, pData, size, reliable, dwTimeout );
    ; Q4 U2 j' ~) ]8 ?}</P>8 b; ~# [; @1 i, ]  H* R5 D7 n
      J( d7 f) V' _: ~
    <P>
    7 f3 h0 Y7 k4 Y7 ?* x* `7 [! b//-----------------------------------------------------------------------------1 c6 Y$ W8 z! D& W! U
    // Name:
    0 q! a8 }( V; o% V// Desc: # d% Y. ^; T: }" s
    //-----------------------------------------------------------------------------! P  c# A$ P! V% i# O# V" S
    void CMazeServer::SendConfigPacketToAll( ServerConfigPacket* pPacket ), f/ o5 T: ?" ]
    {) p2 Q) D- I% O- W
        // If we're up and running, then send this new information to all clients, o5 a% [. \+ B# o
        if( m_pNet )
    ! l, [9 L, n' S    {: d5 x& u; b: S6 ]3 J
            //Use the AllPlayers ID! s$ o8 q+ c" x* f: P
            SendPacket( DPNID_ALL_PLAYERS_GROUP, pPacket, sizeof(ServerConfigPacket), TRUE, 0 );
    8 E. z0 a/ E1 e- s" T    }
    + D. ^' p6 o" I( k$ B/ S}</P>
    # x' C$ h, \* k. U$ E+ z& X) F2 i& v& q& Y9 p5 i) Z; p
    <P>
    9 |- f7 e: [+ G, `//-----------------------------------------------------------------------------
    % k* k5 m0 \/ u- @# l# ~  c& o// Name: 2 Z6 j* T2 v2 Q6 w3 n3 u: {  A3 k
    // Desc:
    : l! f! ], x8 p% L- q. N//-----------------------------------------------------------------------------9 g. S& Q* b& j# H
    void CMazeServer::SetClientReliableRate( DWORD percent )) l9 M$ D! [1 {6 B
    {
    & V# y  W! d5 r5 D    // Update client config, and build packet containing that data
    5 T& F6 ?7 u4 Y5 D3 R- R9 g    m_ClientNetConfigLock.Enter();
    4 F6 E# B0 M2 C    m_ClientNetConfig.ubReliableRate = BYTE(percent);* u6 z" t& H6 W- Q! w% i) @- X# l  j
        ServerConfigPacket packet( m_ClientNetConfig );1 J3 M- M0 |. N' v9 ^- t4 V
        m_ClientNetConfigLock.Leave();</P>/ j, W7 p0 N! @8 K, i5 i/ {$ o# j) Z
    <P>    SendConfigPacketToAll( &amp;packet );
    - K3 Z8 V' G. A}</P>
    1 |) t/ F& M+ \, m+ j* X$ a
    6 }! m7 L' X  s8 x  b3 Z<P>
    & @' t6 z; ]! P/ V' @) o, S( ^/ A//-----------------------------------------------------------------------------' S  U" g7 C7 q: y1 Z7 B9 e
    // Name: * n3 k' R( t) u! S9 d
    // Desc:
    + m4 p' G2 Y6 I; K7 P//-----------------------------------------------------------------------------
    & J. l( k8 o9 Y# ^' N( _! Svoid CMazeServer::SetClientUpdateRate( DWORD rate )! `9 B1 d  y! z4 z  \2 P$ G- w( X
    {
    - X: Z1 ^6 [- _* y    // Update client config, and build packet containing that data5 g, }% `- O2 S& X$ }
        m_ClientNetConfigLock.Enter();
    ) R/ E3 f# k# J8 n7 M, T' ?' H1 I2 Z    m_ClientNetConfig.wUpdateRate = WORD(rate);
    $ N. q" c/ V$ l1 u3 o    ServerConfigPacket  packet( m_ClientNetConfig );( s! M1 C. h; m0 r& W5 j  i( |7 B
        m_ClientNetConfigLock.Leave();</P>
    ( N: D# D( v9 H+ K, g" @4 K<P>    SendConfigPacketToAll( &amp;packet );) G. [  Y- q3 ]+ N$ ?
    }</P>
    / _5 d" v# C7 ~
    , R$ m2 R* e8 F* ?( D3 p& S<P>
    ( V( f* `; ~4 }  R//-----------------------------------------------------------------------------
    1 f& [7 d/ T- b5 H8 m8 ~5 P// Name: . v% @0 o0 a; m0 @- _1 p: c
    // Desc: 3 {0 r  [( ?  J) |; N
    //-----------------------------------------------------------------------------$ `: l" y! P, S5 j( w4 z. I
    void CMazeServer::SetClientTimeout( DWORD timeout )
    * [, i+ h* x0 P+ m- t{5 O" `9 i+ @8 u( M6 b7 t' s
        // Update client config, and build packet containing that data
    8 V8 q7 O& N& _; \4 _3 e* D2 Q' j    m_ClientNetConfigLock.Enter();
    ! ]2 e0 V  q- |! w    m_ClientNetConfig.wTimeout = WORD(timeout);
    * V9 k0 f% a* z. \0 \. j, W* G6 C    ServerConfigPacket  packet( m_ClientNetConfig );6 t7 K1 U7 s. C9 o- R( b* l6 ?5 e* Z
        m_ClientNetConfigLock.Leave();</P>
    9 K, Y% Y) H/ g; ?* j<P>    SendConfigPacketToAll( &amp;packet );
    : W( _& c" r7 A}</P>* A6 |- Y" o. g+ U  X9 z
    3 B0 t! }$ P, v, b# L& q8 @' s
    <P>; K7 g; N5 _0 I
    //-----------------------------------------------------------------------------. C8 Q2 ?, |% \% V2 H: M
    // Name: 4 Q- ]- x- A, n# f! ~" _3 R
    // Desc:
    / |, a$ t" T# n& G: c( Q4 N//-----------------------------------------------------------------------------
    # s. S. S  E5 v' Cvoid CMazeServer::SetClientPackSize( DWORD size )
      a! s. x4 b3 Y) M* t! L{3 U( a7 R1 R7 s* o0 n
        // Update client config, and build packet containing that data& B: y1 t' A, h1 T$ G8 b
        m_ClientNetConfigLock.Enter();. w( z  }. K% x% B3 Z/ w( A
        5 p" S5 `: M4 `$ a
        m_ClientNetConfig.ubClientPackIndex++; //Increase index and verify location in array.
    % _3 X; n* S  N0 w    if(m_ClientNetConfig.ubClientPackIndex &gt;= PACK_ARRAY_SIZE)   7 \3 k5 k% g. U( b
            m_ClientNetConfig.ubClientPackIndex = 0;</P>: K& Q. o; `2 I: Q5 D
    <P>    m_ClientNetConfig.wClientPackSizeArray[m_ClientNetConfig.ubClientPackIndex] = WORD(size);
    ) L; o6 M# m  }$ G% Q8 f    ServerConfigPacket packet( m_ClientNetConfig );
    6 [. f! h& I5 m5 T, S( o7 l9 ]    m_ClientNetConfigLock.Leave();</P>
    8 t9 @5 _0 Z$ J; E9 e/ @1 C' ~<P>    SendConfigPacketToAll( &amp;packet );
    # C! f8 y  }. \}</P>
    $ i; q' v& A' W, h& S" g+ G9 W) A% m4 h3 U" _
    <P>
    ( l0 H% w- f. z% k//-----------------------------------------------------------------------------0 W) B' Z. v3 ~! I, I; c
    // Name:
    2 r6 E! k$ k  K* L! e% x( u// Desc: ; h1 v1 M* Q1 J3 E
    //-----------------------------------------------------------------------------( t. M5 a; k9 E) W- Z$ g- N
    void CMazeServer::SetServerPackSize( DWORD size )6 U. P$ ^3 H2 S( J. Y. ^0 M' d; X
    {! l2 y3 y. F$ C3 V3 q9 T0 W- T
        // Update client config, and build packet containing that data  L8 {7 h/ {- j. f9 g0 s# T
        m_ClientNetConfigLock.Enter();
    # o# ?+ m( L9 }! z- C    $ O1 b4 g) G7 r, r! C
        m_ClientNetConfig.ubServerPackIndex++; //Increase index and verify location in array.- C! j/ r- A4 ^3 X5 k3 l, @( ~1 b
        if(m_ClientNetConfig.ubServerPackIndex &gt;= PACK_ARRAY_SIZE)   & ^3 x; \' W+ i, `0 H
            m_ClientNetConfig.ubServerPackIndex = 0;</P>. I$ i5 X; u" n( o; s- `, q! p6 J5 V& a
    <P>    m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex] = WORD(size);/ @5 h: [9 G( i- ]0 K* }% R0 F
        ServerConfigPacket packet( m_ClientNetConfig );
    ; e( H, T, i0 V, L, D5 q    m_ClientNetConfigLock.Leave();</P>
    $ J) Q* J4 A5 ^! H; I0 q+ u; q  R7 {" P<P>    SendConfigPacketToAll( &amp;packet );
    % I3 Q8 e5 h4 J" d' k/ _}</P>
    4 |$ P. u& L. n: w6 t* O: a+ n<P>6 h: ^" y/ y: `) t3 m8 S# M
    //-----------------------------------------------------------------------------. B9 n* [' H: W& s- ~* @
    // Name: ; m4 ~- G. ^& J
    // Desc:
      B4 s! A- v; k//-----------------------------------------------------------------------------
    # W6 `3 u4 F' h: D' qvoid CMazeServer::SetClientThreadWait( DWORD dwThreadWait )4 |9 d6 E) i1 J! s/ @$ [3 \  E
    {
    . j; f: ~  G1 {' c) e0 W: |) O    // Update client config, and build packet containing that data
    6 B5 T7 _% J" n- K3 C    m_ClientNetConfigLock.Enter();
    $ t2 I, y) \+ d! Q   
    $ U7 u! g: I! o5 X# l$ f    m_ClientNetConfig.dwThreadWait = dwThreadWait;
    ; g: b' @& S* b+ l% n5 {6 p    ServerConfigPacket packet( m_ClientNetConfig );8 I0 E4 Y. k8 _: d8 t+ I- a) p8 B
        m_ClientNetConfigLock.Leave();</P>
    & h$ {' p% m/ y; w7 m0 N- t<P>    SendConfigPacketToAll( &amp;packet );0 m( f7 F% _- v6 g, t# z
    }</P></DIV>
    zan
    转播转播0 分享淘帖0 分享分享0 收藏收藏0 支持支持0 反对反对0 微信微信
    您需要登录后才可以回帖 登录 | 注册地址

    qq
    收缩
    • 电话咨询

    • 04714969085
    fastpost

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

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

    蒙公网安备 15010502000194号

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

    GMT+8, 2026-6-15 15:31 , Processed in 0.434834 second(s), 51 queries .

    回顶部