QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 4184|回复: 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>
    - M* ^8 B0 d5 n3 N+ D+ u<>// File: mazeserver.cpp9 b: P1 i: |4 O! ~! m- ?) v8 D
    //
    : b' i; P& R  Q! g/ X  u// Desc: see main.cpp
    ' G5 N& \0 V( p7 Q  J' f//
    # N2 l/ U5 l7 g2 D/ i- n" s+ _// Copyright (c) 1999-2001 Microsoft Corp. All rights reserved.
    ' O$ Q( T2 Y7 S//-----------------------------------------------------------------------------
    # j9 C8 h9 a+ Z- ]#define STRICT( s" ?  k4 @% s5 Q2 x; ~
    #define D3D_OVERLOADS* @) m1 M+ a- j
    #include &lt;windows.h&gt;  y! Q# F$ n- i% e3 X9 R
    #include &lt;d3dx.h&gt;  T, |4 i3 Q$ s- N* n4 ]
    #include &lt;stdio.h&gt;
    6 {% w9 W$ {- _, D; j3 |, S#include &lt;math.h&gt;1 {3 |& V! n8 j- |3 B5 R9 ~
    #include &lt;mmsystem.h&gt;. [4 ]; h/ W2 F, X
    #include &lt;dplay8.h&gt;' ?& t: [& W) @& {7 P. D' }
    #include &lt;dpaddr.h&gt;
    ( c! r& W5 L- \3 l- E  Y  a#include &lt;dxerr8.h&gt;9 _  n; T' [; ?; o- C0 X
    #include "DXUtil.h"
    & f, C- j( o2 \7 K9 ^' @* J: j#include "MazeServer.h"' W3 \. p, p, f; ~
    #include "ackets.h"
    0 l; Q! t) @" K) k6 h  @#include "Maze.h"
    9 Y. E9 t& S$ C% B#include &lt;malloc.h&gt;
    - i8 M' U7 R  H# V% s' Z#include &lt;tchar.h&gt;</P>
    ) y5 b; p! K4 a. C3 x
    9 ~8 P8 K/ s* E1 ?" o4 P<>//-----------------------------------------------------------------------------" Q- _5 w& N; v) |' |" |7 `
    // Name:
    $ m3 ~* J: H, b2 |& ~6 A6 E// Desc: & r6 b. ~8 h) R( j" ~: n
    //------------------------------------------------------------------------------ S' H4 S* X8 d" d5 d9 U
    CMazeServer::CMazeServer()
    & G* P8 w- l: [8 W% g6 e6 V{
    1 t- c) b! Q  V* m% D+ O% u6 k. s    m_dwPlayerCount         = 0;" v. y) j4 Y' U7 l, K
        * @7 N) N' M5 @
        m_wActiveThreadCount   = 0;
    ' X  J, y, G+ D( ]5 m" n+ I    m_wMaxThreadCount      = 0;
    6 E& L& R' q7 }5 g4 e- U7 x& r1 Z    m_fAvgThreadCount      = 0;
    ( I2 [0 M$ j: D* m( ]    m_fAvgThreadTime       = 0;
    ( j, u: Y! G8 c9 Y9 R    m_fMaxThreadTime       = 0;</P>
    ( D0 f, @8 v) {+ P; O7 n" d<>    m_dwServerReliableRate  = 15;* t, q' K0 Y' k6 _6 k$ O
        m_dwServerTimeout       = 150;
    ) k3 x5 Z" e  l9 g    m_dwLogLevel            = 2;
    ! X- Z- ^6 N/ Q2 a! n" M4 a7 E    m_pMaze                 = NULL;</P>/ d3 z2 e4 T( l  j+ s
    <>    m_ClientNetConfig.ubReliableRate = 15;
    ; w) u0 `. U8 x: V) z    m_ClientNetConfig.wUpdateRate    = 150;7 g# [2 u5 K) i. o
        m_ClientNetConfig.wTimeout       = 150;</P>
    - _  i' V" T8 e& R7 N8 A<>    m_ClientNetConfig.dwThreadWait = 0;</P>
    ! _0 g3 [: ]: Z$ R. O5 I<>    m_ClientNetConfig.ubClientPackIndex = 0;
    % m# P1 k# I' n6 r5 j    m_ClientNetConfig.ubServerPackIndex = 0;
    0 c) z. I% E9 L    for(WORD x = 0; x &lt; PACK_ARRAY_SIZE; x++); T) v6 v$ N1 _/ q
        {: ^$ h! K$ h! X( _# u1 W# x
            m_ClientNetConfig.wClientPackSizeArray[x] = 0;
    $ h8 E5 [4 {- ~% g: ], k        m_ClientNetConfig.wServerPackSizeArray[x] = 0;
    9 t+ c0 o4 |" J( T    }9 s: |6 }+ l/ B- L0 w! I9 ]7 y
    }</P>
    - ], G6 Z0 T% A4 t  n) r0 q1 ^5 e; g: J2 J+ i+ A
    <>- m4 x$ K9 O: U
    //-----------------------------------------------------------------------------7 M- J$ r3 q, D: _8 z
    // Name:
    - V) V* L% \3 m4 V// Desc:
    8 _. q! w. q+ x4 m; k//-----------------------------------------------------------------------------
    + Z! D2 F" J6 O3 \HRESULT CMazeServer::Init( BOOL bLocalLoopback, const CMaze* pMaze ), `: P, [4 u1 K" B
    {
    ) Y' u2 |9 w  R4 X# W    m_bLocalLoopback = bLocalLoopback;8 f. W# x' H5 W2 N$ w
        m_pMaze = pMaze;
    . Q# K/ Z7 n8 c1 p    if( m_pMaze == NULL )
    * E) k/ C- l; F        return DXTRACE_ERR( TEXT("aram"), E_FAIL );</P>
    / Z5 M; W  D4 m8 Q* h<>    // Grab height and width of maze
    3 [+ e1 W( `# H: s& X, ~: r    m_dwWidth = m_pMaze-&gt;GetWidth();5 C( b) D) U# [
        m_dwHeight = m_pMaze-&gt;GetHeight();</P>* w' S3 i! A5 X. O( S3 m2 w
    <>    m_ClientNetConfig.dwMazeWidth  = m_dwWidth;
    % B; H' D2 O3 A    m_ClientNetConfig.dwMazeHeight = m_dwHeight;</P>1 M. O; e; t0 {4 F) C8 v
    <>    // Validate size. Must be a power-of-2 times LOCK_GRID_SIZE. Compute the shifts.- o+ I3 {% U9 I8 s% y8 A% L
        if( m_dwWidth &gt; SERVER_MAX_WIDTH || m_dwHeight &gt; SERVER_MAX_HEIGHT )! v! S$ N  s$ q( m3 u
            return DXTRACE_ERR( TEXT("Maze height and width need to be less than 128"), E_INVALIDARG );
    / O+ p# o: q- F    if( (m_dwWidth % LOCK_GRID_SIZE) != 0 || (m_dwHeight % LOCK_GRID_SIZE) != 0 )& o8 I% q% N* `
            return DXTRACE_ERR( TEXT("Maze height and width need to be divisable by 16"), E_INVALIDARG );</P>+ n& k( |* E% }- K
    <>    DWORD scale = m_dwWidth / LOCK_GRID_SIZE;
    ( W0 j& W2 a, ?, @/ ]$ f# p    m_dwMazeXShift = 0;4 e' q) T# [! M9 ~1 `
        while ( (scale &gt;&gt;= 1) )1 A" T( i% t& {  W
            m_dwMazeXShift++;</P>
    7 Z& y& f7 ^3 _6 K1 n<>    scale = m_dwHeight / LOCK_GRID_SIZE;' d! C. o3 _, `$ \: \0 n
        m_dwMazeYShift = 0;/ K/ f' T9 m: w  h0 E9 L4 ?
        while ( (scale &gt;&gt;= 1) )  d% T  x" W- `9 Y3 c6 \4 n
            m_dwMazeYShift++;</P>: G6 F6 R' `+ W
    <>    if( ((DWORD(LOCK_GRID_SIZE) &lt;&lt; m_dwMazeXShift) != m_dwWidth) ||
    ) f% S: W1 ?3 r1 _) F        ((DWORD(LOCK_GRID_SIZE) &lt;&lt; m_dwMazeYShift) != m_dwHeight) ); A, C3 Z; e( b) G& P; H- q( L
            return DXTRACE_ERR( TEXT("Maze height and width need to be power of 2"), E_INVALIDARG );</P>1 m' h& c7 M' N# |; t' `
    <>    // Initialise the player list
    ) U  e# `: k! Y: e( Y3 A    ZeroMemory( m_PlayerDatas, sizeof(m_PlayerDatas) );
    $ I; X5 _5 j; O5 o/ ~" N' T    m_pFirstActivePlayerData = NULL;) K, h4 r2 P$ t0 O/ T$ x  A
        m_pFirstFreePlayerData = m_PlayerDatas;# ~+ D' r2 J, K7 k, \
        for( DWORD i = 1; i &lt; MAX_PLAYER_OBJECTS-1; i++ )# u: z+ `: z6 n5 A, R. E
        {
    % t8 n# ?# B" u; O        m_PlayerDatas.pNext = &amp;m_PlayerDatas[i+1];
    ) r- |4 h6 ?  s; s% s        m_PlayerDatas.pPrevious = &amp;m_PlayerDatas[i-1];$ ?' J* J* U$ n
        }</P>
    9 w0 F9 Z4 B% }<>    m_PlayerDatas[0].pNext = &amp;m_PlayerDatas[1];- v. h, O: G2 @- ]! }
        m_PlayerDatas[MAX_PLAYER_OBJECTS-1].pPrevious = &amp;m_PlayerDatas[MAX_PLAYER_OBJECTS-2];
    1 T/ g& }% v" `$ G* P    m_dwActivePlayerDataCount = 0;. C1 M9 F  R5 F; s2 Q
        m_dwPlayerDataUniqueValue = 0;</P>" D& ~* N  w  l* s
    <>    // Initialise the cells
    6 a: @, N+ k6 D1 l6 h2 g. n    ZeroMemory( m_Cells, sizeof(m_Cells) );9 T8 p7 w" I, w! M
        ZeroMemory( &amp;m_OffMapCell, sizeof(m_OffMapCell) );</P>  o9 P$ C5 p; R/ ^, @' `
    <>    return S_OK;6 S# ]9 D7 b2 N) Z2 [* A( J" A
    }</P>
    7 H) c; f- [4 E( y% f5 [6 ~
    ; h' T. u  q  U/ V( I$ o5 ^- `8 w<>. g0 Q# ~! @) N- J, o
    //-----------------------------------------------------------------------------! C1 {, V9 U0 w& |6 H5 o. t
    // Name:
    5 [2 P2 X* ~$ N* y4 S, u% W// Desc:
    . T! C' w8 V) I, @. g//------------------------------------------------------------------------------ U* r  @$ Q! j2 g2 F
    void CMazeServer::Shutdown()
    / S0 z5 j: V) t& \7 Y) y8 U{* c1 _# o2 g# q) L$ m& ]& ~
    }</P>) S' y" Y* V$ _

    5 l! [5 s: [0 ^0 |<>& e! ?6 z! q: T5 d8 r5 @2 a1 |
    //-----------------------------------------------------------------------------
    2 d; Y/ ]! j6 }- R) R// Name: * [( V9 k& t; I/ ]( ?
    // Desc:
    - |% k3 ^: Z+ A' ?" [  N//-----------------------------------------------------------------------------) s/ D$ s, h  U# [
    void CMazeServer:ockRange( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )/ b) e2 Z' `4 H' i" ~
    {
    & P* M/ K& M& _, I4 y# o; S3 d    m_LockGrid.LockRange( x1&gt;&gt;m_dwMazeXShift, y1&gt;&gt;m_dwMazeYShift ,
    $ E4 ^& u, r& L7 T                          x2&gt;&gt;m_dwMazeXShift, y2&gt;&gt;m_dwMazeYShift );# O8 ?2 ~' H- s8 F3 V& W. f
    }</P>
    ) f3 s3 C" z" N( O
    3 {% G: Z  K% W+ q<>
    4 m; _0 _$ f- j* L' T4 A//-----------------------------------------------------------------------------
    ( g2 _6 o' j+ Y/ y% R// Name: 2 i# p* z$ p5 [2 `2 N# o7 U: b5 ~6 F
    // Desc:
    : y$ U' N5 t, d  {/ n//-----------------------------------------------------------------------------
    7 Y  `3 A( v( E: i9 {# Fvoid CMazeServer::UnlockRange( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )
    , G  }& q5 ^0 n9 |0 j; w{
    + a( q6 D" ]9 \( @    m_LockGrid.UnlockRange( x1&gt;&gt;m_dwMazeXShift, y1&gt;&gt;m_dwMazeYShift ,
    . S) V) V2 ^3 R9 L$ d                            x2&gt;&gt;m_dwMazeXShift, y2&gt;&gt;m_dwMazeYShift );' T* m+ s: J, ^" D7 d. s  ^4 J
    }</P>' h" I+ M! \. P+ \5 o( g2 D) y2 F

    4 ]& d& g5 P2 N# D7 u2 l* [<>5 E4 S& Q7 d, ]4 ]! ^7 `
    //-----------------------------------------------------------------------------# q4 u. Z% m. }* Z7 b$ y
    // Name: 2 g+ Y- u: S7 l2 R7 z6 a
    // Desc: * ^. V! z$ F5 u( Q3 ~" t
    //-----------------------------------------------------------------------------9 P7 ]0 Z9 m" A. J) W, E8 g, N
    void CMazeServer:ockCell( DWORD x, DWORD y ), s" U( u2 ]7 t; T% B: E) S
    {' y1 W0 e& O) B2 s) A* J
        if( x == 0xffff ), b+ i! x) r( B
            m_OffMapLock.Enter();4 R8 |) L) ]& K3 d; `- i
        else7 }- f* U; z2 y
            m_LockGrid.LockCell(x&gt;&gt;m_dwMazeXShift,y&gt;&gt;m_dwMazeYShift);: V2 k: Y* Q- ^# e$ g9 x8 u0 k
    }</P>
    - R5 X0 h/ I  j/ `: V" N  g$ I6 W# f; {* {. U: e: j5 g0 n
    <>
    / k- u$ |! v# n1 G1 q0 @5 @$ c5 k//-----------------------------------------------------------------------------
    1 G! }0 l* |& j* h// Name: 6 L1 q& s& g" }. L+ u4 v1 a
    // Desc: / t4 A  [! ?' y6 d+ [* Z
    //-----------------------------------------------------------------------------8 i' E9 [0 j4 b% h' L
    void CMazeServer::UnlockCell( DWORD x, DWORD y )0 Y. I0 a6 A8 G2 |; M0 f! D
    {' d6 V- K0 e+ ^7 n
        if( x == 0xffff )
    / V% _2 {9 J+ t+ K! D        m_OffMapLock.Leave();/ O5 Y; v; S. R# G
        else
    9 ^. D2 |7 J1 v        m_LockGrid.UnlockCell(x&gt;&gt;m_dwMazeXShift,y&gt;&gt;m_dwMazeYShift);
    5 n6 w* ^" O6 b3 T6 ~& ?}</P>
    0 c  g3 g& Z$ y5 ]/ i5 E# D
    , u5 j7 T4 M7 ]<>  r2 }# d7 P- s4 ]3 \' a" {9 G! p
    //------------------------------------------------------------------------------ {9 U1 Y# F$ e, }" j
    // Name:
    5 H( P) G' s! n1 Y5 U4 y// Desc: ; Z/ }1 O9 w$ u9 ?/ S% T4 F
    //-----------------------------------------------------------------------------, j" ~. x7 m" X
    void CMazeServer:ockCellPair( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )! {/ F* o) J+ y3 j; r9 V
    {
    * e" b  a* R' o! g5 d    if( x1 == x2 &amp;&amp; y1 == y2 )' o! E: ?6 H  K2 S
        {  h1 T2 Q8 s+ M  O+ R
            if( x1 != 0xffff &amp;&amp; y2 != 0xffff )2 x/ H" ?" v9 H2 G# K
                LockCell( x1, y1 );
    : N4 _/ c$ ^: ]& {) F        else
    3 ]) M/ k) N- W0 F7 q2 G            m_OffMapLock.Enter();</P>; }- {3 x7 K- z  a6 }
    <>        return;
    1 K/ T8 M& K: A5 V) L5 n* Y) N1 x0 |    }</P>7 O. K) l+ p& W2 a$ X3 t
    <>    DWORD x1shift = x1&gt;&gt;m_dwMazeXShift;1 K+ {! T, I- D3 w
        DWORD x2shift = x2&gt;&gt;m_dwMazeXShift;
    . Z3 X8 g: i$ _" \( c; N0 t* _    DWORD y1shift = y1&gt;&gt;m_dwMazeYShift;' p# _4 |  u6 b, s# e
        DWORD y2shift = y2&gt;&gt;m_dwMazeYShift;</P>" o+ v% Z. F% c; X! \% S
    <>    if( x1 == 0xffff )
    % G* n# U, ^( f: Q6 m7 D( R3 o$ B    {* j5 I. k$ {4 Y, z% m, M4 k6 R& b
            m_OffMapLock.Enter();
    2 ^# }# b- j1 x6 \. C        m_LockGrid.LockCell(x2shift,y2shift);. V, P) M- V; u7 D1 F* D( u
        }: C( y. T" }1 P
        else if( x2 == 0xffff ); B  }+ }0 v1 z4 L& ?: t, C
        {
    - Z- N0 Z- ^  `        m_OffMapLock.Enter();. o( Y, L3 G7 s* B
            m_LockGrid.LockCell(x1shift,y1shift);0 [- g! h' y+ @7 r8 d4 ^
        }9 T) h2 Z3 p& ]5 l
        else ! w* d) S7 [& i, `: ]  b2 [! j
        {4 f3 A$ {9 Q: w: s$ t, D
            m_LockGrid.LockCellPair(x1shift,y1shift,x2shift,y2shift);) b0 V1 H, D% ?: @1 H
        }
    . q" s' [8 u( |" b1 Q}</P>
    / Y% x5 V# x$ ~+ I7 r8 }
    + a$ S4 [, }1 E' O, H" H1 X<>/ u8 y- Q4 E. k& \; H0 f
    //-----------------------------------------------------------------------------3 `0 B5 X6 U+ R+ c
    // Name:
    5 p9 D! \. {6 r+ T# _8 A( L" c// Desc: 2 q0 p& f8 c" |9 r1 b* N) e
    //------------------------------------------------------------------------------ [! g% _. b3 L( v: J
    void CMazeServer::UnlockCellPair( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )
    ( i# Q  Y$ G: F3 Q{
    , Z5 o/ j# E, ^2 ]' p    if( x1 == x2 &amp;&amp; y1 == y2 )' }& B- z5 `9 Y' J9 U* W
        {
    + S/ d/ u4 l( B1 c4 @& p" P9 V0 U        if( x1 != 0xffff &amp;&amp; y2 != 0xffff )' C9 f+ u) W5 l, ]4 |9 B8 D, Z4 \: I
                UnlockCell( x1, y1 );
    ' s+ B+ `/ k6 ?- A. t        else3 D( y1 O# h1 \; J  ]
                m_OffMapLock.Leave();</P>8 W. Y3 f! @7 C9 _
    <>        return;# s0 ^" C5 P" I  X& h, [- N" _
        }</P>: d# K0 O/ h8 T
    <P>    DWORD x1shift = x1&gt;&gt;m_dwMazeXShift;
    " _1 \, P& M  j4 v    DWORD x2shift = x2&gt;&gt;m_dwMazeXShift;8 E+ v* y# c9 e# U! @; E$ A/ j) t
        DWORD y1shift = y1&gt;&gt;m_dwMazeYShift;1 g3 q, D& b- I" o$ K( G! t
        DWORD y2shift = y2&gt;&gt;m_dwMazeYShift;</P>3 d, c8 d7 Q2 h. u3 X; e. \0 m; h
    <P>    if( x1 == 0xffff )
    ! F5 f! b2 u1 t, c& Z    {
    7 S4 Y+ |+ A; X' r9 i+ C        m_LockGrid.UnlockCell(x2shift,y2shift);
    ) V% G! C1 l8 u6 N/ y) @        m_OffMapLock.Leave();
    0 ?, z" v$ w" \$ Z5 \: k0 u    }2 i3 N: h. {3 I6 ^2 O& a4 J
        else if( x2 == 0xffff )+ p& E. z  C2 l9 E6 P& I! J
        {
    # v) ]) u) }9 ]        m_LockGrid.UnlockCell(x1shift,y1shift);
    9 \1 j9 e; z, ~9 s& V% c/ n        m_OffMapLock.Leave();; h/ e  m! N0 V
        }
    4 v7 K9 y2 a& f5 _8 g+ _    else
    9 F' K# F3 n. y( J    {
    . h# b' z# q- q, _6 _        m_LockGrid.UnlockCellPair(x1shift,y1shift,x2shift,y2shift);7 A" X, r  I, H2 P4 E6 g% K
        }) G7 W% ?4 }! D1 }2 u+ q
    }</P>6 e  B- x$ L, x+ Q. N& V; l# a

    * g* B* E4 g  j8 B* p# Q& ]2 [<P>+ n2 F# g. [" F. W; L3 \
    //-----------------------------------------------------------------------------; ?$ d+ K8 W! W
    // Name: , Y, o& D3 M  g( {8 g
    // Desc:
    $ h( B7 ^2 x9 f: J* Z. h3 r; B//-----------------------------------------------------------------------------+ Q6 f3 N4 N, \! J5 l" d! f! ~
    void CMazeServer::OnAddConnection( DWORD id )4 c+ Z  C) Q# e8 g, i
    {) q* E# N1 R; v" U3 m3 ]
        m_AddRemoveLock.Enter();</P>
    % l+ T6 s9 ^" R- q' d6 Z8 L( }( K<P>    // Increment our count of players
    : `/ H! p6 p% K. V5 ~    m_dwPlayerCount++;
    5 H2 f  b; c& t    if( m_dwLogLevel &gt; 0 )
    , i& g9 p% j/ l1 r" b( A; B  M1 J    {1 }3 l. H# M7 t
            ConsolePrintf( SLINE_LOG, TEXT("Adding player DPNID %0.8x"), id );
    0 I6 {+ X7 A6 ^$ g2 d7 M        ConsolePrintf( SLINE_LOG, TEXT("Players connected = %d"), m_dwPlayerCount );
    ) X1 C9 H, w- O- t! C* W    }</P>
    ! I0 M8 N; [' h<P>    if( m_dwPlayerCount &gt; m_dwPeakPlayerCount )
    6 v: `5 H; k8 B! c1 r  M9 N        m_dwPeakPlayerCount = m_dwPlayerCount;</P>5 t4 f3 P0 {4 {
    <P>    // Create a player for this client
    & q- Z9 f. \! \: r2 x: y# i    PlayerData* pPlayerData = CreatePlayerData();
    4 J, u; N) y) T9 Y# }    if( pPlayerData == NULL )
    , h6 r* {& R2 v" I$ W+ x: ^    {) I5 s6 A7 i% Z, n4 x
            ConsolePrintf( SLINE_LOG, TEXT("ERROR! Unable to create new PlayerData for client!") );
    $ w: L! b/ ]* x& ?) S$ F        DXTRACE_ERR( TEXT("CreatePlayerData"), E_FAIL );
    5 t: U' f8 g& E/ y  a. Q        m_AddRemoveLock.Leave();
    ( W- d/ |+ x- \5 ?: O        return;
    0 C1 @+ Z& k9 q9 X* N$ O    }</P>
    ( s- y. b# `/ K+ T% L9 e+ \<P>    // Store that pointer as local player data
    % }3 J  ^' J0 s, M9 [! M! n# t    SetPlayerDataForID( id, pPlayerData );</P>  X( d/ ]' S* ]
    <P>    // Grab net config into to send to client
    1 t* E1 s" j/ t* c& ^    m_ClientNetConfigLock.Enter();, a- o! b1 q  x. Z/ ?1 c
        ServerConfigPacket packet( m_ClientNetConfig );
    , G" ^% ^4 c! j/ \9 L- T0 @9 O    m_ClientNetConfigLock.Leave();</P>
    % u3 [0 b1 P: \  F! x( R' N<P>    // Send it, n! K5 J: \  w
        SendPacket( id, &amp;packet, sizeof(packet), TRUE, 0 );</P>
    ; u4 h# M# _4 s7 [<P>    m_AddRemoveLock.Leave();
      v! z" K: D# ~9 ?! c. }5 t}</P>% P% A) {/ L! w$ x
    , Z& E. }. A+ v; I" W" H& \
    <P>" b5 A( H/ l( a% T- s9 _2 N( [
    //------------------------------------------------------------------------------ J2 ~: ?2 N) R7 Y1 |: Q
    // Name:
    & i# x5 l! ^" k. z/ z4 ^// Desc: / d6 f! g8 D0 O7 W+ W
    //-----------------------------------------------------------------------------$ R! ^5 b8 q' L# t6 ]/ m! Q
    void CMazeServer::OnRemoveConnection( DWORD id )
    7 b8 |' ?* n4 h; t* B! K; _* ^0 Y{1 U& Q) e; }) h& s( ~! s
        m_AddRemoveLock.Enter();</P>$ p4 H" P& V" v- B! h2 u6 I/ p
    <P>    // Decrement count of players. U+ Z4 @3 e- r1 ~1 L" K" w
        m_dwPlayerCount--;</P>
    & L# x& K5 p5 T8 g7 L0 G<P>    if( m_dwLogLevel &gt; 0 )
    6 F1 x$ k/ ?6 X$ M    {
    # `3 }. l& _6 b" V" h- g  K        ConsolePrintf( SLINE_LOG, TEXT("Removing player DPNID %0.8x"), id );. P: r) e0 e& z% m
            ConsolePrintf( SLINE_LOG, TEXT("Players connected = %d"), m_dwPlayerCount );7 [, ]- m  ~- y; T& q
        }</P>" @5 B; d/ a* F, s; o+ k
    <P>    // Find playerdata for this client
    : \- V+ m; z( Q! U( m; I    PlayerData* pPlayerData = GetPlayerDataForID( id );
      [: F" h0 E. q  ]+ [  z: M    if( pPlayerData != NULL )
    2 E7 t5 b' _* j0 Z+ a' [    {' o" W" P- I, W+ y" A4 \
            // Destroy it
    4 Q  G( ^4 l3 l/ B7 n        RemovePlayerDataID( pPlayerData );
    & h+ S8 r5 A$ j2 u6 G$ P& x        DestroyPlayerData( pPlayerData );
    " i& Z- d; }9 l. t$ l    }</P>4 O% r( C5 P$ R/ B6 e9 u. k
    <P>    m_AddRemoveLock.Leave();
    ' G$ {+ \: G# c. e8 ^}</P>
    ' q" t6 q1 n  j8 Y8 V0 r' w2 ]
    ; ~% @. p. K/ A; F* X% v9 \# V<P>
    6 i- v: G8 Z# N# T+ ]//-----------------------------------------------------------------------------
    " k6 d8 {3 w9 Y: R8 j( {2 L// Name:
    1 T* Z7 d  K, D// Desc: $ ^1 e: g7 ~# ^: u
    //-----------------------------------------------------------------------------" |" b! V+ |) g: k, w7 g* O+ c$ D& |
    HRESULT CMazeServer::OnPacket( DWORD dwFrom, void* pData, DWORD size )8 W/ h# z6 z1 |" f$ [
    {
    & W2 U$ }) x; J    BOOL fFoundSize = FALSE;</P>
    % ]0 H/ R$ h& v5 n  v. c<P>    // Increment the number of thread we have in this process.
    9 W# G2 Y: ^; r9 P4 a    m_csThreadCountLock.Enter();</P>* ^/ t$ S" W+ ~( E3 T2 w
    <P>    //Get the start time of when we entered the message handler.' O3 f# ?' f( {% E6 i, k9 t
        FLOAT   fStartTime = DXUtil_Timer( TIMER_GETAPPTIME );</P>  z1 W* Z; e+ _" t
    <P>    m_wActiveThreadCount++;( N  }2 M6 v1 q# Y
        if(m_wActiveThreadCount &gt; m_wMaxThreadCount)
    ! p' O' W% C( M+ `! x        m_wMaxThreadCount = m_wActiveThreadCount;
    & Q" Z! E% J. I6 b' y% ^   
    5 \% n, n! y5 Z    // Calculate and average.
    + G  d# @: H4 ~5 j8 u& }+ t    FLOAT fdiff = m_wActiveThreadCount - m_fAvgThreadCount;" s8 c* u+ z' F' \0 a5 o1 p2 D
        m_fAvgThreadCount += fdiff/32;0 ~; @' o) `. E/ P
       
    / a7 c4 A) V1 ~5 ]9 n2 n7 T    m_csThreadCountLock.Leave();</P>
    # Z# N3 j( ?3 Y1 o3 m) ?! c2 B<P>* @5 c8 F* Y% h
        ClientPacket* pClientPack = (ClientPacket*)pData;
    3 [5 M& w9 G6 F7 r    switch( pClientPack-&gt;wType )6 A$ v8 o0 Y- a: X# \0 K& `
        {
    1 Q- i" T! \% n( ~; f$ O% M; K        case PACKETTYPE_CLIENT_POS:
    5 x8 O& g5 J+ `, o7 u0 g            . R6 ?/ c3 \. F7 o0 g2 G$ W% V; j
                // Check to see if the packet has a valid size. Including
    * X8 k4 w) j! h0 ^! p; P            // the custom pack size.. [0 g* w. C' E8 M
                if( size &lt; sizeof(ClientPosPacket))6 M5 w, P3 }5 @
                    fFoundSize = FALSE;
    0 U' L# m7 G4 n4 S8 i            else if( ! IsValidPackSize(size - sizeof(ClientPosPacket)))
    8 ^7 ?9 a6 O3 i, l3 m                fFoundSize = FALSE;
    + I: a* J+ C; ]( o            else3 D2 V. O. q: g: @+ V$ v
                    fFoundSize = TRUE;</P>
    - D5 i' M' g, e% d5 V$ ?<P>            // If valid sized packet, handle the position.
    9 _* b/ v! x# t; ?1 ]            if(fFoundSize)7 M# q/ b8 l" b+ q
                    HandleClientPosPacket( dwFrom, (ClientPosPacket*)pClientPack );
      P  L" G: Q- j6 P            else6 g: g9 R) d1 k! {) W  o' \& j
                    m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );</P>- h; u2 F4 T$ P* B0 l6 m
    <P>            break;</P>: Z9 j  l7 z% N& h" A
    <P>        case PACKETTYPE_CLIENT_VERSION:
    4 I+ w$ [) r, B& Z% @  I            if( size == sizeof(ClientVersionPacket) )2 M. {/ j  ^1 [4 ?! l* w+ F
                    HandleClientVersionPacket( dwFrom, (ClientVersionPacket*)pClientPack );
    % B6 H5 m1 B* t) A% r; p" x            else! U9 S1 {* Y, x' l! y
                    m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );2 W; h9 b$ B! B
                break;</P>, _8 w5 ?$ O1 E! x
    <P>        case PACKETTYPE_SERVER_CONFIG:</P>& Z6 _8 R' I1 t2 y+ l
    <P>            // Server config packet sent to all users (including server). Just ignore and continue.</P>
    ) u5 _( |8 w4 a6 @: ^0 L# X' b, k, B<P>            break;
    8 F; B5 q' L/ V% B( k$ o) b        default:
    ' |! W8 \: j( k* [5 ]            HandleUnknownPacket( dwFrom, pClientPack, size );
    + c' I# ?" M7 r- _' W4 d- _( N8 u            break;+ B, _5 T7 s3 T) f( K
        }</P>
    * X8 Q. Z+ }; _  O6 g<P>    //If the user wants to hold the thread, Sleep for given amount of time.4 n7 T3 |  }% z7 R. }; _
        if ( m_dwServerThreadWait &gt; 0 ), C$ \( W3 |6 C5 W
        {+ |, l! Y# i+ L
            Sleep( m_dwServerThreadWait );
    - F6 ~3 e% `  [6 b9 Y    }
    9 y" c: l7 s, r( C  h4 p! M# @   
    7 }5 ]2 f1 X3 R3 O# {    // Retrieve thread data for this process.
    9 [+ `' A0 o+ K7 s, R    m_csThreadCountLock.Enter();</P>
      M  X/ Z0 B+ n& L* B0 ~- ?<P>    m_wActiveThreadCount--;</P>
    ) I7 Z2 M6 k8 [8 P<P>    FLOAT fDiffTime = (DXUtil_Timer( TIMER_GETAPPTIME ) - fStartTime) - m_fAvgThreadTime;$ K8 C6 m. N* O% _
        m_fAvgThreadTime += fDiffTime/32;</P>  `1 v0 p& c! {3 d
    <P>    //Get the Max time in the thread.
    ; R: B' n( \( w  a+ T    if ( fDiffTime &gt; m_fMaxThreadTime )
    ) Q7 U* m. j# s. X7 |( b    {
    # W( o, a& P7 ^7 V        m_fMaxThreadTime = fDiffTime;( j: V- D' J0 u* d# ^; z5 V& d
        }</P>  z, E' K- T& {' v# G0 I! c. u$ e
    <P>    m_csThreadCountLock.Leave();</P>
    0 |) F) k3 t, N<P>    return S_OK;. y0 a1 F7 c2 R
    }</P>
    , ?) Q/ }: i$ J. R: V7 V5 T
    " T, l( u$ N" F: o9 G* _+ f<P>//-----------------------------------------------------------------------------7 T7 L3 ~8 R) E. t% x' Q' S
    // Name:
    ) j( O9 F6 c' U! \% Z. k// Desc:
    & E, |7 o1 t* f; p6 R5 i2 x//-----------------------------------------------------------------------------$ R/ ~6 A: u; m& {
    BOOL CMazeServer::IsValidPackSize( DWORD dwSize )
    3 Z, U: K9 G9 o{
    / ]6 Y1 c: J4 b4 H0 g  m+ U    BOOL fFoundSize = FALSE;1 o- q6 g3 ^2 I  C& G2 K) [
        BYTE ubPackLocation = m_ClientNetConfig.ubClientPackIndex;# p4 q7 |1 Y1 H, U
       
    # t5 @7 q# ^- y4 L( T    // Check through the array of valid pack sizes.
    " V1 s" m1 ]7 V& U    if(dwSize != m_ClientNetConfig.wClientPackSizeArray[ubPackLocation])
    4 ^  \. {  W6 \* h* I    {
    4 T& m5 |& X; X0 q* c        for( --ubPackLocation; ubPackLocation != m_ClientNetConfig.ubClientPackIndex; ubPackLocation--)( u) ?0 V1 z. R1 J+ o
            {/ w0 v4 _$ k1 F1 H. Q
                if(dwSize == m_ClientNetConfig.wClientPackSizeArray[ubPackLocation])
    $ g% [& q' e6 b; ]) i            {+ k* C* C: [0 e. i
                    // Found valid size in the array.2 i$ g, s! B% e& o) x3 j
                    fFoundSize = TRUE;
    6 }/ O+ Q% V8 Z" e# a+ L                break;
    # X, G! X* R6 e! t5 P            }
    + L7 p% N; |7 T+ a: G* V            if(ubPackLocation &gt;= PACK_ARRAY_SIZE)  ubPackLocation = PACK_ARRAY_SIZE;  //Wrap the array.
    + ^. |$ O- p) Z9 I& `9 h        }
    ' f# k: `# `* ]    }" F2 X1 g8 \0 ]5 W) D* w
        else- r5 i; X+ X% c1 Y, |: c
        {
    8 V4 U4 x) f: m& |0 N& |        fFoundSize = TRUE;
    8 ~) w# O6 o6 D/ a& B    }</P>0 @. P+ |0 g4 H6 g7 X( l# Q
    <P>    return fFoundSize;
    1 m) H# x- O$ Z- D/ m}</P>
    $ v6 G6 r8 U& g1 p+ |  n% k- q<P>- O; i& ?$ t$ c  P- i( G" x" H
    //-----------------------------------------------------------------------------/ Z/ d6 b9 J8 I! S# R
    // Name: 1 q* j2 Y& \. c9 T/ P, b
    // Desc: 4 q) l, r3 r/ |6 p+ [' i# z
    //-----------------------------------------------------------------------------
    ! h* P# f* g  v7 }+ w! {8 ivoid CMazeServer::OnSessionLost( DWORD dwReason ): ]" ?/ H; g8 a# G" Y! C. Q
    {
    ! Q5 w, i+ Z* c& L# {7 g3 v& X    ConsolePrintf( SLINE_LOG, TEXT("ERROR! Session was lost") );
    0 z) }$ I2 y$ o1 h. [6 b}</P>0 X: T) E& ^& O4 Z& k- E

    6 J1 |/ h/ e7 Q+ P+ f; p<P>
    ! {: N! Q. J2 M8 Q/ P//-----------------------------------------------------------------------------
    1 M# M; ?9 M; a' |// Name: 2 H4 O  X+ J1 d+ R
    // Desc:
    2 `2 r/ y6 M1 G8 n: U3 l//-----------------------------------------------------------------------------3 N* @) @" a' m* |
    PlayerData* CMazeServer::CreatePlayerData()1 n! O4 N: q0 G7 f% [& ?$ W
    {3 E7 ?. T+ X4 w0 }$ l2 T$ P9 x6 p; b
        m_PlayerDataListLock.Enter();</P>
    , E  O" I1 Y" r% M) R<P>    // Grab first free player in the list) c9 q# {5 R8 h* @
        PlayerData* pPlayerData = m_pFirstFreePlayerData;</P>
    9 ?0 D% \! ~) l" ?<P>    if( pPlayerData )
    8 o. S2 L4 Q! G' S1 m% v    {, \! a5 M% I* z+ i
            LockPlayerData( pPlayerData );</P>( {5 W, q7 T% v1 @" l
    <P>        // Got one, so remove it from the free list
      X5 x$ T, h* O/ L7 _1 R: @        if( pPlayerData-&gt;pPrevious )
    5 i$ R* p& F* {5 F, l$ j+ {9 T* P            pPlayerData-&gt;pPrevious-&gt;pNext = pPlayerData-&gt;pNext;
    , p! k- \& \7 l# L, t        if( pPlayerData-&gt;pNext )
    / \" `7 B! Q- [" R  U5 M2 X% Q            pPlayerData-&gt;pNext-&gt;pPrevious = pPlayerData-&gt;pPrevious;
      A. A2 A- v: N7 r& L: Y        m_pFirstFreePlayerData = pPlayerData-&gt;pNext;</P>) x6 ^$ I0 R! M! o( a3 a, l# {
    <P>        // Add it to the active list+ v; ~) s' N# Z
            if( m_pFirstActivePlayerData )
    $ I4 O3 k! l$ i- X            m_pFirstActivePlayerData-&gt;pPrevious = pPlayerData;' F  `  X; y8 {/ |9 b) U: T
            pPlayerData-&gt;pNext = m_pFirstActivePlayerData;
    % {& k- L( B0 f& e) a        pPlayerData-&gt;pPrevious = NULL;: C& |. E8 T& P" P$ }2 }9 _/ U
            m_pFirstActivePlayerData = pPlayerData;</P>! F% q5 Z+ n  e9 n9 p
    <P>        // Update count of players: [/ i5 g6 v* r
            m_dwActivePlayerDataCount++;</P>
    3 }3 V: r" d- {9 V<P>        // Generate the ID for this player1 H5 \& q+ n7 ?6 Q
            m_dwPlayerDataUniqueValue++;& ^7 ~9 W" ?$ _# ^
            pPlayerData-&gt;dwID = (DWORD) ((pPlayerData-m_PlayerDatas)|(m_dwPlayerDataUniqueValue&lt;&lt;PLAYER_OBJECT_SLOT_BITS));</P>
    3 w0 A6 M0 i5 d: f) ^<P>        pPlayerData-&gt;pNextInIDHashBucket = NULL;
    3 ^: g% e4 _( S3 d& O; K        pPlayerData-&gt;NetID = 0;& J- x/ U! e2 a  j# ]
            pPlayerData-&gt;dwNumNearbyPlayers = 0;</P>& \1 K4 _7 o! `; c$ u7 ?
    <P>        // Insert into the "off-map" cell# O: Q0 n  J! I; D5 `" r
            pPlayerData-&gt;fPosX = pPlayerData-&gt;fPosY = -1;
    . S- k4 P9 f+ I! o        pPlayerData-&gt;wCellX = pPlayerData-&gt;wCellY = 0xffff;$ z3 n5 V! S4 ?4 y+ y' y
            m_OffMapLock.Enter();
    / N, H0 d/ H' \$ k3 x8 E9 d% \8 n8 t# a, E        pPlayerData-&gt;pNextInCell = m_OffMapCell.pFirstPlayerData;
    * v1 t+ d) P, @/ [9 n* d% n& E        m_OffMapCell.pFirstPlayerData = pPlayerData;* S2 g, C* c$ u/ k9 l; P- E$ {  b
            m_OffMapLock.Leave();</P>
    8 D+ w0 V( H& D" J9 j2 k1 C6 u: |<P>        // Mark as active
    # [( X5 j/ ^  l& a9 @. d* ~        pPlayerData-&gt;bActive = TRUE;</P>! v- v% k2 p4 \0 y/ L3 F% _/ j  l
    <P>        UnlockPlayerData( pPlayerData );  o. A3 G8 K/ {# w" O4 l
        }</P>8 _% O# @# \6 [% N) j* f' D0 F
    <P>    m_PlayerDataListLock.Leave();</P>+ E7 a! _8 {: A
    <P>    return pPlayerData;
    4 ^( R1 _! o! V}</P>
    7 M# b/ P& O" J' a9 a2 o" m$ ~# V1 N. z7 D' l
    <P>
    $ O: q6 B* ?* {' v, C+ l2 F" ?//------------------------------------------------------------------------------ P* H  q) z: `4 B! m# I
    // Name: ' F( ?; {8 Y" m: }: [; B
    // Desc:
    # [' Q8 J8 S& F//-----------------------------------------------------------------------------$ w& b* h( I, K. [0 B! S# i1 V
    void CMazeServer:estroyPlayerData( PlayerData* pPlayerData )1 i3 K( m' R* Z& x+ g( i- Y! X
    {
    * ^' T1 b! g+ g' Z* y    m_PlayerDataListLock.Enter();- z) ~( E6 V8 H9 i
        LockPlayerData( pPlayerData );</P>- t" H$ [$ G+ [* h9 z4 O3 n6 ~3 z0 J8 I
    <P>    // Remove the player from its cell$ a3 C4 z+ j( T  C! `( v/ B; ^2 |8 Y+ k
        RemovePlayerDataFromCell( pPlayerData );</P>
    : o+ K" n1 b& J9 ^9 d7 r) \<P>    // Mark as inactive
    ) ?$ ?9 U& k7 W& f" j# t    pPlayerData-&gt;bActive = FALSE;</P>
    , p4 G6 B; ~7 E" c9 M6 M<P>    // Remove player from active list7 U; \5 t6 O; w/ O3 D
        if( pPlayerData-&gt;pPrevious )
    , `# U; s+ k; v9 ]' P3 M; q$ i3 Q* A        pPlayerData-&gt;pPrevious-&gt;pNext = pPlayerData-&gt;pNext;" E! v! c9 k: e
        if( pPlayerData-&gt;pNext )
    6 R; c' Y3 m3 a( W- C+ w$ ^! x        pPlayerData-&gt;pNext-&gt;pPrevious = pPlayerData-&gt;pPrevious;</P>& m  O% S# k. }' x: a% W2 L# {
    <P>    if( m_pFirstActivePlayerData == pPlayerData )1 X- m* G1 d; k# x# }
            m_pFirstActivePlayerData = pPlayerData-&gt;pNext;</P>) S% K% F3 C2 T# f6 n
    <P>    // Add it to the free list9 n1 q& Y1 F& ?0 Q' n) G4 o; d6 l
        if( m_pFirstFreePlayerData )  U0 w  {& ?8 V/ r: Y
            m_pFirstFreePlayerData-&gt;pPrevious = pPlayerData;
    3 |: G* S$ J( v( x, q7 r    pPlayerData-&gt;pNext = m_pFirstFreePlayerData;7 [9 E3 ^" e6 k
        pPlayerData-&gt;pPrevious = NULL;* D, o" z: u3 d6 X* q
        m_pFirstFreePlayerData = pPlayerData;</P>" B" Z# y  B4 F+ \, {5 K$ F
    <P>    // Update count of players+ ~  L  Z  Y4 J+ K$ p& y
        m_dwActivePlayerDataCount--;</P>1 D" L" t7 B" i$ C# q- V: K: ^
    <P>    UnlockPlayerData( pPlayerData );+ T2 Z* N9 n( V8 a7 J0 G; w" L2 A
        m_PlayerDataListLock.Leave();' R$ q. L8 j, N- i* W
    }</P>
    ; N7 D3 z- j2 h& i
    5 V, }1 T, l$ x/ w  O) Z<P>, W2 B  ?' ~. S* R- A) p
    //-----------------------------------------------------------------------------* _2 g- D. x" n' i( |
    // Name:
      }' f/ i6 h5 z. m7 j, o3 w2 f// Desc:
    7 D; ]5 y/ Z7 Z- Z( A//-----------------------------------------------------------------------------8 n7 |) S$ M) ^" W) y' G: p
    void CMazeServer::RemovePlayerDataFromCell( PlayerData* pPlayerData )- f% ~! R4 _0 R7 ^( s) a* I; F' v$ D; H
    {
    1 v* e2 Q# _- h    // Lock the player
    + s: J$ w: M7 }+ |) P  A" A: e  M    LockPlayerData( pPlayerData );</P>
      ^+ f8 E+ ^* r. O' v4 g<P>    // Lock the cell the player is in
    ! Z5 e4 O( Z; r6 F! e    ServerCell* pCell;
    ) a- |$ B. B( j8 R$ m% k+ L( g: t    if( pPlayerData-&gt;wCellX == 0xffff )
      n1 T0 M3 @6 f: F6 u  F2 [" q- I    {  z- B3 a. a) r3 ]
            m_OffMapLock.Enter();' U9 r, @+ g5 }) q, v. o8 g, v
            pCell = &amp;m_OffMapCell;* X) h/ I' s# o
        }
      a! S$ x8 i  b" j) e  i    else  N/ R4 T6 A( f, z
        {
    ( v0 v7 K6 @5 E0 D) u8 t: Y/ E        LockCell( pPlayerData-&gt;wCellX, pPlayerData-&gt;wCellY );
    8 @* T( o' u, M: i1 w7 p3 H        pCell = &amp;m_Cells[pPlayerData-&gt;wCellY][pPlayerData-&gt;wCellX];+ E/ Q" G0 K; |0 u6 Q
        }</P>) @* B6 T# O5 Z2 `" K3 X
    <P>    // Remove it from the cell4 ]) C6 \# Q7 o1 d& w" B; ^9 Y
        PlayerData* pPt = pCell-&gt;pFirstPlayerData;
    0 Y8 y( J& @0 P7 M    PlayerData* pPrev = NULL;
    6 o: J8 `, F! e" X    while ( pPt )3 y4 ?8 r, t: _6 |! M
        {
    6 F) f9 Y) v% `6 K3 g" V- y: F5 U7 J1 {/ q        if( pPt == pPlayerData )% n) I3 {" e* H- b$ W! b
            {
    . B/ Q8 |! g; i& }- a3 v            if( pPrev )
    - W) }! c- t1 O: [                pPrev-&gt;pNextInCell = pPlayerData-&gt;pNextInCell;; h( y& L& i1 m& l* |8 O
                else- h4 X  H9 D4 N* b( r
                    pCell-&gt;pFirstPlayerData = pPlayerData-&gt;pNextInCell;</P>2 ~' b$ r. c, G$ I% _; j5 y
    <P>            pPlayerData-&gt;pNextInCell = NULL;, ~0 u* q8 S' p1 V! {/ p
                break;( I, k; |  P. U: _8 _/ a5 c
            }5 Z" w+ p. m  V
            pPrev = pPt;4 G; |$ A# l2 d
            pPt = pPt-&gt;pNextInCell;
    # [* o  i1 J7 i4 d% s    }</P>
    " J0 M, L% H# o4 E<P>    // Unlock the cell0 v( H' F+ X1 }4 P; d
        if( pPlayerData-&gt;wCellX == 0xffff )
    $ |/ t9 h8 _- n2 B" r        m_OffMapLock.Leave();
    8 n7 _( ]2 m) Z    else" o% R5 M' ^- O( J# q" K' Y
            UnlockCell( pPlayerData-&gt;wCellX, pPlayerData-&gt;wCellY );</P>
    2 e- x$ L7 k2 H<P>    // Unlock the player, E2 @' A: \, N
        UnlockPlayerData( pPlayerData );4 G- [3 y' x1 U  x6 |
    }</P>% s: o7 r9 w' ]
    8 G: N0 B) y! m4 a% |6 w# Z1 H/ v( d
    <P>' u, S1 ?( W- s# ~; K/ g
    //-----------------------------------------------------------------------------, O' s* l0 H' }5 s" l- H( y
    // Name: * b2 R4 n* _& ]" Q/ y
    // Desc:
    + }$ S& }7 ~! R' o: _9 S//-----------------------------------------------------------------------------. a0 H: {+ C0 w
    void CMazeServer::UnsafeRemovePlayerDataFromCell( PlayerData* pPlayerData )
    , |; u* S2 p# s% k8 A! d{0 d$ x3 J) ~/ o: g' o; p
        ServerCell* pCell = GetCell( pPlayerData );$ O7 D  ^, j: ^* u* s1 l. H+ A
        PlayerData* pPt  = pCell-&gt;pFirstPlayerData;# ?8 p! b! R6 z9 `. V
        PlayerData* pPrev = NULL;& m2 j2 k, J/ E2 I4 e# ?6 P9 w5 [
        while ( pPt )
    . ?3 w+ N$ o# M    {
    5 e" R7 [9 j$ F! L; X" m        if( pPt == pPlayerData ). J% e9 ?: V7 d+ G) Q
            {2 q& B" o# o7 f% T7 S* X" O
                if( pPrev )
    0 g, h0 `7 }( m3 S; y) a3 X2 u                pPrev-&gt;pNextInCell = pPlayerData-&gt;pNextInCell;/ W1 v' W' F6 f7 C. s
                else
    " v7 T$ i8 I/ `2 N# x1 E' ]+ X                pCell-&gt;pFirstPlayerData = pPlayerData-&gt;pNextInCell;; t: E- H: Q% a7 h0 \
                pPlayerData-&gt;pNextInCell = NULL;1 u2 O: u7 d2 v% [. ?
                break;9 u- K: Y" N+ T. W* a8 c
            }: l/ f" B3 S* y  g0 S
            pPrev = pPt;
    6 V$ S2 Z5 O5 G" I  z: z        pPt = pPt-&gt;pNextInCell;
    , u% ~( |% W% l    }
    6 v3 g) t' L8 K}</P>. }8 b$ ~5 U. o2 M3 T  ?

    * A  p/ u' j: N5 D' H<P>
      ?* p9 t0 i$ Y8 F. _//-----------------------------------------------------------------------------
    ! H7 `) ?* k0 j% \& w// Name:
    0 M4 n8 H9 ]4 ?$ r/ D// Desc: 2 s& q" \& ]9 l
    //-----------------------------------------------------------------------------
    ; _6 G0 R: g7 F5 t4 r$ U+ Rvoid CMazeServer::UnsafeAddPlayerDataToCell( PlayerData* pPlayerData )
    + ~: n: W7 u4 ^, c{. \' j8 Y- n0 n8 {- u2 p0 u
        ServerCell* pCell   = GetCell( pPlayerData );8 [1 q' I& `1 {- J6 G9 f. q# G
        pPlayerData-&gt;pNextInCell = pCell-&gt;pFirstPlayerData;
    . t8 b+ ?$ Q% u' v- D    pCell-&gt;pFirstPlayerData = pPlayerData;8 A3 Y9 f! H2 \
    }</P>5 |9 p7 E( ^1 g4 C: y" C

      W3 ?6 K) V! E& B) L1 [<P>8 I& i( }/ P: a7 j0 \# `
    //-----------------------------------------------------------------------------6 j, _. H4 r) _+ q7 ~# E! j0 b4 U2 n
    // Name: ; F' L7 o! Q/ J4 b4 y$ V
    // Desc: * \1 C" P% d/ J+ t: H  X! l1 w7 R0 t  V
    //-----------------------------------------------------------------------------
    0 l& {5 p+ K% |: I# ~% Ovoid CMazeServer::HandleClientPosPacket( DWORD dwFrom, ClientPosPacket* pClientPosPack )
    ) E/ q; }  P% g4 Q( e, b5 `{- j" j6 o3 B8 |, ^- B
        // Grab player for this client and lock it
    ) T+ v3 X! J6 D2 N7 z    PlayerData* pFromPlayer = GetPlayerDataForID( dwFrom );
    # J1 _7 s! O  b8 y    if( pFromPlayer == NULL )$ e4 ?3 Z' a$ k  E, t
        {
    % c. ], A1 z7 l' G5 L        if( m_dwLogLevel &gt; 1 ): Y- c3 \3 A& L) \
                ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Could not find data structure for this player"), pFromPlayer-&gt;NetID );
    , y8 Y/ {; T# O  q3 @3 ~, B7 \        return;) u. k- ]( n. h- d( V3 e: ]) t
        }</P>
    4 H! Y$ z* }' s7 j8 M5 ?, A+ r  A<P>    LockPlayerData( pFromPlayer );</P>
    + A  Q1 p/ B; S2 m% j, V<P>    if( FALSE == pFromPlayer-&gt;bAllow )
    $ o- N' q* t( N+ m    {" S& }- m: Y5 x( W/ N) O/ L
            if( m_dwLogLevel &gt; 0 ), a9 x9 t8 z5 f9 T) R5 v
                ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Got position packet from bad client.  Rejecting client"), pFromPlayer-&gt;NetID );</P>
    4 v4 p0 {, |. J+ U<P>        m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );/ S4 Y- n  `' a: [) |
            UnlockPlayerData( pFromPlayer );
    / s; |- ~( B) A" E. ^; F7 f/ q        return;
    " h  S7 O2 e0 ^* ^    }</P>
    " A* O1 X& I2 V4 B" h6 ?: C5 k  y1 e<P>    // Compute the cell the player should be in now
    ! K; l. g6 d$ m- @0 {    DWORD newcellx = int(pClientPosPack-&gt;fX);! {" z$ V% ?2 `) Z" [8 g$ D; x
        DWORD newcelly = int(pClientPosPack-&gt;fY);
    & P2 C9 k/ A. X7 K7 t& i( O4 ^: \    DWORD oldcellx = pFromPlayer-&gt;wCellX;
    ; o) M" G' r( A* j    DWORD oldcelly = pFromPlayer-&gt;wCellY;</P>' M6 f/ r3 Y  _/ f
    <P>    // Have we moved cell?
    ! @% c( [) U  _+ d0 a    if( newcellx != oldcellx || newcelly != oldcelly )
    ' R2 N& b' N3 ^6 d( y6 I    {4 K' Z! g' d% {, Y: ]. t
            // Yes, so lock the pair of cells in question! d/ k& P( {  Y; v9 v; k
            LockCellPair( oldcellx, oldcelly, newcellx, newcelly );</P>
    9 ]# Z# F+ \% j- X1 N1 I! s<P>        // Remove from old cell and add to new cell$ g( m! W9 O$ V- ~  c* }9 a
            UnsafeRemovePlayerDataFromCell( pFromPlayer );
    $ V6 v1 K3 H+ f& H* D( u; c        pFromPlayer-&gt;wCellX = WORD(newcellx); pFromPlayer-&gt;wCellY = WORD(newcelly);
    $ K+ c) M3 Y9 r! L        UnsafeAddPlayerDataToCell( pFromPlayer );</P>7 L* B8 d$ H' k& x
    <P>        // Unlock cells
    ) ~" I  ]' A/ h- r1 n7 ^/ f3 P! c, N- ]        UnlockCellPair( oldcellx, oldcelly, newcellx, newcelly );
    0 Q4 G/ ~2 @  x3 ~5 G/ o+ Y    }</P>
    5 y  [* B3 b" F. V& B9 ?5 F<P>    // Update player position
    9 n* D0 Y" S, Z& l7 d5 B$ v! B2 D    pFromPlayer-&gt;fPosX      = pClientPosPack-&gt;fX;
    5 T4 U- n) h; S% B+ [    pFromPlayer-&gt;fPosY      = pClientPosPack-&gt;fY;
    2 o; n) F. [7 r& n6 |: K+ ~/ B    pFromPlayer-&gt;aCameraYaw = pClientPosPack-&gt;aCameraYaw;</P>
    * o; L8 |- X! e% H* j1 @<P>    // Allocate space to build the reply packet, and fill in header
    7 `: C" j0 c) R; r    DWORD dwAllocSize;
    & T+ Y! ]  a: g  `  V) q' p4 x+ f    ServerAckPacket* pSvrAckPack = NULL;</P>
    ) j$ c, L, A, ?: N4 U<P>    // Begin by allocating a buffer sized according to
    ' O1 ]( P* B8 H4 W6 l1 _    // the current number of nearby players + 4.  This will give
    ( g- S% t# V# N    // a little room for more players to come 'near' without resize
    ' I+ Z8 Y- j9 P5 n) Y6 R    // the buffer.! B8 _) b8 |# g% e+ ]
        DWORD dwMaxPlayerStatePackets = pFromPlayer-&gt;dwNumNearbyPlayers + 4;</P>9 V# w9 _3 t- H4 z
    <P>    dwAllocSize = sizeof(ServerAckPacket) + dwMaxPlayerStatePackets*sizeof(PlayerStatePacket);
    9 j  A; K, K) f: ]    pSvrAckPack = (ServerAckPacket*) realloc( pSvrAckPack, dwAllocSize );
    $ o4 t* b& d; J- e/ }    if( NULL == pSvrAckPack )6 _3 L* y: e& L3 ?$ V: H- |! u# t
        {
    ; e* o8 o. t# W! w        // Out of mem.  Cleanup and return+ b+ W! |2 }- O6 Y" _9 R
            UnlockPlayerData( pFromPlayer );
    7 J8 X0 Y9 P* I6 c6 l  a0 U        return;      
    : g' F1 X1 Q. C1 x/ W+ h  x, J    }
    5 y2 I' f( m, ^    ZeroMemory( pSvrAckPack, dwAllocSize );</P>  ]; d# C3 @% Q7 Z4 Z
    <P>    *pSvrAckPack = ServerAckPacket(m_dwPlayerCount);9 E! Q7 @. \1 j" \& q+ _
        pSvrAckPack-&gt;wPlayerStatePacketCount = 0;7 B: m5 N# H# E7 t
        PlayerStatePacket* pChunk = (PlayerStatePacket*)(pSvrAckPack+1);</P>4 }# P# M& Z2 f& ~
    <P>    // Compute range of cells we're going to scan for players to send
    5 X5 M" `  P  ~) T  Z' b    DWORD minx = (newcellx &gt; 7) ? (newcellx - 7) : 0;
    - O: ?, \% ]5 o# X; s    DWORD miny = (newcelly &gt; 7) ? (newcelly - 7) : 0;2 _; e& T. x" k
        DWORD maxx = (newcellx+7 &gt;= m_dwWidth) ? m_dwWidth-1 : newcellx+7;
    ; `1 s9 I- g3 e& s* S    DWORD maxy = (newcelly+7 &gt;= m_dwHeight) ? m_dwHeight-1 : newcelly+7;</P>1 w8 H) i6 D6 H( F! f
    <P>    // Lock that range of cells
    ( A' y+ ^. U0 q  b9 n# F# b    LockRange( minx, miny, maxx, maxy );</P>
    3 M8 N  c# }; r1 e<P>    // Scan through the cells, tagging player data onto the end of
    ; F) P! q- d5 A! Y) E+ ~. j    // our pSvrAckPacket until we run out of room
    1 W& L. t3 W7 e- u    for( DWORD y = miny; y &lt;= maxy; y++ )
    ! p7 k! q* C& `7 G+ P& w( v& ?: K5 h    {/ W7 h* Z' Y  m+ f3 g0 v
            for( DWORD x = minx; x &lt;= maxx; x++ )
    . E- Z, b( n5 {* O' `        {
      c8 M& e6 U' `$ {1 F3 d, A( E( U/ e6 _            PlayerData* pCurPlayerData = m_Cells[y][x].pFirstPlayerData;; i/ r- ]9 o/ ]  e' M# f. j
                while ( pCurPlayerData )
    + l. k1 n9 M1 E) h2 z            {* c5 f1 B6 [5 K- A& ^
                    if( pCurPlayerData != pFromPlayer ). A: W/ @& e& c$ L; ^
                    {( C1 Q& h' c3 F$ o) ?
                        if( pSvrAckPack-&gt;wPlayerStatePacketCount &gt;= dwMaxPlayerStatePackets )6 G6 Q2 Z& l& W2 H
                        {6 X( }0 @/ P5 u6 Q9 u
                            // Make sure pChunk is where we think it is
    ; Z; y$ e! l8 \6 k                        assert( (BYTE*) pChunk == (BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket)) );</P>: M/ d  P+ u3 f4 \! z
    <P>                        // There are more than just 4 new nearby players, so resize the & U) m% N: m4 U3 B. u  c1 G
                            // buffer pSvrAckPack to allow 16 more PlayerStatePacket's.6 T3 t  U( U2 ^, T2 ]# Z! d
                            dwMaxPlayerStatePackets += 16;
    ' z8 ^6 y% w( ^7 @( i+ o1 h8 q, l                        dwAllocSize = sizeof(ServerAckPacket) + dwMaxPlayerStatePackets*sizeof(PlayerStatePacket);! M2 q( D3 J5 N- ?% [- m. v
                            ServerAckPacket* pNewSvrAckPack = NULL;% R0 o! \2 y5 c7 U& J& c  J
                            pNewSvrAckPack = (ServerAckPacket*) realloc( pSvrAckPack, dwAllocSize );# I2 V  d2 x3 |
                            if( NULL == pNewSvrAckPack )! F0 a. Z  V' y# w, n9 L9 [
                            {, n* O8 C4 g5 h: M
                                // Out of mem.  Cleanup and return
    4 ]/ S, G) q3 d% r                            free( pSvrAckPack );* R, i5 D' K0 H- k" @) F
                                UnlockRange( minx, miny, maxx, maxy );; n( |: A! ?, n; I* [% H8 Y
                                UnlockPlayerData( pFromPlayer );
    $ i  F, P; u2 T/ O                            return;      
    6 d4 @) c- [3 X! S' O0 a                        }</P>2 n1 W  M$ M" I; b8 F# G* K! m( K
    <P>                        pSvrAckPack = pNewSvrAckPack;
    ) ], Q4 v. R5 y                        pChunk = (PlayerStatePacket*) ((BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket) ) );</P>
    3 X; k9 Q7 @7 |9 p: G<P>                        // Make sure pChunk is still where its supposed to be; ]& e# ?8 x+ A- B
                            assert( (BYTE*) pChunk == (BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket)) );' D: w( Y1 P  P0 L: k+ m# v/ f0 R
                        }</P>
    7 ]; F1 T- }; M' M<P>                    pChunk-&gt;dwID       = pCurPlayerData-&gt;dwID;
    % O5 E4 B1 s: U; y- v                    pChunk-&gt;fX         = pCurPlayerData-&gt;fPosX;
    % z/ ^: i9 ~6 L; v                    pChunk-&gt;fY         = pCurPlayerData-&gt;fPosY;9 L  a8 i% \% u3 A( S2 h1 |3 D
                        pChunk-&gt;aCameraYaw = pCurPlayerData-&gt;aCameraYaw;! e* O8 r$ E% `; p' n+ U) J# u
                        pChunk++;2 n9 w* o( N: [8 i. L# [' M5 D' C
                        pSvrAckPack-&gt;wPlayerStatePacketCount++;
    " x( v! y& W  {0 ?  i/ D                }
    ( ~0 N' T- b0 U" O1 f. x                pCurPlayerData = pCurPlayerData-&gt;pNextInCell;" z# {) J8 P% v
                }' `9 }4 x4 i' h8 U/ _3 W8 O! V
            }  F5 q& {, A/ j' O. W, s
        }</P>* F4 p: J$ [" L' w
    <P>    // Update the dwNumNearbyPlayers for this player
    2 }6 h( q2 X; c    pFromPlayer-&gt;dwNumNearbyPlayers = pSvrAckPack-&gt;wPlayerStatePacketCount;</P>
      p  p0 A2 X8 y, p" [/ h<P>    // Unlock range of cells
    2 `( y4 I  ]9 ], }- r    UnlockRange( minx, miny, maxx, maxy );</P>
    - X* J9 s7 X9 ?4 i<P>    if( m_dwLogLevel &gt; 2 )* j3 L- q- X7 Z
        {- _( ]1 k1 R8 c5 v! Y$ {
            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Position is (%0.2f,%0.2f)"), pFromPlayer-&gt;NetID, pFromPlayer-&gt;fPosX, pFromPlayer-&gt;fPosY );
      H9 y# \/ V1 k    }
    / _# `+ A0 Z, v/ t* l+ W. ?    else if( m_dwLogLevel == 2 )
    4 J# X  d0 I' `    {
    1 C4 ~: Z: j. n/ b0 K$ K) s: S" g        FLOAT fTime = DXUtil_Timer( TIMER_GETAPPTIME );, G5 d5 L& ?, j
            if( fTime - pFromPlayer-&gt;fLastDisplayTime &gt; 60.0f )- d$ j" y  a8 T4 Z, X$ M3 Z
            {
    : V+ i( z& x( O8 }* h& t+ m            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Position is (%0.2f,%0.2f)"), pFromPlayer-&gt;NetID, pFromPlayer-&gt;fPosX, pFromPlayer-&gt;fPosY );: f9 c" Q7 |  m+ \9 d; m' z
                pFromPlayer-&gt;fLastDisplayTime = fTime;
    0 ~- y4 [5 H' Q" }" B$ G        }; R6 s' B" R) @* l2 M
        }</P>
      {+ ?: j8 B2 k5 w<P>    // Unlock the playerdata
    3 x) x: x% p* Q- I4 S    UnlockPlayerData( pFromPlayer );</P>
    ( W* F# ]( t  u( H) {9 |<P>    // Send acknowledgement back to client, including list of nearby players
    6 S: g0 X% O7 _% N8 ?. J    DWORD acksize = sizeof(ServerAckPacket) + (pSvrAckPack-&gt;wPlayerStatePacketCount * sizeof(PlayerStatePacket));
    6 |$ X% ^" O7 Z
      d8 W0 ^" j$ E" _. X    // Pack the buffer with dummy data.8 m% ^" A& P+ n' l& H) A
        if(m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex] &gt; 0)3 A9 L. B) I5 k0 L
        {0 K/ |! i  Y- f/ f5 u' w8 h/ q
            DWORD   dwBufferSize = acksize + m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex];4 A2 O, Q1 U' H9 H" D6 y
            VOID*   pTempBuffer = 0;</P>
    $ p2 s/ r$ V( D% I<P>        pTempBuffer = malloc(dwBufferSize);) G3 ?- [5 k$ G& }& O
            if( NULL == pTempBuffer )
    0 A0 L2 o* x; B# Y8 V& z3 P. H        {
    . S) R; K/ K* [0 m- }' b7 M            //Out of memory
    + I. q4 Z" ^) u) N% o8 T. g1 A            DXTRACE_ERR_NOMSGBOX( TEXT("System out of Memory!"), E_OUTOFMEMORY );
    , l  [, A; k% ^; y- S            free( pSvrAckPack );; d  @. ]% N5 |& Y' ]  T. U" z, [
                return;5 a! H* J) D/ c8 @) o
            }</P>
      V( x8 M  D- [1 d% ^<P>        FillMemory(pTempBuffer, dwBufferSize, 'Z');$ i  Y- U1 o3 g1 c# v* R/ E
            memcpy(pTempBuffer, pSvrAckPack, acksize);</P>
    & u5 f# ?2 X8 {" l  F# _1 M<P>        SendPacket( dwFrom, pTempBuffer, dwBufferSize, FALSE, m_dwServerTimeout );8 B/ c2 Q( o% V* W- ?4 r
        ( G$ V7 _1 z! Q2 j" [7 x
            free(pTempBuffer);" n2 p( n  u( Z0 R
        }   9 k: ]) J! n2 r; p; n, |
        else
    - w1 P. l" R+ b7 Q    {
    ( E7 `' O  }  C        SendPacket( dwFrom, pSvrAckPack, acksize, FALSE, m_dwServerTimeout );
    8 m8 v& @+ ^$ H4 U    }</P>
    5 X: O0 n6 a, B- S<P>    free( pSvrAckPack );</P>  Q! E+ I2 u; b! K+ x+ ?1 o2 R
    <P>}</P>
    # q6 w4 \/ o3 O% Z$ Y) G1 g! H, W# N$ X; w
    <P>
    + w! C* O' G2 j//-----------------------------------------------------------------------------
    ( ~. U' z9 T, n# Q* `' ~# Z// Name: 4 l* u+ R! |3 {# M8 i+ C$ ?
    // Desc:
    2 z: J7 ~% y8 K6 Z//-----------------------------------------------------------------------------  P' {. s/ i4 a, i, H3 }0 U
    void CMazeServer::HandleClientVersionPacket( DWORD dwFrom, ClientVersionPacket* pClientVersionPack )
    & l  J: G/ V, n{
    / u, r' }  \- X, i# @% d2 l    // Grab playerdata for this client and lock it
    6 s& R, H1 \: D- U( M    PlayerData* pPlayerData = GetPlayerDataForID( dwFrom );
    9 g' e/ \, q, `  Y+ K" L    if( pPlayerData == NULL )
    ) S: k' F' W9 ]6 h* w, z        return;
    6 `" z" S& }* C" v% a8 w2 A# z    LockPlayerData( pPlayerData );</P>9 i% P% s, y6 I4 `5 {
    <P>    // Record the version number
    4 k: e- w0 X! `0 z    pPlayerData-&gt;dwVersion = pClientVersionPack-&gt;dwVersion;</P>" _; w1 w: V3 `  R9 Q
    <P>    if( m_bLocalLoopback )
    4 ^- h0 @: \1 H        pPlayerData-&gt;bAllow = TRUE;: L8 Q/ u2 f* T+ a
        else
    3 B( P( @9 D, p; Z3 i        pPlayerData-&gt;bAllow = IsClientVersionSupported( pClientVersionPack-&gt;dwVersion );</P>
    7 L! s& r/ }' w# g<P>    if( m_dwLogLevel &gt; 0 )+ j! q% l, z) h& P" M8 K
            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>1 E; W; [+ }! x" e
    <P>    if( FALSE == pPlayerData-&gt;bAllow )
    8 S( y) T3 u& G. f+ O  b& Z    {0 a1 z8 X7 [/ Z/ ]
            if( m_dwLogLevel &gt; 0 )4 Z. G2 T6 U/ E0 I& Z# T
                ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Rejecting client"), pPlayerData-&gt;NetID );</P>! M7 w9 C, F! R9 y; E7 x
    <P>        m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );: D/ P2 W0 W3 ?; A" T6 l
            UnlockPlayerData( pPlayerData );
    $ Z, e- }/ h  ?8 V; @        return;8 Y9 T- R) H; r2 s* O
        }</P>9 v. J, f) D+ C- f4 C
    <P>    // Unlock the playerdata% i' ]. Z' b( g
        UnlockPlayerData( pPlayerData );</P>  {1 @8 a, z5 ?& v
    <P>    // Send acknowledgement to client that the client was either accepted or rejected5 m" D- h% E* W/ a0 p' \! W) n
        ServerAckVersionPacket packet( pPlayerData-&gt;bAllow, dwFrom );
    ( z( j9 ?- R, M8 U' I- r" ~    SendPacket( dwFrom, &amp;packet, sizeof(packet), TRUE, 0 );
    1 b+ U- J# _+ g) p" i( j! w8 p}</P>/ |( @& T9 U+ H3 {) F8 |9 Z4 D
    / F* I5 M* }9 x& U
    <P>7 x& F. m; Y! q9 f2 z
    //-----------------------------------------------------------------------------( J! z" U6 L3 b* b3 A3 l" K
    // Name: . e6 F0 D0 ]. Z3 M" |/ D% M7 N
    // Desc:
    ( q; E+ r; |5 w& v: A. _9 Y1 M//-----------------------------------------------------------------------------$ t- H9 i8 C$ p& B! q/ D2 ]* u3 `& N
    BOOL CMazeServer::IsClientVersionSupported( DWORD dwClientVersion )0 h7 b7 h5 ^0 E! B$ I. F
    {
    " z" c) M* B, b4 E0 O0 a1 G    switch( dwClientVersion )7 I: N8 {; \: B: S8 |
        {* H) ~% y- P1 F, Y( i5 ^
            case 107: // only v107 is supported
    6 ~- B1 U& w3 {6 r9 g2 \& @$ x            return TRUE;; \1 b: f" [+ H1 T
            default:0 B& C9 [. H: T6 A% j8 U
                return FALSE;; Z3 I2 v0 P8 T2 Y1 o, J+ h
        }7 u- Q! W4 H% B8 G' u1 o, Z
    }</P>
    - [7 o, g. t; r+ }( b( f  I' \  e' b' H3 c- _. ?7 Z1 d# F
    <P>/ C7 M8 l% r; L" @% `1 l
    //-----------------------------------------------------------------------------
    2 @7 L7 U( L) l% U' M8 p// Name:
    7 N5 P/ T$ _+ {4 c' Y: c! s// Desc:
    / R/ J6 o  g( `" x+ h) l//-----------------------------------------------------------------------------
    + `8 n; u) s" Uvoid CMazeServer::HandleUnknownPacket( DWORD dwFrom, ClientPacket* pClientPack, DWORD size )
    $ k4 }# R6 {9 i8 t% J: d* k{
    0 ?5 J9 s) b% \    if( m_dwLogLevel &gt; 1 )
    4 E0 }( i3 `8 Q$ S$ g6 [( g        ConsolePrintf( SLINE_LOG, TEXT("ERROR! Unknown %d byte packet from player %0.8x"), size, dwFrom );</P>+ I+ }7 |- T. t, }) m+ S! \% V
    <P>    m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );
    4 i: u8 [4 H+ Z* ~}</P>+ ?5 D# K( m6 L0 J8 T

    2 u9 O8 E# P6 M7 ^0 e<P>
    & H- L9 @; r) L7 Z//-----------------------------------------------------------------------------
    # U9 u0 W9 ?# s9 ]// Name: ( k/ Q3 z$ l9 A; p
    // Desc:
      W% i' s, w3 G6 K/ B/ O//-----------------------------------------------------------------------------
    / X' x9 k) C! R+ y+ tDWORD   CMazeServer::IDHash( DWORD id )% v7 L: v% [6 r5 X0 ]5 z  m, c$ R
    {
    2 o( y- I" G) z, M! }4 `    DWORD   hash = ((id) + (id&gt;&gt;8) + (id&gt;&gt;16) + (id&gt;&gt;24)) &amp; (NUM_ID_HASH_BUCKETS-1);
    8 v1 B% P  @# E# r6 y' O6 i/ W    return hash;
    * A. O- k( [4 [, o( g}</P>1 C6 d6 b' ]3 O5 o! q. q1 d
    2 I$ i4 W- c) M/ q' Q! q
    <P>
    2 O4 I* Z; p9 r8 Z" _//-----------------------------------------------------------------------------! k* J. ]$ a* g1 t
    // Name: 0 \) s9 H) F: l$ z
    // Desc: / }7 R4 P( X; ?) y5 q; D% l
    //-----------------------------------------------------------------------------
    , G( P0 Q5 p: e7 Y8 Tvoid CMazeServer::RemovePlayerDataID( PlayerData* pPlayerData )
    & I/ D/ _1 s* x{% B) x" Y, o: a3 s7 F1 T* e1 _0 p9 I
        // Hash the ID to a bucket number
    % ]" b' q8 x( W) s( [    DWORD   bucket = IDHash( pPlayerData-&gt;NetID );</P>/ M9 K  I' r' o# N. l) G8 \
    <P>    // Lock that hash bucket% f$ s9 y( m0 I, K
        const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;- w  Z) @( ]1 e2 E, n- v& b1 Y1 B
        m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>+ Q) w: g% }3 X
    <P>    // Loop though players in bucket until we find the right one2 M8 G5 l- g$ q6 ~, Z; T
        PlayerData* pPt = m_pstIDHashBucket[bucket];
    ' N( n+ N* k% c3 e2 P: b8 K    PlayerData* pPrev = NULL;
    0 A2 k% R5 ^$ k& K& h    while( pPt )5 z- |, _7 e* Y' K6 L- b
        {
    6 ]1 W" g( V; F1 k        if( pPt == pPlayerData )0 h% M- q- L, s/ n) a* y/ J7 T
                break;$ x7 I3 y: v+ O7 h) F/ y
            pPrev = pPt;3 Z6 v6 T' X3 P2 G) r# V: v
            pPt = pPt-&gt;pNextInIDHashBucket;
    2 {6 r( l) o" |* s, O/ R% @    }</P>
    6 V' j: Q% e# Q( R<P>    if( pPt )
    ( b* w( r+ `( i5 k    {, g: k5 [( H1 P8 W- r$ x
            if( pPrev )
    ! E6 o8 I, y, P6 c            pPrev-&gt;pNextInIDHashBucket = pPt-&gt;pNextInIDHashBucket;
    * ]) |# S' ^1 H) y1 ^        else
    + K5 g2 v& p  A7 m6 n4 x) D" t            m_pstIDHashBucket[bucket] = pPt-&gt;pNextInIDHashBucket;' j- h. z0 Q; z8 W
            pPt-&gt;pNextInIDHashBucket = NULL;
    & O. F: F% Q* D    }</P>& D. e0 M. [. T$ H) D
    <P>    // Unlock the hash bucket) u( W/ J$ Y3 `% G# J* X
        m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();" c# S) Z% x0 E& Q* F
    }</P>! |$ a8 _( L0 ~2 s' O5 n* u
    * w; I$ H6 o+ X" s9 ^1 F
    <P>" ]7 N! n( @/ ^" q+ l0 u; F! `
    //-----------------------------------------------------------------------------) o- d  z" c% c' ~- s
    // Name: 7 Z$ |5 M. I% A& N
    // Desc: 1 x2 t. |. M8 \2 S0 Q/ E& z) Z
    //-----------------------------------------------------------------------------( H0 p# D& c2 _' M: ?
    void CMazeServer::SetPlayerDataForID( DWORD id, PlayerData* pPlayerData )
    . ^0 m$ p$ K& j{
    1 z( n  X  w+ u    // Make sure this player isn't added twice to the m_pstIDHashBucket[]* ^5 K  U" ~9 n# i+ r
        // otherwise there will be a circular reference' H) j. M+ V' j8 d2 [8 t3 d9 E/ e8 H
        PlayerData* pSearch = GetPlayerDataForID( id );1 F/ V; d0 E8 {# R3 o$ \0 ?; T
        if( pSearch != NULL )2 z! `' k, M3 r5 p+ x5 B. t7 r
            return;</P>7 d* N( K. c6 `- g8 h1 j; q  A
    <P>    // Hash the ID to a bucket number
    + K* C/ y% ^( R4 n7 u    DWORD   bucket = IDHash( id );</P>
      r4 p* p2 T& O' x+ T<P>    // Lock that hash bucket
    ( R" I3 g! c7 }2 @' x    const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;: m! _+ w: D* c; M1 b- ^0 [
        m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>
    ; e# O: f3 s( F4 s4 u<P>    // Add player onto hash bucket chain
    % z+ S$ \8 G- [% W6 O5 }    pPlayerData-&gt;pNextInIDHashBucket = m_pstIDHashBucket[bucket];& H) W" [1 Z$ l2 s4 F
        m_pstIDHashBucket[bucket] = pPlayerData;</P># {/ ~' J: S" h7 [
    <P>    // Store net id in player
    " J4 i' |" {" l/ n0 |    pPlayerData-&gt;NetID = id;</P>
    8 M0 z0 g  u6 j' L2 y- r2 z<P>    // Unlock the hash bucket( `* Z4 u- |; C! l
        m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();
    , r/ ?9 H$ l! J, ~( |& N, A}</P>
    . q. C! R% X8 d  l; c! h2 p
    - U' b$ @( W0 ]" M6 l1 Q<P>, E* F. N# m5 I+ U
    //-----------------------------------------------------------------------------$ D7 `: @3 p4 t6 U! [
    // Name: 6 O9 b! v$ c; s  `
    // Desc: 4 ]7 e$ O/ y% A2 x2 H3 w7 z
    //-----------------------------------------------------------------------------
    % c/ z5 y* f! T, {PlayerData* CMazeServer::GetPlayerDataForID( DWORD id )9 Q$ q4 b+ J7 X+ m1 D
    {& s/ L0 ~" P, Y# V1 o, M, s
        // Hash the ID to a bucket number. O9 I9 W" G5 F
        DWORD   bucket = IDHash( id );</P>
    # p* `# [, U  U# R+ p5 ~( y<P>    // Lock that hash bucket
    . c  v) @0 d& i6 G8 ]8 E; k5 J    const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;
    4 ]$ [" \" W# p* V' q    m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>
    2 {7 n5 Q# |2 c1 @6 S$ O0 ^<P>    // Loop though players in bucket until we find the right one
    " T4 z- M1 F  L    PlayerData* pPlayerData = m_pstIDHashBucket[bucket];
    % q/ T: J9 A0 o2 c( _5 v    while ( pPlayerData )( r) P# @4 x( r- _" p9 E0 Y6 ]
        {
    : z$ }, @7 n0 \% f( J% n        if( pPlayerData-&gt;NetID == id )
    . e8 t1 v% q' a" W7 V            break;* V; p# h! y. t( [0 ^+ X
            pPlayerData = pPlayerData-&gt;pNextInIDHashBucket;
    & E; _/ y7 [7 ~- F5 k: L  T    }</P>
    6 l6 X$ [- D# ^; P4 j! a<P>    // Unlock the hash bucket' Z* t! L" U/ L0 D1 v% D
        m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();</P>
    # y0 u: K) k- \0 v<P>    // Return the player we found (will be NULL if we couldn't find it)9 Z6 }5 Z, Y! p! e+ ]
        return pPlayerData;
    3 `7 X; A% d! t8 p. ?1 _}</P>' w, ?1 ~* a0 [+ D2 a) K0 j

    6 @8 I. t$ Z) q( P3 m3 P6 }<P>
    2 C; Y7 N- f( M9 u6 ^: S. m; _//-----------------------------------------------------------------------------& f3 l* b5 I, i( B$ q- [
    // Name:
    3 Z8 r2 B% t4 O) `. K// Desc: calls DisplayConnectionInfo for each connection in a round-robin manner
    / ]  P9 h9 h, B; d) n# K& ^* _) K( D//-----------------------------------------------------------------------------1 s3 \& P2 \. U$ a% _. U1 r
    void CMazeServer:isplayNextConnectionInfo()
    + D1 E( M- H7 b0 E& y3 a# ]{5 }# b2 N+ ^$ ^! C
        if( m_pNet )( k; ]% H4 r  Q1 M8 d& Y
        {
    # c( B2 D* S8 ?' Z1 E+ c        // Find the player that was displayed the longest time ago, and display it.
    " r% `2 V- a& B        FLOAT fCurTime = DXUtil_Timer( TIMER_GETAPPTIME );
    , S. v7 J) {$ P4 |        PlayerData* pOldestPlayerData = NULL;  n2 |0 S7 T8 d2 ~2 b2 }
            FLOAT fOldestTime = 0.0f;</P>
    + I8 n8 Z. j& ]$ z* m% B/ o7 a0 }<P>        m_PlayerDataListLock.Enter();</P>
    ! X" n  q  ^4 y<P>        PlayerData* pPlayerData = m_pFirstActivePlayerData;
    ( n( ]/ G( v. S: `        while ( pPlayerData ). p: I, j* ]+ b5 c; S( |" t" E
            {
    ! m9 s# t8 t9 a7 m) ^            if( fCurTime - pPlayerData-&gt;fLastCITime &gt; fOldestTime )5 E: f  x/ {# v/ ]
                {" ]& I% {# H+ U4 U" Q
                    fOldestTime  = fCurTime - pPlayerData-&gt;fLastCITime;
    7 j4 U! E4 I9 Q4 J7 e% F                pOldestPlayerData = pPlayerData;' x( z3 \* ]8 b# f+ l/ u8 u
                }</P>
    ' e8 i7 y* l) @* u4 g<P>            pPlayerData = pPlayerData-&gt;pNext;
    # r9 e. c: M- {        }</P>
    7 x# H* e8 ^4 U<P>        // Display the player with the oldest CI field, and update its CI field.
    8 e# y( L! v: J0 m; K) j. U4 j        if( pOldestPlayerData )
    6 H0 b1 X7 x4 S9 w        {  C5 M! X- }2 ^- P) D5 K
                ConsolePrintf( SLINE_LOG, TEXT("Displaying connection info for next player") );
    1 [, V" C6 X  m' ]- F, ^            DisplayConnectionInfo( pOldestPlayerData-&gt;NetID );
    6 v4 g- z# \  ~, a! J- A! W            pOldestPlayerData-&gt;fLastCITime = fCurTime;
    1 {5 D" S8 o! Q  V/ R9 r  M1 h        }
    " k: M- T, C1 x; e9 ]7 d, N  A        else& X2 ?. c/ u# X/ T  n- z- D
            {
    # \8 X( o! E- o3 J# i# h6 G$ I            ConsolePrintf( SLINE_LOG, TEXT("No players found") );
    : r' ~: s; ^7 J0 o) i        }</P>9 @. Q9 |7 v, |" y, L
    <P>        m_PlayerDataListLock.Leave();' [* R0 ~$ W5 }1 V3 d% O
        }5 i  `) r* y/ i% S% r
    }</P>
    : }/ [; Q" h2 L; _  U8 n2 G
    0 c" D4 Q! K& j" u<P>
    ) H/ |& j1 d) @' P1 l//-----------------------------------------------------------------------------
    ' X1 _4 S/ s6 z3 p: V// Name:
    2 g* L  z/ z. h6 \. r& N// Desc:   |! B1 ^( J, c( J" p& j8 o* A
    //-----------------------------------------------------------------------------
    ; @4 c/ \& G3 L) y1 C3 ?void CMazeServer:rintStats()' F' Q' t3 w# }0 a/ {
    {" n9 o- O, E0 p7 c- _( l7 L
        ConsolePrintf( SLINE_LOG, TEXT("Thread count: Active=%d Avg=%.2f Max=%d"),
    1 s6 D2 d4 M6 o                                    m_wActiveThreadCount, m_fAvgThreadCount, m_wMaxThreadCount );* s+ g% Q1 Q( \9 F6 s; Z" `
        ConsolePrintf( SLINE_LOG, TEXT("Thread Time: Avg=%.4f Max=%.4f(s)"),
    0 F6 d, s) O& S                                    m_fAvgThreadTime, m_fMaxThreadTime );
    7 f$ I2 ?+ f* L: j+ T    ConsolePrintf( SLINE_LOG, TEXT("Players online (not including server player): %d"), m_dwPlayerCount );+ P4 w/ V3 C$ @4 k
        ConsolePrintf( SLINE_LOG, TEXT("Peak player count: %d"), m_dwPeakPlayerCount );" K4 B$ D$ z6 |2 d( S" i
    }</P>) J& D: P2 Z& X' m

    , Q. [3 s2 x6 h2 s<P>
    ! y) N& K3 M  D. R( t//-----------------------------------------------------------------------------: D1 f7 A/ H% ]! J: p% a
    // Name:
    $ _5 _) r4 Y1 l" `7 U& D& M2 [// Desc: * r' O6 O* d2 \" @
    //-----------------------------------------------------------------------------/ U. j' \$ c& ]' D
    void CMazeServer:isplayConnectionInfo( DWORD dwID )
    & q4 {8 c& v  p) c, G{+ A$ s- g: ]) ?2 f3 I9 t$ d
        TCHAR strInfo[5000];1 U( R1 A3 _) W7 n2 D2 G0 Y( n
        TCHAR* strEndOfLine;
    $ d. m' ^) h. [; J/ O    TCHAR* strStartOfLine;</P>
    % [, L& {/ K9 P8 T  @<P>    // Query the IOutboudNet for info about the connection to this user, J2 {; Y# v! v8 ]
        m_pNet-&gt;GetConnectionInfo( dwID, strInfo );</P>6 g! y" x/ V) ]: Y9 ?9 s
    <P>    ConsolePrintf( SLINE_LOG, TEXT("Displaying connection info for %0.8x"), dwID );4 K( ^/ L( Z4 A
        ConsolePrintf( SLINE_LOG, TEXT("(Key: G=Guaranteed NG=Non-Guaranteed B=Bytes P=Packets)") );</P>
    9 S6 t7 a% ?1 n% m0 m<P>    // Display each line seperately$ T% ?! }3 n7 e6 H/ y1 X3 k) F
        strStartOfLine = strInfo;
    - ^& P" p3 ~$ ~: }    while( TRUE )5 f+ W' d  a/ Z. V6 y: n5 C$ Z
        {; L" g8 X! F& d! ~: k3 A1 u( Y/ i0 {
            strEndOfLine = _tcschr( strStartOfLine, '\n' );
    6 }" q3 B9 G0 a0 w- p6 I        if( strEndOfLine == NULL )- ?" G! d" T( P; V% O# g
                break;</P>5 \; M* Z- C7 E
    <P>        *strEndOfLine = 0;' X- r9 d, [/ M0 `5 H0 j* \# h
            ConsolePrintf( SLINE_LOG, strStartOfLine );
    4 g/ R; |4 p: D4 g        strStartOfLine = strEndOfLine + 1;% H! w# c6 w' W6 W" M
        }5 L' g1 {7 z. C0 `, y7 g
    }</P>- v' s4 G1 s0 }1 T3 U
    3 o& r$ b  V$ ~, G% C3 t
    <P>
      G1 `* ~: `( |$ n  `7 r//-----------------------------------------------------------------------------6 Y. U* e6 i, `2 V& K) E3 d8 ?
    // Name:
    . P) }0 \2 ~; C& q// Desc:
    3 a( e) F& c2 P' T' i$ e- p+ g1 ?//-----------------------------------------------------------------------------
    9 q' C9 q% d8 r! m/ l' THRESULT CMazeServer::SendPacket( DWORD to, void* pData, ! u4 v) J5 O0 w* h- U
                                     DWORD size, BOOL reliable, DWORD dwTimeout )
    9 R  Y; A7 N2 ^4 o) _  A) }{
    6 \# h' E1 }- K' v6 r4 C& Y    // Chance of forcing any packet to be delivered reliably
    ; p. \" y2 Q4 ~    if( m_Rand.Get( 100 ) &lt; m_dwServerReliableRate )
    - B: z: H. g% V. V0 z% C        reliable = TRUE;</P>6 `4 {' u  j$ F7 F% v% H
    <P>    return m_pNet-&gt;SendPacket( to, pData, size, reliable, dwTimeout );
    0 ?% n/ N2 R8 I- W! f# @2 J}</P>5 }8 p6 V; j: F

    ! a9 q$ c7 O- b8 s8 w0 o* M<P>
    & A7 F8 W/ s0 d/ V# z//------------------------------------------------------------------------------ W* h# h3 K* @; d. z
    // Name:   ]4 R  Q: T+ M; c& d, B
    // Desc: 3 N* A3 ~- e5 E% i8 D7 I
    //-----------------------------------------------------------------------------
    , R/ N# {; M8 ?2 U/ U! [) A4 `void CMazeServer::SendConfigPacketToAll( ServerConfigPacket* pPacket )
    0 O6 A& b4 H7 t$ H{( }7 R7 v' v; Z
        // If we're up and running, then send this new information to all clients
    9 v) E/ f2 A, J    if( m_pNet ); x; @- T8 A, \4 S; K. t
        {
    ! U$ ?3 M8 z" i( T' T) T/ X        //Use the AllPlayers ID
    / [$ ]2 E" m" ?/ i, x: {" i3 Y        SendPacket( DPNID_ALL_PLAYERS_GROUP, pPacket, sizeof(ServerConfigPacket), TRUE, 0 );/ a4 `6 I2 z: ]* f+ y& r
        }
    " b; u3 A' s+ s}</P>
    6 D/ K9 R; ]3 ^* R2 a+ g) d# O) Q* \4 w
    <P>3 E. r" [" G4 e
    //-----------------------------------------------------------------------------
    / d' g: X9 ?8 `! Z- A. x// Name: ! ]8 N* |2 {% R8 Z& W9 ^4 u
    // Desc: # Z. k: p0 H6 t0 C
    //-----------------------------------------------------------------------------
    # m! t* z: N* ]5 X" n5 avoid CMazeServer::SetClientReliableRate( DWORD percent )
    5 U7 x& m: T& f; W3 d/ \{
    & l" y) X& B( f9 @% ]. t    // Update client config, and build packet containing that data% W7 T9 |2 h) C
        m_ClientNetConfigLock.Enter();7 l! i' s" W6 c! s1 x) v
        m_ClientNetConfig.ubReliableRate = BYTE(percent);
    - U! U$ h* Y4 c/ v% |5 ?. }    ServerConfigPacket packet( m_ClientNetConfig );
    ) ^% a* S+ [  Y$ L5 k" Z7 Q    m_ClientNetConfigLock.Leave();</P>: o4 b- Y1 m3 V% O
    <P>    SendConfigPacketToAll( &amp;packet );
    1 o! ?8 U+ |7 e! t1 `4 I) p}</P>" j' f" B; y( [; A& `3 e& ~; S
    % U2 i$ l$ C* N- z5 g3 }1 t
    <P>6 T: e1 T. s( V& b& K( q
    //-----------------------------------------------------------------------------
    ! L8 r5 O6 @2 e0 v// Name:
    3 A' G$ l7 O3 [( x8 f// Desc: 7 k/ }" H6 C9 N& X
    //-----------------------------------------------------------------------------2 r7 }7 F' B& r9 _
    void CMazeServer::SetClientUpdateRate( DWORD rate )! [+ N- E# {  T* D# n) S4 l
    {8 F+ }2 G" D& X1 j
        // Update client config, and build packet containing that data
    , Y, x* a- G" t# t3 u6 q    m_ClientNetConfigLock.Enter();
    $ M# B* X! d, p6 K  Q# Z# n: g    m_ClientNetConfig.wUpdateRate = WORD(rate);+ N% ?3 s1 y5 j) [
        ServerConfigPacket  packet( m_ClientNetConfig );
    8 s$ d9 V3 C; P5 D    m_ClientNetConfigLock.Leave();</P>; Y* y* q: |$ J- A2 p3 L
    <P>    SendConfigPacketToAll( &amp;packet );  j6 R( ^7 h5 b# e8 L) V1 Y
    }</P>, @. S3 `% G3 D/ [7 R
      ~; m" I4 O% y. _* W4 L
    <P>( m2 L5 m+ K7 Y( {6 p: D& p: u* e
    //-----------------------------------------------------------------------------
    * I( k+ ?8 k) i8 k& D// Name: 7 d# s9 a( h5 o# d0 ~
    // Desc:
    ; h; b" I4 {, |: h% X//-----------------------------------------------------------------------------; B. z. R7 y* J* B% u& M  o
    void CMazeServer::SetClientTimeout( DWORD timeout )$ Q; M1 A3 |! y* i) ~
    {
    # i6 g, |; H+ Z! |    // Update client config, and build packet containing that data* C0 V  T" u+ d+ J6 N: l
        m_ClientNetConfigLock.Enter();) h6 p" ?/ Z- P; |" K" q* ^/ _4 \
        m_ClientNetConfig.wTimeout = WORD(timeout);
    7 A$ a4 L! a$ Y3 C    ServerConfigPacket  packet( m_ClientNetConfig );; j2 n8 d3 @6 @0 m; }
        m_ClientNetConfigLock.Leave();</P>
    0 u' }) F5 c: M: Z9 u0 w<P>    SendConfigPacketToAll( &amp;packet );+ X6 I) [* C8 _2 P/ P
    }</P>
    1 w- N: x3 E6 x% _  ~0 b; R
    3 D' z$ x; r9 b: x# C7 e<P>
    0 d6 S- Z# g1 W- J; l+ g//-----------------------------------------------------------------------------1 K2 ~1 ?2 A; s0 o7 }
    // Name:
    1 _5 W; S" G8 O. _( K8 m1 x// Desc: 6 W8 z- M9 c2 y+ B. h. g" Y, ~
    //-----------------------------------------------------------------------------
    ( K/ a0 U. J& vvoid CMazeServer::SetClientPackSize( DWORD size ), S+ c6 a# L; o1 w: d3 t+ e
    {% w. w9 y$ a6 c1 ~/ I/ ]
        // Update client config, and build packet containing that data
    % s4 ]2 F" h, \6 c7 O6 R7 f    m_ClientNetConfigLock.Enter();
    5 P, c  {: `0 S) r! m   
    / @3 O9 ^0 \' |8 O  `    m_ClientNetConfig.ubClientPackIndex++; //Increase index and verify location in array.7 f" H3 A/ U& G% r) N
        if(m_ClientNetConfig.ubClientPackIndex &gt;= PACK_ARRAY_SIZE)   
    3 Z* d. M( R/ ]* T- ^' T0 {        m_ClientNetConfig.ubClientPackIndex = 0;</P>
    0 o* \0 K, d' _  @* m6 ^5 T, B, J3 v<P>    m_ClientNetConfig.wClientPackSizeArray[m_ClientNetConfig.ubClientPackIndex] = WORD(size);& V$ W+ N1 P" r* B3 T. a* L; ], p2 O8 u
        ServerConfigPacket packet( m_ClientNetConfig );- }) D/ }1 X0 G( r0 R$ j
        m_ClientNetConfigLock.Leave();</P>4 I: @% T" D6 A  x# B
    <P>    SendConfigPacketToAll( &amp;packet );' i5 P* x1 L- z1 M/ y7 F
    }</P>+ |3 Q" q4 u: c, _8 c( `7 d
    $ I2 u0 j* Q0 b2 I
    <P>
    5 r; N6 Y0 |  y//-----------------------------------------------------------------------------
      D% P4 O  a0 ^2 _5 K/ P// Name: / z$ j1 a" y. A# r
    // Desc:
    2 W" t4 V$ b2 S* [" g' h/ r5 e, ]//-----------------------------------------------------------------------------, e5 F$ y8 a9 _# z: x4 @
    void CMazeServer::SetServerPackSize( DWORD size )& G5 `  R- \2 S% Q; f7 P; t& `- i3 J
    {$ b2 U; p6 Y7 C# D: ^- B6 J
        // Update client config, and build packet containing that data8 ]( |' O2 m' I+ R; ]. D
        m_ClientNetConfigLock.Enter();
    ! O! |+ b# x% _; R2 h" S8 n    ' Q" l% S5 h: c
        m_ClientNetConfig.ubServerPackIndex++; //Increase index and verify location in array.; \, C3 m' p! _; Z0 g" b
        if(m_ClientNetConfig.ubServerPackIndex &gt;= PACK_ARRAY_SIZE)   
    % }/ }. s; z/ t2 Q  |" a) E; P        m_ClientNetConfig.ubServerPackIndex = 0;</P>
    0 x# s; z+ C3 D4 F! _; G<P>    m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex] = WORD(size);
    0 Q. b) b% r- Y% F  U% a1 I    ServerConfigPacket packet( m_ClientNetConfig );6 I* n: u$ c8 o, }' c
        m_ClientNetConfigLock.Leave();</P>8 G+ z% w/ s+ [: I
    <P>    SendConfigPacketToAll( &amp;packet );
    + u/ u) Y1 Q, K- F/ q1 V}</P>- F4 m  P0 C, S) Q' i9 k
    <P>! K# _0 _, `, J: c1 d
    //-----------------------------------------------------------------------------
    + H' z0 V8 K& ~// Name: . i3 U! A/ ]3 I  ]; t- Y
    // Desc: ( J9 Z. U  \/ W( P4 v
    //-----------------------------------------------------------------------------  N$ O! f+ q# _3 p
    void CMazeServer::SetClientThreadWait( DWORD dwThreadWait )# R! ]+ ?( h) K: ~2 `; |
    {: i" K, \; e! Q# V* C
        // Update client config, and build packet containing that data+ p7 U6 _9 u1 u* h) y6 G
        m_ClientNetConfigLock.Enter();& D3 y" w: C* s; V% [+ r% i
       
    6 z- Q& n* A  ^' [1 d    m_ClientNetConfig.dwThreadWait = dwThreadWait;
    % |1 ^3 Z8 u" r$ m! R2 _    ServerConfigPacket packet( m_ClientNetConfig );
    ! z" S. n. J# I1 |0 Z    m_ClientNetConfigLock.Leave();</P>* U& M2 ~: M9 u6 `
    <P>    SendConfigPacketToAll( &amp;packet );  y! N! J& Z5 H2 C, y/ J& A6 V
    }</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-12 22:22 , Processed in 0.467536 second(s), 51 queries .

    回顶部