QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 4169|回复: 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>
    ' k- i1 Q6 M$ ]0 M# |! r3 z- J<>// File: mazeserver.cpp
    6 v5 b# ?$ A  _1 i" W9 x//% P: ~$ K. j) _1 h
    // Desc: see main.cpp
      U: ~! I& H9 m- o3 \//
    : `/ T, V- C) {// Copyright (c) 1999-2001 Microsoft Corp. All rights reserved.0 l% d" Z# F5 Z
    //-----------------------------------------------------------------------------
    & l' D: l4 R) k, F+ L/ L#define STRICT
    . Y$ u$ r7 C: I. K#define D3D_OVERLOADS
    + b4 T  l& Z, A) N( ^6 g#include &lt;windows.h&gt;
    & N; k1 w; X4 e#include &lt;d3dx.h&gt;
    % e# b; U0 A+ g/ [. ?#include &lt;stdio.h&gt;
    & m4 H  D5 ^- i7 F! C7 Y7 N2 L#include &lt;math.h&gt;" ~- L$ R- N3 n: m# ]) y
    #include &lt;mmsystem.h&gt;% ~6 U5 p! n) P( x% O- r2 M
    #include &lt;dplay8.h&gt;
      v* l+ }* a9 O' V#include &lt;dpaddr.h&gt;
    $ d( ?6 m* t6 R# c#include &lt;dxerr8.h&gt;
    9 w! v  ^* w; r, `3 x* W#include "DXUtil.h"2 P5 M: I7 d0 J/ Z! A% F
    #include "MazeServer.h"
      V' `+ S: @1 ]% Z4 ?#include "ackets.h"
    % D! k) N5 f) t2 U$ b- P. \#include "Maze.h": e) }9 R7 L1 Q7 h9 C, G
    #include &lt;malloc.h&gt;
    % q) n. t% Q$ ?4 b( S: y#include &lt;tchar.h&gt;</P># ]# n: O. Q* P6 d& `; z

    2 ?4 E) s( b2 C( _6 g' R<>//-----------------------------------------------------------------------------
    7 H- y! B+ {; \9 v9 y// Name:
    , V$ c& x# {2 U; ]// Desc: , I! l) s5 r" y$ {) X% p% P
    //-----------------------------------------------------------------------------) F1 o4 }' u* G) O  h, _7 r  g# Q
    CMazeServer::CMazeServer()
    2 u  C7 O/ f7 k- ^7 {{
    . V  D' f. A6 L" u& A* V' h    m_dwPlayerCount         = 0;* _, m. J% D  W4 d3 _
        . f- I2 O& _* q# u
        m_wActiveThreadCount   = 0;
    / {2 i$ s& V3 z2 q  P# a    m_wMaxThreadCount      = 0;/ f8 Q& f( t9 d5 Z+ F! Q! P
        m_fAvgThreadCount      = 0;
    . d) v. [& H- c7 k7 g0 W7 ^    m_fAvgThreadTime       = 0;; C# ?1 \1 l# y- ^" p8 p$ }
        m_fMaxThreadTime       = 0;</P>8 _! v2 Y# Z" ~( m* w5 ?: k
    <>    m_dwServerReliableRate  = 15;2 k  v7 h( M  d- D) G* L
        m_dwServerTimeout       = 150;& F  v0 `# w1 U, L! Y" e/ @0 Q
        m_dwLogLevel            = 2;) q4 t8 W9 C8 [- x+ ~7 u
        m_pMaze                 = NULL;</P>! C1 P0 b, q* T& v. T! O. C
    <>    m_ClientNetConfig.ubReliableRate = 15;
    * B+ {2 M, K3 Q' _3 E& o    m_ClientNetConfig.wUpdateRate    = 150;  o4 _  n" Q  ~) R5 R  h- p
        m_ClientNetConfig.wTimeout       = 150;</P>1 k! ^, U) V/ }' `& y
    <>    m_ClientNetConfig.dwThreadWait = 0;</P>
    9 k3 o" s7 _- o- @6 ~' x<>    m_ClientNetConfig.ubClientPackIndex = 0;
    6 L$ Z7 s, g0 W9 y9 t9 U    m_ClientNetConfig.ubServerPackIndex = 0;' V( B- u8 J% X0 F6 r
        for(WORD x = 0; x &lt; PACK_ARRAY_SIZE; x++)$ g6 j" c. Z) m6 t% b" @" K
        {! d: u( x/ ?5 S4 ^4 N! T" h
            m_ClientNetConfig.wClientPackSizeArray[x] = 0;
      C. h$ ?5 ~1 p        m_ClientNetConfig.wServerPackSizeArray[x] = 0;
    % |2 i5 s* L' [* |    }
    9 }# K1 ^" F3 B& @/ f7 e' [}</P>
    ! R8 w( m% z5 R$ n" W5 l+ P, G
    ' q; d8 I. f: _, l<>7 w& g# m+ S+ K- ^
    //-----------------------------------------------------------------------------, \2 d! ^* B+ t. D! h& G
    // Name: 7 B2 q! K2 ?/ K3 ]* K
    // Desc:
    5 B& @. I; O' Q* b2 W% ?: c. N4 |//-----------------------------------------------------------------------------# c) U4 h/ g; c
    HRESULT CMazeServer::Init( BOOL bLocalLoopback, const CMaze* pMaze )8 p0 W" k9 h5 y$ N) I
    {4 ]1 f% w1 }3 ~& Z- \. Q& w
        m_bLocalLoopback = bLocalLoopback;
    1 Z/ C1 m- |4 ~9 L" l% M( u9 K    m_pMaze = pMaze;
    7 ^3 M) c* `" }2 l9 I    if( m_pMaze == NULL )
    " K" z( Z( n, ~+ U. V        return DXTRACE_ERR( TEXT("aram"), E_FAIL );</P>
    & l: N/ @, v" \0 A<>    // Grab height and width of maze! t; s, Q. [' z
        m_dwWidth = m_pMaze-&gt;GetWidth();
    5 R( Y" H  K! D+ v+ _    m_dwHeight = m_pMaze-&gt;GetHeight();</P>
    " O2 c  B" a. d/ x' U$ @6 g<>    m_ClientNetConfig.dwMazeWidth  = m_dwWidth;
    $ S% b$ g/ q7 v" \+ s    m_ClientNetConfig.dwMazeHeight = m_dwHeight;</P>0 |# w2 x. U8 F5 |7 e
    <>    // Validate size. Must be a power-of-2 times LOCK_GRID_SIZE. Compute the shifts.4 I( O/ g. W) O5 i* A' \( o1 \# y
        if( m_dwWidth &gt; SERVER_MAX_WIDTH || m_dwHeight &gt; SERVER_MAX_HEIGHT )
    0 @& T3 H) y2 n: d& S        return DXTRACE_ERR( TEXT("Maze height and width need to be less than 128"), E_INVALIDARG );2 V, R- y# D8 L/ ?3 T5 |6 t
        if( (m_dwWidth % LOCK_GRID_SIZE) != 0 || (m_dwHeight % LOCK_GRID_SIZE) != 0 )! u3 j; H9 x" Y1 r. J7 V8 u  i) g
            return DXTRACE_ERR( TEXT("Maze height and width need to be divisable by 16"), E_INVALIDARG );</P>9 j# e/ q$ R0 e8 K1 ]# {9 Y7 U
    <>    DWORD scale = m_dwWidth / LOCK_GRID_SIZE;1 R1 F& h0 w+ z' @) A8 Q- P
        m_dwMazeXShift = 0;
    $ g; }4 @, [$ C9 S* q4 M    while ( (scale &gt;&gt;= 1) )
    ; c6 t' k3 m4 T. I* [  ^2 c) f: p        m_dwMazeXShift++;</P>9 X5 t# B1 W+ i
    <>    scale = m_dwHeight / LOCK_GRID_SIZE;
    6 v  W% R+ W5 V- x: R: P    m_dwMazeYShift = 0;  S9 _/ W' H+ F+ x8 l% o
        while ( (scale &gt;&gt;= 1) )! |) I+ [! w' I; J# z
            m_dwMazeYShift++;</P>0 ]" l( V% l1 {& }( ^
    <>    if( ((DWORD(LOCK_GRID_SIZE) &lt;&lt; m_dwMazeXShift) != m_dwWidth) ||7 n. f) T( Z3 K6 J
            ((DWORD(LOCK_GRID_SIZE) &lt;&lt; m_dwMazeYShift) != m_dwHeight) )* k2 r. g! l0 Y, g. |5 K
            return DXTRACE_ERR( TEXT("Maze height and width need to be power of 2"), E_INVALIDARG );</P>
    0 t% F6 S4 k+ w- K9 E<>    // Initialise the player list
    7 ?( S; ]9 H/ B, I$ u    ZeroMemory( m_PlayerDatas, sizeof(m_PlayerDatas) );
    + y$ y4 ]. B2 L$ p    m_pFirstActivePlayerData = NULL;
    # ^3 R6 ?/ P/ m: s0 |    m_pFirstFreePlayerData = m_PlayerDatas;8 v7 [& R2 i0 s1 g' O: Z! R, A
        for( DWORD i = 1; i &lt; MAX_PLAYER_OBJECTS-1; i++ )) o- z/ i9 K- T1 X! |
        {6 P1 S" _) q- F
            m_PlayerDatas.pNext = &amp;m_PlayerDatas[i+1];: c' x5 E% Q8 o" J: Y) j0 H
            m_PlayerDatas.pPrevious = &amp;m_PlayerDatas[i-1];# T1 o4 ~' C. ]6 L! s1 N. J
        }</P>
    ' z' l  h6 q0 [7 c! t! E<>    m_PlayerDatas[0].pNext = &amp;m_PlayerDatas[1];0 l4 D3 H9 ]: m3 A# ~
        m_PlayerDatas[MAX_PLAYER_OBJECTS-1].pPrevious = &amp;m_PlayerDatas[MAX_PLAYER_OBJECTS-2];
    9 {6 E) I. z, _- G0 k: v    m_dwActivePlayerDataCount = 0;0 k1 s$ p- I* @: \; G0 p
        m_dwPlayerDataUniqueValue = 0;</P>
    9 J! H7 ?1 f4 U/ p' k, ]! e. W<>    // Initialise the cells; Y" G2 `% {  G" F% {
        ZeroMemory( m_Cells, sizeof(m_Cells) );
    , y' a/ s) z; B; z/ q: J    ZeroMemory( &amp;m_OffMapCell, sizeof(m_OffMapCell) );</P>
    7 [5 k1 M5 B( E% d$ Q<>    return S_OK;
    , ?7 W& C  C8 U}</P>
    0 h) b0 V8 u6 b+ l- A- r  y! |! r# J$ A  j& f  i% P' w
    <>8 y7 e2 z5 z. B+ t; j6 c
    //-----------------------------------------------------------------------------2 c- m6 _% n- r( c, r! z, k- Z$ G" p
    // Name: % R/ U8 C7 e! E. R2 j0 P
    // Desc: - s- ^$ q) E6 D7 k$ R. r
    //-----------------------------------------------------------------------------9 P1 T/ r9 _, ~2 W) o8 A
    void CMazeServer::Shutdown()8 \0 h3 W5 w( E. R8 _
    {# p" o' v- D8 R6 d) C
    }</P>
    2 P; y% v( \% D" A: {5 [( Z. Q, q; E+ Z, c' }6 @2 i3 l
    <>3 H* E/ f9 i/ X. S- x2 Z
    //-----------------------------------------------------------------------------6 s& O& ^' `; }: {
    // Name:
      }) e5 r- P7 x" p& N// Desc: $ e( S" v$ a) L3 T3 Z
    //-----------------------------------------------------------------------------6 x% G- v$ B* ]9 h- u; {" ?6 f2 {
    void CMazeServer:ockRange( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )
    2 k  [- u* V+ T9 E/ l) x{
    9 ]" d  n1 u9 ?2 U' f" l' q    m_LockGrid.LockRange( x1&gt;&gt;m_dwMazeXShift, y1&gt;&gt;m_dwMazeYShift ,9 G  N( z8 y1 M6 J: V4 r
                              x2&gt;&gt;m_dwMazeXShift, y2&gt;&gt;m_dwMazeYShift );9 w$ \0 C9 P0 v5 L8 a
    }</P>
    & R( o6 c/ L( k7 q3 h, P. w
    3 J6 N' Z: {7 G0 y- X( `7 E<>
    ; r+ \+ ^9 _. p( T& ~//-----------------------------------------------------------------------------; r* q7 ^5 s2 N% j! Y
    // Name:
    , F4 W1 }; Y, N& S9 R) n" U) r4 y// Desc: - g( Q) S& S# y$ P3 }# Z8 q
    //-----------------------------------------------------------------------------. s$ C$ _3 C% |( F! e
    void CMazeServer::UnlockRange( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )  u$ Y- ]; V' ^- P4 }
    {  x: c- X) u* {2 `9 d* U2 P, |
        m_LockGrid.UnlockRange( x1&gt;&gt;m_dwMazeXShift, y1&gt;&gt;m_dwMazeYShift ,7 O0 ~% y" T% f/ l# u" g& c+ N
                                x2&gt;&gt;m_dwMazeXShift, y2&gt;&gt;m_dwMazeYShift );( k4 S' p5 q  F6 s. D6 L2 C
    }</P>' {2 i; J& Q4 y% O3 o( J- {  n

    0 A1 y! N/ H6 |; `<>
    - |' V4 Q# T5 i+ R//-----------------------------------------------------------------------------( P5 G: I- S( W# y; i
    // Name:
    : W; Y6 }- H- Z# e1 w- ~( q// Desc: * N9 ~  P4 x1 p1 G# N3 G
    //-----------------------------------------------------------------------------0 M# B& N6 L8 z& J
    void CMazeServer:ockCell( DWORD x, DWORD y )! P+ R1 k, {' x* h/ Q1 I
    {
    9 O7 d) B) u5 [% D  b* l    if( x == 0xffff )$ w9 {! |' O) q8 e* Y5 C; H
            m_OffMapLock.Enter();& P* |2 ~# ~6 L- m( F! C8 W
        else
    7 C  K  A& q6 w9 n: M        m_LockGrid.LockCell(x&gt;&gt;m_dwMazeXShift,y&gt;&gt;m_dwMazeYShift);
    9 ^" x' @" `! w4 |* e}</P>( y2 U  X9 i0 z" J' h* i1 ]# [

    ( ~5 c, B, v' w# Z<>
    ) U' V7 N, I  k8 F! n: P7 o& ^//-----------------------------------------------------------------------------, I0 `  k4 t- Y8 ~* b3 i
    // Name:
    ' n. J6 s8 i8 ], g. G9 Z" ~// Desc:
    : |+ K& C. F: J//-----------------------------------------------------------------------------
    ! z- |4 F5 S. I! v! n; ^void CMazeServer::UnlockCell( DWORD x, DWORD y )
    / c& |6 g. c$ \; p8 Y) `0 A6 b{
    . |' g6 d/ u9 P2 s: I  f    if( x == 0xffff )
    ' ^" `) n0 ^# o4 x        m_OffMapLock.Leave();
    " S- V- c  K% ]" i    else' G: u0 b2 w8 z; f9 W# N
            m_LockGrid.UnlockCell(x&gt;&gt;m_dwMazeXShift,y&gt;&gt;m_dwMazeYShift);5 x" }; ]0 v' J& U" ]& P
    }</P>
    # {) c7 F# A" B) V6 O% E* a4 q/ H( O) u% R
    <>
    5 g1 u; Q% H: v2 d8 G1 A. H: V% R//-----------------------------------------------------------------------------
    % y( t  s" H* g' M// Name: 8 J1 m& V+ S$ _- H. v& O: r
    // Desc:
    . M% P1 n4 c* Z: a# m//-----------------------------------------------------------------------------
    - Y& ~8 r8 e) u4 r1 uvoid CMazeServer:ockCellPair( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )6 S, I/ x0 [4 ^  w& A5 z6 p
    {
    7 p9 C+ N8 C1 t7 Y1 h0 T* d    if( x1 == x2 &amp;&amp; y1 == y2 )
    + b* `# I6 W* ~, G2 V6 f  Z    {3 T! t3 s) H' N) ^- D( ?1 j; r
            if( x1 != 0xffff &amp;&amp; y2 != 0xffff )+ L' {' P6 O0 ]+ P  s+ @
                LockCell( x1, y1 );
    7 v) _4 g. I. A) {1 M3 B- e8 w        else
    4 c# h" t- Y! g" V            m_OffMapLock.Enter();</P>2 g( g  G* O+ n8 J1 b
    <>        return;
    5 L  d0 L  G: J# B, T    }</P>
    2 ^7 a1 {0 l0 R. X/ Y; i* ~, a<>    DWORD x1shift = x1&gt;&gt;m_dwMazeXShift;
    / a; a9 n' E" E$ W1 u9 W, C4 D    DWORD x2shift = x2&gt;&gt;m_dwMazeXShift;
    " z4 e& C6 c9 r; V    DWORD y1shift = y1&gt;&gt;m_dwMazeYShift;
    2 d3 B3 w+ i) t! d0 z/ h5 i3 I# V    DWORD y2shift = y2&gt;&gt;m_dwMazeYShift;</P>
    5 Q5 d" W* M8 o( y! S<>    if( x1 == 0xffff )) k/ U* S$ y$ E0 a
        {
    * q% Q' f. u6 n+ k" B        m_OffMapLock.Enter();& `- T% B& s0 S+ u  N
            m_LockGrid.LockCell(x2shift,y2shift);
    . T( m5 t; e0 p4 R, r% h) s    }
      H! q( _& S/ P2 d3 e; K    else if( x2 == 0xffff )! k% y/ y" n' H: ]% m
        {9 u4 B3 G* {; W$ g/ }: _; s* \  U
            m_OffMapLock.Enter();: z6 w8 m0 A; {# r  {8 J) Y
            m_LockGrid.LockCell(x1shift,y1shift);
    6 a, S0 z: R) o) L6 M    }1 A  o8 X  l; \
        else 0 m! s! j  x( E; K! _& I& Q. l( }
        {
    ( o$ A0 ~. J" Z        m_LockGrid.LockCellPair(x1shift,y1shift,x2shift,y2shift);5 E* F" F7 X; _4 R2 P; ?
        }! D/ n, M& u1 g& W3 F4 c
    }</P>! Q8 l9 I  s9 c0 Q/ l: G% |; ]% Y
    * h6 T( v, R  `) K
    <>
    ; a5 M0 ]2 r. o' z+ R. ~/ T: b//-----------------------------------------------------------------------------, l* @5 Q6 n1 ]+ k4 H, J
    // Name: ' m  v4 m) U+ x" l$ J. Y& t8 `# {
    // Desc: ! M, Z9 |/ q& I, R; ]1 I
    //-----------------------------------------------------------------------------6 l/ r% A3 R* G- t6 b- y" \6 b
    void CMazeServer::UnlockCellPair( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )
    / ~5 d- Z( C. b$ I; H" B0 P{  W& x7 W. _" E0 G+ w: S( R
        if( x1 == x2 &amp;&amp; y1 == y2 )
    5 |! n* p0 |6 x& y    {
    2 a+ r# ?& h# K" J' H7 d        if( x1 != 0xffff &amp;&amp; y2 != 0xffff )" V- Q9 i9 H1 q3 N8 w2 @4 x
                UnlockCell( x1, y1 );
    : @! X+ b2 P9 V        else
    6 g7 `8 n1 j- {, D$ i/ i            m_OffMapLock.Leave();</P>
    5 ^9 i  e$ Q; ^$ }! D: ?4 Q, d<>        return;
    + G! N; y) t" T1 l) @( j6 q; T    }</P>, B; y7 u. ^$ O0 S
    <P>    DWORD x1shift = x1&gt;&gt;m_dwMazeXShift;# O% d( C; Y. T- a- V, X
        DWORD x2shift = x2&gt;&gt;m_dwMazeXShift;
    $ R& C" |! b4 _0 e& C    DWORD y1shift = y1&gt;&gt;m_dwMazeYShift;
    + U/ A. L( J* x    DWORD y2shift = y2&gt;&gt;m_dwMazeYShift;</P>
    ) ?* T! K. q  k; H  l) r1 g<P>    if( x1 == 0xffff )
    ' C7 N$ P7 ^/ {/ o/ L    {2 Z, |, I% b6 U4 L7 F
            m_LockGrid.UnlockCell(x2shift,y2shift);/ o2 z$ d/ q% R9 T/ @8 D
            m_OffMapLock.Leave();/ g% I  i& F6 r) i: q& _/ ]; t" c
        }
    . h  N, K5 [1 X% `& s. b! s    else if( x2 == 0xffff )
      ?1 R( _% d. t7 [9 W" Z    {
    $ [2 Q. R" A: A+ n' i/ p        m_LockGrid.UnlockCell(x1shift,y1shift);
    ' w$ G  M% r- ?7 k$ z1 P- L0 F        m_OffMapLock.Leave();
    * [. A- j% v+ ]* N- g1 U" Q. S    }; T6 g4 h+ R2 `2 f. x% f
        else , s. z8 d7 K' w, ^
        {
    8 ^1 \+ a6 ?" `1 U& \4 [        m_LockGrid.UnlockCellPair(x1shift,y1shift,x2shift,y2shift);' E4 n9 [. W3 V8 o% M% S8 j
        }
    . Y) ]- C9 r5 [. |" r* x# R4 R) x}</P>
    ) s, C. V" b' i9 B
    1 S- X$ Y' G+ M: G: A5 o<P>0 r4 d. m5 M$ Q. B8 G1 R' O1 t
    //-----------------------------------------------------------------------------
    * n3 v' ]6 m, v' A7 L// Name: : V* h) ?+ f; |& Q
    // Desc:
    3 m+ P) v2 y6 i" G- T8 ~% T//-----------------------------------------------------------------------------2 L. V3 x: H4 P  s
    void CMazeServer::OnAddConnection( DWORD id )
    8 a+ u* S- q; [" `0 G, E{; i' f5 r3 {7 P& Z1 H
        m_AddRemoveLock.Enter();</P>% ~8 U# h' N5 w8 V. J
    <P>    // Increment our count of players1 K4 n) H- z2 R; |, m/ g" q( I
        m_dwPlayerCount++;0 Z2 o3 G; X& L5 a/ V% P8 o
        if( m_dwLogLevel &gt; 0 )
    * |& L" K% ~4 l    {0 w' F7 D& a/ \* o* p
            ConsolePrintf( SLINE_LOG, TEXT("Adding player DPNID %0.8x"), id );
    ; Q- N$ P- u. a0 `: s& W* R9 Z' h        ConsolePrintf( SLINE_LOG, TEXT("Players connected = %d"), m_dwPlayerCount );' {: u' b1 B/ Q
        }</P>0 N' j& {6 y+ z
    <P>    if( m_dwPlayerCount &gt; m_dwPeakPlayerCount )
    , [. Y& C/ I9 y. g9 H8 z; @        m_dwPeakPlayerCount = m_dwPlayerCount;</P>
    4 N, b- c; a8 K+ Q' h, [7 w<P>    // Create a player for this client
    ; C7 c, w5 d& \$ E5 H/ P7 U    PlayerData* pPlayerData = CreatePlayerData();
    * o  l7 ]# c9 }& e3 Q# C    if( pPlayerData == NULL )" ^' @& J8 P1 p) @; D8 f8 o: O
        {
    " c: x" \* T% H% v# d3 f$ S        ConsolePrintf( SLINE_LOG, TEXT("ERROR! Unable to create new PlayerData for client!") );
    8 J1 g  ?+ d2 S. I# T8 S* Q5 ?        DXTRACE_ERR( TEXT("CreatePlayerData"), E_FAIL );
    ( T" T6 B( _; D        m_AddRemoveLock.Leave();% h$ ]  M; R9 r* R% S$ j- \
            return;
    2 _, |4 s  ^5 D& Q" W# }    }</P>2 ?5 {; H; w" L4 ?
    <P>    // Store that pointer as local player data
    % `, J: ]- P" J! a  ?$ ?+ f; D) M    SetPlayerDataForID( id, pPlayerData );</P>
    $ D4 U3 c/ `# T<P>    // Grab net config into to send to client
    + d$ z7 C) B( U3 U* y    m_ClientNetConfigLock.Enter();
    2 {5 ~& ]) E/ I8 C) P! N  A! f    ServerConfigPacket packet( m_ClientNetConfig );4 p" R! N. l" }" y! k
        m_ClientNetConfigLock.Leave();</P>
    " r" t) P% A: \% G( y# Z<P>    // Send it
    ) r8 E* I( p* U    SendPacket( id, &amp;packet, sizeof(packet), TRUE, 0 );</P>
    & d+ N! Q% F" `3 N% }: |<P>    m_AddRemoveLock.Leave();
    ! b, h' d; s- _: Z}</P>
      a+ Y) h7 f8 Z$ U, H2 g% J3 z1 T1 V3 q
    <P>7 D% N/ Y; }" e
    //-----------------------------------------------------------------------------+ N0 G3 H7 `1 H$ a/ h
    // Name:
    + v  _  _/ ?- X0 N/ @  g// Desc: " M, I3 Z; o! S7 g
    //-----------------------------------------------------------------------------
    & v0 A. `) P  s2 T( l1 bvoid CMazeServer::OnRemoveConnection( DWORD id )
      d9 a. z$ p5 z  `' \{$ p$ D. U* V0 D& V5 a- }
        m_AddRemoveLock.Enter();</P>
    ) W. Z( j' w& Y1 s& {<P>    // Decrement count of players, n8 p) T# b( e. ^6 k$ ~! J
        m_dwPlayerCount--;</P>2 }* h* f( t( b# c
    <P>    if( m_dwLogLevel &gt; 0 )
    / _# L" _  k) c; [# E2 {+ \    {
    0 P, d3 S0 o0 [) F$ T" d+ {3 n        ConsolePrintf( SLINE_LOG, TEXT("Removing player DPNID %0.8x"), id );
    5 e0 y3 k+ m7 ~% q: x! D, u        ConsolePrintf( SLINE_LOG, TEXT("Players connected = %d"), m_dwPlayerCount );, W/ @3 _$ p3 |8 A- Z
        }</P>
    ' v, ?  H" Y3 o( c; Z4 u! r<P>    // Find playerdata for this client% {+ G& K, U* g: l+ v; `! I
        PlayerData* pPlayerData = GetPlayerDataForID( id );: E& H2 U7 ~; A: [/ }; r: V9 u
        if( pPlayerData != NULL )
    # u2 B' i) ?( _: e* o    {
    + m* F! F$ f8 z8 L. m# }# y        // Destroy it
    ; N$ U" `4 G9 d, L; v! I        RemovePlayerDataID( pPlayerData );# S$ x5 _, {+ Q  `0 ?
            DestroyPlayerData( pPlayerData );7 s3 M* A8 M: G7 m  t3 _
        }</P>
    / @# U/ X: C7 z6 P<P>    m_AddRemoveLock.Leave();3 z( K8 ~* C" v9 q. ?% j
    }</P>
    7 j  M- ^/ I# L' U2 M( R" F3 p% m& L  W6 ~$ ~$ W, E
    <P>
    2 J8 m8 }( F% k* V" {& J7 X//------------------------------------------------------------------------------ E4 G, M* P* k) g+ }
    // Name:
    : |$ D1 h- \7 V5 Q: ^/ k: y// Desc:
    & v+ e  B1 h$ E7 r+ h+ q6 c//-----------------------------------------------------------------------------. L, N9 y5 r' K9 c  @" D7 \8 \
    HRESULT CMazeServer::OnPacket( DWORD dwFrom, void* pData, DWORD size )
    % w. K# w# e9 _* b. J) g{7 i& W# m: v' P2 j9 ]. [
        BOOL fFoundSize = FALSE;</P>
    3 `3 y; `3 G, v" P<P>    // Increment the number of thread we have in this process.
      S2 N+ s- c: e! d0 r* A5 Z" x    m_csThreadCountLock.Enter();</P>
    " `1 y9 H  S* A$ y$ X; b<P>    //Get the start time of when we entered the message handler.
    * h3 D! E  U  P5 i4 y) p    FLOAT   fStartTime = DXUtil_Timer( TIMER_GETAPPTIME );</P>
    ( j2 E# G- F: Z  X$ n<P>    m_wActiveThreadCount++;* S; d7 n! h. M# @
        if(m_wActiveThreadCount &gt; m_wMaxThreadCount)5 G; h# ?; n) U% c8 b7 L
            m_wMaxThreadCount = m_wActiveThreadCount;) s1 h: \5 A+ P& y; g2 B  X7 O& e
        " L8 X$ A; R$ t; S4 ^
        // Calculate and average.
    + @9 A/ Z! {4 I4 `: T4 J. E3 k+ k8 P    FLOAT fdiff = m_wActiveThreadCount - m_fAvgThreadCount;% r9 X; O# H7 R
        m_fAvgThreadCount += fdiff/32;
    . W3 A. D2 Q' Q" R   
    9 i5 M1 D( B5 i8 T% t2 s    m_csThreadCountLock.Leave();</P>
    6 B* ~3 M3 }* f8 O# X( C<P>
    - C' h( \, h* E9 Y! m    ClientPacket* pClientPack = (ClientPacket*)pData;
    9 a1 i3 M$ }' D5 g" x; y5 e6 P7 l    switch( pClientPack-&gt;wType ): S0 o# R& G5 A4 J9 D3 A
        {9 V8 L3 s* v# G% z! O, w0 Z$ r1 M
            case PACKETTYPE_CLIENT_POS:# }" p- Z4 [* q
                ' l% J; k/ S5 @1 K8 r+ p
                // Check to see if the packet has a valid size. Including * G- j0 A0 Z% `# x. W
                // the custom pack size.
    * m6 y9 E. y% |1 {% s  H            if( size &lt; sizeof(ClientPosPacket))
    0 V7 V' F+ n- ^: i& r% S                fFoundSize = FALSE;# w2 O$ \. H! h" l& v) s
                else if( ! IsValidPackSize(size - sizeof(ClientPosPacket)))
    / D7 p! h  D% y9 u                fFoundSize = FALSE;$ p6 G2 G+ @$ d& a
                else2 e0 @0 D& T! s1 W+ u7 D; q* [. z
                    fFoundSize = TRUE;</P>$ ]7 j9 z+ h% W8 k/ ^( S
    <P>            // If valid sized packet, handle the position.
    9 u7 \/ H" b9 {: }! A/ W            if(fFoundSize)
    % p( v* `  i' H# J( ~                HandleClientPosPacket( dwFrom, (ClientPosPacket*)pClientPack );
    . [3 ?4 g+ v. W2 H& ^/ M% r            else7 ?' h8 p  b. ?; m% `
                    m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );</P>
    - _8 J$ l. h: S<P>            break;</P>. [6 u! Z, Z* Y$ n
    <P>        case PACKETTYPE_CLIENT_VERSION:: a2 s8 u9 Z" v, n" ~8 y* Y
                if( size == sizeof(ClientVersionPacket) )3 E' _5 I# O- B0 t, |( {/ `
                    HandleClientVersionPacket( dwFrom, (ClientVersionPacket*)pClientPack );4 z9 @: p3 @/ [% x
                else
    ) R0 K. p8 R- r7 J' l' _                m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );
    5 O, D- ]" l# U( s9 [            break;</P>  k4 r/ S2 C- g2 F  @% ~9 e
    <P>        case PACKETTYPE_SERVER_CONFIG:</P>7 k4 a8 O* }9 D5 J* ^  _5 G- |0 N3 g
    <P>            // Server config packet sent to all users (including server). Just ignore and continue.</P>
    - ~3 L( e* p' J$ u( k<P>            break;4 d. z+ D1 t" S  X) Z. }
            default:& h9 R" l8 f) ?& o/ j0 F0 g4 x
                HandleUnknownPacket( dwFrom, pClientPack, size );/ }$ E& f2 Z9 H- x
                break;2 Q- c% ]) @' t' j: M
        }</P>8 {# A2 C0 n/ o4 f3 `+ k6 e
    <P>    //If the user wants to hold the thread, Sleep for given amount of time.
    ' j3 F! _$ t8 t9 m( H    if ( m_dwServerThreadWait &gt; 0 )
    7 q5 E9 @# O6 K    {7 \0 [* _% I5 x0 Y$ r0 x
            Sleep( m_dwServerThreadWait );& a2 j- d9 \8 {
        }) Y5 |6 S  H7 q0 h0 L
          i) ^) c: |% ^3 s0 y- @) r& f
        // Retrieve thread data for this process.7 F! |4 H5 X1 C
        m_csThreadCountLock.Enter();</P>
    % t. ?& N$ m* E' ]- v! \<P>    m_wActiveThreadCount--;</P>
    / Y, \6 V$ u# Z; H6 }; m<P>    FLOAT fDiffTime = (DXUtil_Timer( TIMER_GETAPPTIME ) - fStartTime) - m_fAvgThreadTime;4 p$ X8 @7 L3 J4 |# A4 y5 U
        m_fAvgThreadTime += fDiffTime/32;</P>3 ]1 V* X7 q' B$ t
    <P>    //Get the Max time in the thread.7 q% t0 ?9 o! M* i# M; I$ o
        if ( fDiffTime &gt; m_fMaxThreadTime )# a, R5 x7 s: ?/ i
        {
    - L9 p) M# k" K+ A+ M% G$ K        m_fMaxThreadTime = fDiffTime;
    1 D6 l5 N4 \& j- e% a/ ?$ j    }</P>+ h! g3 @& ^/ f0 s' N0 |8 Z
    <P>    m_csThreadCountLock.Leave();</P>( ~: F  t4 A6 u/ X# l  y8 J
    <P>    return S_OK;
    6 \" Z- ~2 l- b# O/ g2 o; K}</P>
    " \5 q9 v! g0 ~2 k; D( d, k4 k
    / y8 U1 \; G3 o! l+ E<P>//-----------------------------------------------------------------------------" }4 A7 ?3 u1 o9 u+ }' V. S( U$ q) C
    // Name: 8 F2 _/ l: y: v1 h3 \# a) w  {% Y
    // Desc:
    ! H/ o9 [/ M3 z/ F% Y: ?//-----------------------------------------------------------------------------$ E# Q: [. u3 O$ K3 j6 u
    BOOL CMazeServer::IsValidPackSize( DWORD dwSize )7 g$ y1 Z9 E/ @, [) N* R1 c% n
    {
    / [/ @6 Q3 O7 h$ I% y7 Z/ l' {5 G    BOOL fFoundSize = FALSE;& V) x! M8 H: H. ^+ q" c
        BYTE ubPackLocation = m_ClientNetConfig.ubClientPackIndex;! S. h- Y4 ~6 h' z5 z
       
    1 W( M3 j4 G( @' E    // Check through the array of valid pack sizes.6 x( m' M3 h& x
        if(dwSize != m_ClientNetConfig.wClientPackSizeArray[ubPackLocation])
    * T9 ]) g2 A- B    {6 N) Y: Z7 F3 H
            for( --ubPackLocation; ubPackLocation != m_ClientNetConfig.ubClientPackIndex; ubPackLocation--)  G3 D4 x7 U1 G& _! P9 h
            {/ {) w, D; c5 |1 ^" j6 k+ o. s
                if(dwSize == m_ClientNetConfig.wClientPackSizeArray[ubPackLocation])$ U( R' J" w0 v8 @
                {
    ) k" ~1 ~4 b) l; Q) q2 |; e                // Found valid size in the array.
    : K. Q2 P  C  S; r# ^1 X5 f2 y5 P( S                fFoundSize = TRUE;, t# S( h; W9 y
                    break;
    & b7 B, l9 h; e            }: e) M: J! _3 q/ m5 @
                if(ubPackLocation &gt;= PACK_ARRAY_SIZE)  ubPackLocation = PACK_ARRAY_SIZE;  //Wrap the array.
    2 j3 ~0 g  z3 l2 P        }
    % T0 C5 j" u) t0 N2 y    }
    1 Y- K2 f; J/ o, e; O    else& A( \7 C+ Z( U; e* R6 ]* q, Y
        {- X3 |, u9 U  L7 u
            fFoundSize = TRUE;; y( Q8 J. w" X. \3 v! L$ {$ p4 _9 ?
        }</P>
    6 y; P' E( u% q% [<P>    return fFoundSize;2 E& S" x! ]2 f$ U, T
    }</P>1 E% a4 i. i7 \/ a. Q  F5 `
    <P>
    % E$ l  ^5 Y$ D; X+ {: P//-----------------------------------------------------------------------------9 E) X9 C4 ^7 d' q
    // Name: " o  o* Y+ x& a4 J7 \7 ]
    // Desc:
    . {( c& |6 }$ W, C7 ?1 j1 A0 x//-----------------------------------------------------------------------------
    5 B. D6 `5 \% P8 ~$ J( Rvoid CMazeServer::OnSessionLost( DWORD dwReason )1 V- S0 ]% B9 R4 M2 `/ Z  t
    {' ?) p9 H7 j5 d
        ConsolePrintf( SLINE_LOG, TEXT("ERROR! Session was lost") );, a$ W) ^8 W" A. V4 ]& e
    }</P>
    , Q: G1 A! T) r2 y6 V* l( p5 b* H4 W
    ; K, J$ ^5 X2 I# I0 @$ |<P>
      L" V9 ~  P7 A//-----------------------------------------------------------------------------
    6 e: n* P+ Z, O+ _, t// Name:   K, r9 i, p7 s5 ^1 I
    // Desc: 3 l: Q- k4 g# ^' B
    //-----------------------------------------------------------------------------
    & l/ {% J) o. d# z+ p: j1 |6 nPlayerData* CMazeServer::CreatePlayerData()
    + X! |. Z. T, U) u7 y) t) L{8 g8 \7 h6 v" I2 N
        m_PlayerDataListLock.Enter();</P>8 `* A6 C( @; m! K- a! i
    <P>    // Grab first free player in the list
    " d% W' w* M6 z* v! F    PlayerData* pPlayerData = m_pFirstFreePlayerData;</P>7 o2 s8 u1 `5 j0 I
    <P>    if( pPlayerData )- f6 ~; g  h! q9 X, Q2 ^/ g1 G
        {) E0 B- x* C3 s9 B# e
            LockPlayerData( pPlayerData );</P>
    ! b& U9 |4 a7 V' k, {& d1 L8 l) K<P>        // Got one, so remove it from the free list7 `2 n1 f- e7 o
            if( pPlayerData-&gt;pPrevious )
    * T9 y; L* ~& S            pPlayerData-&gt;pPrevious-&gt;pNext = pPlayerData-&gt;pNext;. H, \5 ~: J8 j+ b0 J& f
            if( pPlayerData-&gt;pNext )
    $ X( }' o- w2 d) O6 x            pPlayerData-&gt;pNext-&gt;pPrevious = pPlayerData-&gt;pPrevious;0 ~  J! M! ^* ?: m0 ?$ m2 b8 ?
            m_pFirstFreePlayerData = pPlayerData-&gt;pNext;</P>/ P' W6 b- n1 K: _1 }: ~% z1 D
    <P>        // Add it to the active list
      I2 a. H% n1 O  v& C( N+ D4 i1 I        if( m_pFirstActivePlayerData )9 R4 Z& ^* D7 S3 s. Y' g
                m_pFirstActivePlayerData-&gt;pPrevious = pPlayerData;+ M( o9 P) v8 {# |
            pPlayerData-&gt;pNext = m_pFirstActivePlayerData;; A* N1 k0 l3 q2 |/ ~9 S! c' c. X
            pPlayerData-&gt;pPrevious = NULL;( Y6 ]2 B1 r' ^5 j; D& u) P& k9 b
            m_pFirstActivePlayerData = pPlayerData;</P>
    1 M5 x  a# ~% n5 r! a+ b<P>        // Update count of players9 l8 ^9 x' L5 t
            m_dwActivePlayerDataCount++;</P>
    3 ^, A* y6 F& h; D<P>        // Generate the ID for this player
    * J+ A! {+ m' y. o+ j        m_dwPlayerDataUniqueValue++;% x) X- z; I1 O: l* s+ p
            pPlayerData-&gt;dwID = (DWORD) ((pPlayerData-m_PlayerDatas)|(m_dwPlayerDataUniqueValue&lt;&lt;PLAYER_OBJECT_SLOT_BITS));</P>
    + c9 z3 Y5 {6 K+ c. Y7 P3 {- @" ^( F5 e2 _<P>        pPlayerData-&gt;pNextInIDHashBucket = NULL;
    : R0 x6 N& P# O) [) Z        pPlayerData-&gt;NetID = 0;/ Q2 z4 a- j4 h& ]- G) w
            pPlayerData-&gt;dwNumNearbyPlayers = 0;</P>; ?: g6 |+ C6 |0 n+ k% @4 Y6 i
    <P>        // Insert into the "off-map" cell7 n+ q8 _+ O1 \, n% C6 ~0 Q
            pPlayerData-&gt;fPosX = pPlayerData-&gt;fPosY = -1;7 S2 a7 m. @' P. E: |1 p& u
            pPlayerData-&gt;wCellX = pPlayerData-&gt;wCellY = 0xffff;" R3 s/ p0 u1 C# T) ?: D
            m_OffMapLock.Enter();
    1 c6 G" z" g' ]/ @2 q        pPlayerData-&gt;pNextInCell = m_OffMapCell.pFirstPlayerData;. {: L" J" K+ x- ~+ a9 x- t
            m_OffMapCell.pFirstPlayerData = pPlayerData;- L2 z( x" G  F5 j2 }+ |+ s
            m_OffMapLock.Leave();</P>
    % ^+ @6 W+ s4 t0 t<P>        // Mark as active9 Y% K. w' z( U3 F" m. F
            pPlayerData-&gt;bActive = TRUE;</P>  ?/ l8 b% X( v2 y4 h, \2 z9 R$ |
    <P>        UnlockPlayerData( pPlayerData );( {" o' F4 J. \( L5 z
        }</P>" e& Q+ j3 z' I# p# ^$ W
    <P>    m_PlayerDataListLock.Leave();</P>
    2 ]% z2 |0 j! b$ i. n+ Y<P>    return pPlayerData;6 P- j+ m& U1 C: l  ]1 @- t, D7 W, h6 a: P
    }</P>
    , {* b, b. w/ T4 T$ L5 P9 {
    0 k& k4 D7 Z! P* b# D) E<P># p3 m& Z4 _7 X7 W- ?
    //-----------------------------------------------------------------------------# @0 [  R$ K! g9 P" Q" Z
    // Name:
    $ ]) Q; k$ _; f// Desc:
    & b. D9 b0 W/ v6 Q. G) h//-----------------------------------------------------------------------------' y% |1 B1 Y5 m0 c
    void CMazeServer:estroyPlayerData( PlayerData* pPlayerData )
    $ A3 [- G8 @2 m9 `' q3 S{
    3 I2 y2 K) h0 J2 S( h. V1 z; T. r    m_PlayerDataListLock.Enter();
    : g5 `$ A  D5 n4 B+ z6 b3 S    LockPlayerData( pPlayerData );</P>
    ' C; @+ ^! {$ s$ J- c8 g<P>    // Remove the player from its cell
    $ u: D3 n  R  f" l    RemovePlayerDataFromCell( pPlayerData );</P>0 B# y( e5 x6 T+ U
    <P>    // Mark as inactive# `8 q! G; a: `. N
        pPlayerData-&gt;bActive = FALSE;</P>2 [3 {! x0 L$ _% T$ l# E
    <P>    // Remove player from active list
    7 d( v/ p. E! _# \0 t8 d    if( pPlayerData-&gt;pPrevious )  Y! p! W1 f7 m' ]
            pPlayerData-&gt;pPrevious-&gt;pNext = pPlayerData-&gt;pNext;
    6 C, R8 d% \0 P- G/ m9 j9 B    if( pPlayerData-&gt;pNext )
    1 _6 [5 _6 r$ M3 W        pPlayerData-&gt;pNext-&gt;pPrevious = pPlayerData-&gt;pPrevious;</P>- Q$ @9 Z$ y6 T# m0 U- o
    <P>    if( m_pFirstActivePlayerData == pPlayerData )
    0 p. y8 E5 ]) [' z+ Y( }; n/ A/ Q        m_pFirstActivePlayerData = pPlayerData-&gt;pNext;</P>+ S- o0 i: {2 R3 I1 }' P7 v
    <P>    // Add it to the free list
    9 ^/ Q% u7 O( k% y$ w3 w; I    if( m_pFirstFreePlayerData )& x- M1 Z! o2 h: k1 u1 ^
            m_pFirstFreePlayerData-&gt;pPrevious = pPlayerData;
    4 \  P/ o& q2 q    pPlayerData-&gt;pNext = m_pFirstFreePlayerData;, i1 p. U4 M1 B, |
        pPlayerData-&gt;pPrevious = NULL;- G5 o, X: |7 b# f6 V
        m_pFirstFreePlayerData = pPlayerData;</P>$ g$ @" {  W7 `/ X
    <P>    // Update count of players
    8 c# R  v! E/ f$ D    m_dwActivePlayerDataCount--;</P>
    : J0 n* y* W4 r  P/ j<P>    UnlockPlayerData( pPlayerData );
    3 R$ I9 ~2 V8 o1 B    m_PlayerDataListLock.Leave();. u" ^7 u0 x1 W
    }</P>
    & Y$ ^. @' L% i0 V3 W' P! {) g! x! d4 b
    <P>
    0 V7 a8 Y3 a2 s; p//-----------------------------------------------------------------------------
    * f( E3 n( _0 u0 O9 P) \" |// Name:
    ( Y# a' E9 W/ ?0 O// Desc:
    2 ^5 e5 h# X, a3 q//-----------------------------------------------------------------------------. _" o$ e( v5 y% y! Q8 k
    void CMazeServer::RemovePlayerDataFromCell( PlayerData* pPlayerData )( Q) Y1 f% w7 F0 |2 d+ T" f3 ^7 o
    {$ t# [, y0 |/ D7 D5 I9 y2 _* W/ B2 [
        // Lock the player
    . k- y. l% d( j6 x6 T+ m+ Z    LockPlayerData( pPlayerData );</P>6 W4 `: w# Y% Z* o0 r" Q& R
    <P>    // Lock the cell the player is in" P1 y* x, R; A. \
        ServerCell* pCell;
    * b4 ~- V0 ]6 m    if( pPlayerData-&gt;wCellX == 0xffff )' D# m5 o" o* h* W! l3 i
        {
      X6 ~" v, n5 o6 l% J% z( G5 o        m_OffMapLock.Enter();- h' Z1 \) P* ^6 n( V
            pCell = &amp;m_OffMapCell;
    6 m+ ^5 s' V+ J$ @    }
    6 N. B+ T" j2 s& x1 t    else  |+ |0 r5 J1 h/ ?: h
        {: x& N5 G/ z. s! \$ ?2 j/ T
            LockCell( pPlayerData-&gt;wCellX, pPlayerData-&gt;wCellY );  k4 p) H  x! d* D' z4 O: ^
            pCell = &amp;m_Cells[pPlayerData-&gt;wCellY][pPlayerData-&gt;wCellX];
    - n; r/ r/ p4 C7 |3 L    }</P>) t  p" j0 ?3 o, @+ \
    <P>    // Remove it from the cell' E6 H' ?, L& K0 C( H' i
        PlayerData* pPt = pCell-&gt;pFirstPlayerData;
    : b$ q. l" _# c. o: }    PlayerData* pPrev = NULL;
    $ H: ^. [( D3 i% F+ Z& |- k0 s    while ( pPt )) q& v- k- Y0 X/ V/ @3 m' N
        {
    2 j0 A$ I- _- H2 y- b  L        if( pPt == pPlayerData ). P7 g2 W* b# L+ a
            {
    ' B) i$ T2 H7 w* ~            if( pPrev )4 j# K+ p( O. o3 S% V; ~
                    pPrev-&gt;pNextInCell = pPlayerData-&gt;pNextInCell;; D% ?3 W  T4 N& M* T( [
                else% U) C$ @: ~: z+ P2 r/ f3 d; l
                    pCell-&gt;pFirstPlayerData = pPlayerData-&gt;pNextInCell;</P>
    " \6 u) R9 @* j  L7 c; L<P>            pPlayerData-&gt;pNextInCell = NULL;7 M2 A6 `" b! I% q  w
                break;- E) l4 a4 F0 w4 \, p8 J
            }  m5 |' t! b& j6 T* |
            pPrev = pPt;" r% g) ]7 q. O- H6 }
            pPt = pPt-&gt;pNextInCell;3 V  s8 ]' t% l, y" v" I
        }</P>0 C7 _  b$ h+ I. g' \; M: _" f
    <P>    // Unlock the cell
    ; G" Y8 \' V3 O6 ]# q7 x+ O    if( pPlayerData-&gt;wCellX == 0xffff )( L. b$ n" P7 q7 e4 n- m+ E
            m_OffMapLock.Leave();
    " J' H1 L' u, l6 Y1 E' F    else* U% W8 h: I+ |5 p9 o) D
            UnlockCell( pPlayerData-&gt;wCellX, pPlayerData-&gt;wCellY );</P>8 f/ N/ n% c4 p& q5 ^! f) \. n1 B
    <P>    // Unlock the player
    1 A4 l! d+ }! h6 w% e" G: d    UnlockPlayerData( pPlayerData );
    . c+ b( Z5 B% D" C! E) W/ a}</P>. j- U' Y0 g5 R3 D

    9 U6 r& e) |$ _2 R, T<P>& {$ Z6 d: {1 |; M! W6 @5 O
    //-----------------------------------------------------------------------------
    4 k1 L7 U/ q' f! [7 M% r! W// Name:
    " O; Q+ V+ ^/ N6 M4 y// Desc: 6 q8 ]$ r1 q& C; q: y
    //-----------------------------------------------------------------------------
    / a5 D+ P8 x0 |/ \; _" u' L' Xvoid CMazeServer::UnsafeRemovePlayerDataFromCell( PlayerData* pPlayerData )
    # s, t9 e3 y1 |' ]{9 i) i# _1 P% N
        ServerCell* pCell = GetCell( pPlayerData );
    $ @. y4 }1 y% m/ t: c) T, t% f    PlayerData* pPt  = pCell-&gt;pFirstPlayerData;
    / n9 M7 H8 e8 d( y$ B; g    PlayerData* pPrev = NULL;
    ; {- {3 ], D% u$ ^7 d+ U; c    while ( pPt )
    " ?: ^8 O5 |( o0 M    {
    9 o+ f( ~% R0 I/ e        if( pPt == pPlayerData )
    6 D: Q) ^8 t1 }        {
    9 K# ?3 h6 H1 Z* D            if( pPrev )
    $ q( ?% u& @# n: A7 v. j                pPrev-&gt;pNextInCell = pPlayerData-&gt;pNextInCell;
    5 m  ~) h  _9 B8 Q# }            else; j. A3 W6 ]. v$ A1 J- W" b) B
                    pCell-&gt;pFirstPlayerData = pPlayerData-&gt;pNextInCell;; H, d9 g5 b# _" f
                pPlayerData-&gt;pNextInCell = NULL;
    + e: b$ M+ ~3 L3 G$ w  L            break;6 C4 y" j4 W# c  `' J- b' J  t' e
            }# J+ g. E8 s3 n, b# x  g
            pPrev = pPt;
    2 \+ q  Z! G% ]7 S        pPt = pPt-&gt;pNextInCell;: `8 R3 i3 L' ^7 L! v) }
        }
    / }  j' Y2 f  o) a% M}</P>
    9 o% k; `; [/ t9 r- h9 v) }3 }) ^. \3 W9 L# R* y) @
    <P>+ [+ j9 C6 G3 q/ |, A
    //-----------------------------------------------------------------------------) P/ A) [9 \  L8 p
    // Name:
    ( N2 Y6 V! l  B$ T! s// Desc: / @  y, E9 C0 A: Y
    //-----------------------------------------------------------------------------
    ) [6 b% g+ Q  @2 d9 \void CMazeServer::UnsafeAddPlayerDataToCell( PlayerData* pPlayerData )
    . l1 ^: g: E2 n4 R. G# o{8 h" x. \5 u$ }8 I
        ServerCell* pCell   = GetCell( pPlayerData );) I+ ~5 q" a6 w" {
        pPlayerData-&gt;pNextInCell = pCell-&gt;pFirstPlayerData;8 Y$ f2 x2 p* @+ N
        pCell-&gt;pFirstPlayerData = pPlayerData;
    # P- ^  |* B- h6 I}</P>
    ( Q+ [5 V) c+ A( ]* J
    % f( k) d+ O1 B  G<P>
    , A$ X: ]$ l6 M4 Q//-----------------------------------------------------------------------------
    / h' M+ [$ B' b/ S  e9 d. P7 ~// Name:
    # l7 n: m; V' L: G// Desc: 6 q, ?& w& r9 p7 |% |
    //-----------------------------------------------------------------------------7 D' R! |' c7 A3 L& o9 V
    void CMazeServer::HandleClientPosPacket( DWORD dwFrom, ClientPosPacket* pClientPosPack )2 Q8 D8 D1 g! N0 g5 k9 E) ?. O# v
    {
    ; ~6 u3 {4 |9 B- ?    // Grab player for this client and lock it
    3 j! J0 X0 D2 w1 G& f    PlayerData* pFromPlayer = GetPlayerDataForID( dwFrom );3 Y2 }% h- }7 H; E$ z2 v& }7 I
        if( pFromPlayer == NULL )
    + a3 y8 K- n: p, c# N1 W7 c1 ~    {
    1 t3 \6 \0 s: U. n        if( m_dwLogLevel &gt; 1 )
    7 T3 \2 l# F' L' r' K( M- z$ a            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Could not find data structure for this player"), pFromPlayer-&gt;NetID );
    # M& z( J- K5 k        return;
    & T. ?7 m9 N; f* [0 ]    }</P>9 `3 _; U5 n8 Q' B
    <P>    LockPlayerData( pFromPlayer );</P>
    $ X, H) w% a2 K+ V8 i, V<P>    if( FALSE == pFromPlayer-&gt;bAllow )9 M, d$ v8 _" a6 e
        {
    5 w4 K2 Z- `5 D/ |) E  ~  g% t        if( m_dwLogLevel &gt; 0 )) l+ \+ |; T0 t- `- `; g) Z; t( @
                ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Got position packet from bad client.  Rejecting client"), pFromPlayer-&gt;NetID );</P>
    9 h$ e* B2 _7 C' Z6 o<P>        m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );
    0 r+ ^/ w, A5 g# Q6 W4 K6 _        UnlockPlayerData( pFromPlayer );
    1 }/ l' h' P/ L" z% U4 f        return;
    9 b7 G, f' h% i3 S9 t' Z    }</P>1 ^' g8 ?  F; K! I
    <P>    // Compute the cell the player should be in now. i2 L: @: |. h) z0 G
        DWORD newcellx = int(pClientPosPack-&gt;fX);7 Z# T$ L( E7 e, a' b. e
        DWORD newcelly = int(pClientPosPack-&gt;fY);4 O; e) x$ }' {# ~$ V# n; u
        DWORD oldcellx = pFromPlayer-&gt;wCellX;6 ?, Y: R2 r! ~9 [' i! ]
        DWORD oldcelly = pFromPlayer-&gt;wCellY;</P>5 m, |5 S3 c0 @/ g
    <P>    // Have we moved cell?% Z3 e9 O7 N4 K8 R' M
        if( newcellx != oldcellx || newcelly != oldcelly )( n" E2 V0 U2 D2 c) X; Q
        {2 G& ^  |" F% Y" x) K7 q. U/ N' `
            // Yes, so lock the pair of cells in question
    * ~5 U& K% C4 l7 _: T        LockCellPair( oldcellx, oldcelly, newcellx, newcelly );</P>+ ~( ^5 C; s- \4 [, }
    <P>        // Remove from old cell and add to new cell+ b- H' c% @3 M: J
            UnsafeRemovePlayerDataFromCell( pFromPlayer );/ `! [+ }0 ^5 c4 o+ |
            pFromPlayer-&gt;wCellX = WORD(newcellx); pFromPlayer-&gt;wCellY = WORD(newcelly);
    % J: S2 @$ O' o) E3 V        UnsafeAddPlayerDataToCell( pFromPlayer );</P>
    $ h( Q. D+ Y" @% Q# U<P>        // Unlock cells! F+ t( t$ R1 }) z; J# `
            UnlockCellPair( oldcellx, oldcelly, newcellx, newcelly );) y' z7 o5 z) \  i0 y
        }</P>
    ; P: D0 p/ d, |; C3 C8 n4 D4 a<P>    // Update player position
    % o& e  Y6 d4 G; k9 E- D+ ^7 o    pFromPlayer-&gt;fPosX      = pClientPosPack-&gt;fX;
    * U8 d$ {; @4 ]9 J" _    pFromPlayer-&gt;fPosY      = pClientPosPack-&gt;fY;
    7 p* p: I9 S- ~! b% R    pFromPlayer-&gt;aCameraYaw = pClientPosPack-&gt;aCameraYaw;</P>
    , `: h- V& r- o<P>    // Allocate space to build the reply packet, and fill in header - ?/ B( ?/ ^- r
        DWORD dwAllocSize;, J* X1 d  b5 b# w
        ServerAckPacket* pSvrAckPack = NULL;</P># j- B! }' ^, q
    <P>    // Begin by allocating a buffer sized according to8 z- [5 ^" B, r$ ]$ U3 \
        // the current number of nearby players + 4.  This will give
    * d6 T+ T* x6 G    // a little room for more players to come 'near' without resize
    8 Z& Y( [2 E; g    // the buffer.: R7 S: D$ J6 w
        DWORD dwMaxPlayerStatePackets = pFromPlayer-&gt;dwNumNearbyPlayers + 4;</P>
    - N: r" x( m+ f: p2 D& b7 K<P>    dwAllocSize = sizeof(ServerAckPacket) + dwMaxPlayerStatePackets*sizeof(PlayerStatePacket);& y3 w  f# g, F! G
        pSvrAckPack = (ServerAckPacket*) realloc( pSvrAckPack, dwAllocSize );) J% t; ]$ J) D+ B* N- u
        if( NULL == pSvrAckPack )3 H4 R% u4 I$ r# l! m; M& X
        {* n3 `) F: e/ {0 I
            // Out of mem.  Cleanup and return
      [' ^3 o$ G. x$ p        UnlockPlayerData( pFromPlayer );! i. C  \) `+ U
            return;       8 m; O8 L: U! N4 g2 R
        }8 r) X# o' s4 ^7 N& J2 Y
        ZeroMemory( pSvrAckPack, dwAllocSize );</P>, }( l2 k2 z/ q8 P; w8 u
    <P>    *pSvrAckPack = ServerAckPacket(m_dwPlayerCount);
    # O9 _* f3 O) C9 c    pSvrAckPack-&gt;wPlayerStatePacketCount = 0;3 ^* K1 t, P0 C! ]
        PlayerStatePacket* pChunk = (PlayerStatePacket*)(pSvrAckPack+1);</P>5 n: o  b( T( l2 C9 r
    <P>    // Compute range of cells we're going to scan for players to send. V* Z9 ^. p( X4 E  Z
        DWORD minx = (newcellx &gt; 7) ? (newcellx - 7) : 0;
    ; n6 i3 V1 j6 U. v( m$ U  F' z    DWORD miny = (newcelly &gt; 7) ? (newcelly - 7) : 0;
    ! R8 N% h$ `" w: h3 R3 _4 F  K* Z    DWORD maxx = (newcellx+7 &gt;= m_dwWidth) ? m_dwWidth-1 : newcellx+7;
      N4 A  ?. q: u9 _7 T# }+ O( K    DWORD maxy = (newcelly+7 &gt;= m_dwHeight) ? m_dwHeight-1 : newcelly+7;</P>
    ( s$ |, ]* e6 }) U7 k) |# L<P>    // Lock that range of cells0 N5 c/ }  w) C  {, W# v9 Z
        LockRange( minx, miny, maxx, maxy );</P>; g0 y0 o* o8 F7 O1 d
    <P>    // Scan through the cells, tagging player data onto the end of
    ( ?, W5 l5 ~: X' C* K    // our pSvrAckPacket until we run out of room7 {0 l) N* V( K8 x2 e
        for( DWORD y = miny; y &lt;= maxy; y++ )
    ! a) `3 q8 q# ~4 F6 b( Y    {
    . X& s6 V2 K, H        for( DWORD x = minx; x &lt;= maxx; x++ )1 K" N6 K( h5 E- [1 n
            {
    , O( u* x1 D" M            PlayerData* pCurPlayerData = m_Cells[y][x].pFirstPlayerData;
    " G$ j5 T1 s& Y5 C* W2 h, E            while ( pCurPlayerData )
    : f* X3 ~  j! o! k            {5 [" w0 t; C$ E3 T! V8 h
                    if( pCurPlayerData != pFromPlayer )% d+ p% g2 w; ]% a
                    {
    6 E. I/ |3 \" ?( ?. t* v- {                    if( pSvrAckPack-&gt;wPlayerStatePacketCount &gt;= dwMaxPlayerStatePackets )
    - z8 A* a& B, X# O% B                    {5 c5 l$ x, U) m' h
                            // Make sure pChunk is where we think it is9 z) B" o8 R, w  y$ o" u
                            assert( (BYTE*) pChunk == (BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket)) );</P>3 J& g% v3 W7 e, I" R! r, v- w4 f
    <P>                        // There are more than just 4 new nearby players, so resize the
    ' j" T/ z, q' l7 ^% F' Q                        // buffer pSvrAckPack to allow 16 more PlayerStatePacket's.4 h4 X$ {/ c, c
                            dwMaxPlayerStatePackets += 16;
    ' W1 b& ]8 c) _8 F; X5 j3 |6 e                        dwAllocSize = sizeof(ServerAckPacket) + dwMaxPlayerStatePackets*sizeof(PlayerStatePacket);. H& [; _4 {7 M( O7 M# z
                            ServerAckPacket* pNewSvrAckPack = NULL;" C  w; h( u1 c6 I
                            pNewSvrAckPack = (ServerAckPacket*) realloc( pSvrAckPack, dwAllocSize );
    8 w9 M1 k1 g8 V+ ?# z                        if( NULL == pNewSvrAckPack )
    2 _. e1 b6 a3 E$ Q8 E; R4 S; Z                        {2 I* n5 a/ R5 R0 Q' m7 K7 r, b
                                // Out of mem.  Cleanup and return
    ( n0 w4 M9 ?. a' L' Y/ ~                            free( pSvrAckPack );, d8 Y( ]! H9 E* H1 _
                                UnlockRange( minx, miny, maxx, maxy );
    4 B0 D' i# t2 t3 d                            UnlockPlayerData( pFromPlayer );1 F6 h4 f7 k& U0 X+ }  r, {! r
                                return;       % d( s- R9 |$ R0 o6 Y- d
                            }</P># m9 j( J4 z3 k2 U/ [$ O
    <P>                        pSvrAckPack = pNewSvrAckPack;- Z/ L* _( a& |# t! E1 `; w% B
                            pChunk = (PlayerStatePacket*) ((BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket) ) );</P>
    , C8 M5 b6 m) c( ]8 S<P>                        // Make sure pChunk is still where its supposed to be% M, U% m% @- r
                            assert( (BYTE*) pChunk == (BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket)) );
    & D/ a/ V. j( h% Q                    }</P>+ T$ Z; {9 C6 X
    <P>                    pChunk-&gt;dwID       = pCurPlayerData-&gt;dwID;
    $ J$ d0 \% X1 c% I$ k                    pChunk-&gt;fX         = pCurPlayerData-&gt;fPosX;4 M4 g1 ^& N( G# ?
                        pChunk-&gt;fY         = pCurPlayerData-&gt;fPosY;, N0 G; R3 u# u3 b5 I
                        pChunk-&gt;aCameraYaw = pCurPlayerData-&gt;aCameraYaw;
    % [" Z! `, j5 `+ V) l5 {                    pChunk++;3 o. a% b0 ~. Q+ B3 F* y% P
                        pSvrAckPack-&gt;wPlayerStatePacketCount++;1 |& ], q/ d' [, V
                    }
    % q- Y$ q* P9 e) u) l                pCurPlayerData = pCurPlayerData-&gt;pNextInCell;
    ! U, ?+ l  P# b2 Q# c            }/ h! e5 ~" J9 T8 c' N( t
            }
    - C* P6 f2 _, o3 D' M    }</P>
    6 O$ X. B" K% A! P3 `* I<P>    // Update the dwNumNearbyPlayers for this player
    / h' S& K* x9 j7 c0 o    pFromPlayer-&gt;dwNumNearbyPlayers = pSvrAckPack-&gt;wPlayerStatePacketCount;</P>
      W  R1 e5 @* u5 c) q' H5 e) H# C! y0 C% \<P>    // Unlock range of cells
    4 s. H- r+ M9 n    UnlockRange( minx, miny, maxx, maxy );</P>
    : ^5 F" c. L+ r% h4 }5 I<P>    if( m_dwLogLevel &gt; 2 )
    ( C" C' X' s* q' B; U    {
    ( N' V9 ?. A, j& z7 v: b6 {        ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Position is (%0.2f,%0.2f)"), pFromPlayer-&gt;NetID, pFromPlayer-&gt;fPosX, pFromPlayer-&gt;fPosY );
    " o+ J) I5 N9 k6 c8 c! Z    }" T2 _9 s  p& K6 U0 k$ N
        else if( m_dwLogLevel == 2 )9 p) a$ M& l; M' S5 v3 S& _5 c: v* n
        {
    4 w! l: ^' R% {! b; P& @        FLOAT fTime = DXUtil_Timer( TIMER_GETAPPTIME );- p( K" n5 E' j$ ^( X( u6 z
            if( fTime - pFromPlayer-&gt;fLastDisplayTime &gt; 60.0f )! Z$ B& b5 t. f  v
            {7 L- n0 W' a$ U+ t; Z4 c' ]8 D
                ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Position is (%0.2f,%0.2f)"), pFromPlayer-&gt;NetID, pFromPlayer-&gt;fPosX, pFromPlayer-&gt;fPosY );6 b! N# `" ~; F+ I) {
                pFromPlayer-&gt;fLastDisplayTime = fTime;
    5 w7 n' F$ E" Z        }
    2 c# T, U8 W7 w2 {    }</P>
    ! I$ f' x% @2 z% t& q2 _% Z# ^$ h<P>    // Unlock the playerdata' F# w8 Q# u& ~' B8 V
        UnlockPlayerData( pFromPlayer );</P>3 ~0 U2 y1 e% ~0 r: q4 C3 B
    <P>    // Send acknowledgement back to client, including list of nearby players 1 g$ S5 `3 A; F% ~7 Q: [9 U
        DWORD acksize = sizeof(ServerAckPacket) + (pSvrAckPack-&gt;wPlayerStatePacketCount * sizeof(PlayerStatePacket));" n; `$ ^2 P: J0 c

    9 B* F% s5 O$ ?7 R4 C1 L* j    // Pack the buffer with dummy data.% k: N4 s- A# x5 O* |8 h& J
        if(m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex] &gt; 0)6 `3 e; f6 {) n6 {6 r7 a
        {
    - P1 Y# a8 W# Q9 W& V/ x7 x        DWORD   dwBufferSize = acksize + m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex];
    5 n8 w; J' M# r. y5 I- m9 m$ K! O        VOID*   pTempBuffer = 0;</P>7 u9 B. u* q" c
    <P>        pTempBuffer = malloc(dwBufferSize);
    / c5 R! Q! \* r* l1 [4 j# v" `        if( NULL == pTempBuffer )
    ! M- O& Q0 V! a        {0 t$ s, e- U# |, ]+ C
                //Out of memory* e* i: ~4 r3 V! x; q, x/ d8 I
                DXTRACE_ERR_NOMSGBOX( TEXT("System out of Memory!"), E_OUTOFMEMORY );
    ; U4 U) o6 a" s& \5 J            free( pSvrAckPack );
    ( J% _9 A3 V# P) W4 d) J( j+ F$ |            return;5 i0 i0 P0 F: I. Q( I; Q$ o% ~
            }</P>+ y) C: v7 z( A& q* U5 U" s) U/ u
    <P>        FillMemory(pTempBuffer, dwBufferSize, 'Z');
    & Z2 |3 M: n+ u( u- t) p        memcpy(pTempBuffer, pSvrAckPack, acksize);</P>- s) F. p1 O  t2 f# p+ T
    <P>        SendPacket( dwFrom, pTempBuffer, dwBufferSize, FALSE, m_dwServerTimeout );+ O0 c) G4 L$ H1 M' Y4 n2 h" S
       
    5 S3 K* ~. s$ D3 X, A" [5 B        free(pTempBuffer);, ~0 j% U4 f7 p% _" u1 Q. A
        }   
    , O9 a0 B$ O7 E0 Y    else/ B+ v# `! i" n3 m, _) J) [, n
        {0 \0 l7 o. e$ k2 z- k7 e# W% I
            SendPacket( dwFrom, pSvrAckPack, acksize, FALSE, m_dwServerTimeout );/ ^) ]: T8 E; M7 a! O
        }</P>
    ( W. ?: I& P+ X* a! m& Q  a, P<P>    free( pSvrAckPack );</P>4 u# x4 v9 x  N5 q( r
    <P>}</P>0 _9 K  o- e. b
    , e  ~. b+ U5 e4 r
    <P>
    ; Q! X5 ^3 s/ y$ ]/ P  d//-----------------------------------------------------------------------------
    # R: B' i2 F7 `// Name: 6 J+ i+ W+ \+ k
    // Desc: " {* w1 u7 S0 y9 r; y3 a
    //-----------------------------------------------------------------------------/ \. p& J6 K) o% r' ^$ E7 ^
    void CMazeServer::HandleClientVersionPacket( DWORD dwFrom, ClientVersionPacket* pClientVersionPack )
    " r6 [+ l" h# m. ^{6 ]' P- \( K; [4 [
        // Grab playerdata for this client and lock it" H3 x; Z6 Z5 e' F, O+ J: A0 W* c
        PlayerData* pPlayerData = GetPlayerDataForID( dwFrom );! E+ x. X2 k* I7 v
        if( pPlayerData == NULL )
    6 o% o; }2 U: m7 U( `        return;
    . I1 E' h* ?$ L3 f2 X, W) W" \+ p    LockPlayerData( pPlayerData );</P>
    ) q% T9 x' O3 K$ P6 ~: k% y  S+ ]3 x<P>    // Record the version number   ~3 F! G! m1 C0 T2 A
        pPlayerData-&gt;dwVersion = pClientVersionPack-&gt;dwVersion;</P>
    2 Y# y; Y& T* V) g- C! h" V<P>    if( m_bLocalLoopback )
    / i: M# x8 O9 \% F7 J! j        pPlayerData-&gt;bAllow = TRUE;
    % s. W) n6 g9 c- I9 I- T- Z' o% Z    else: P1 c+ A1 K0 N' M0 ?
            pPlayerData-&gt;bAllow = IsClientVersionSupported( pClientVersionPack-&gt;dwVersion );</P>7 @. D6 Q8 m: k6 x' ^& s% x4 A
    <P>    if( m_dwLogLevel &gt; 0 )$ r9 ?6 `3 ?8 F' X
            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Client version=%d (%s)"), pPlayerData-&gt;NetID, pPlayerData-&gt;dwVersion, pPlayerData-&gt;bAllow ? TEXT("Accepted") : TEXT("Rejected") );</P>
    7 U$ N+ m  p7 z) `' D<P>    if( FALSE == pPlayerData-&gt;bAllow )
    - W, C2 b# O* [    {# c' J3 z/ i, @( V' M
            if( m_dwLogLevel &gt; 0 )
    8 d9 |$ k: |5 i7 T, Z+ r  q0 B            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Rejecting client"), pPlayerData-&gt;NetID );</P>/ B0 F" m8 b; |% ~4 i$ S# a
    <P>        m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );: t. z5 t  G0 U0 {5 B
            UnlockPlayerData( pPlayerData );
    " Z/ e$ r* S) k! r, C        return;
    # R+ b( w: M- z  ?    }</P>
    ) d, s2 q1 ?, G0 U$ P3 E4 }<P>    // Unlock the playerdata
    " V! H% y: I+ m( M    UnlockPlayerData( pPlayerData );</P>
    5 E+ ~& ^* k) `  }<P>    // Send acknowledgement to client that the client was either accepted or rejected4 \) ?8 [! D( c) [
        ServerAckVersionPacket packet( pPlayerData-&gt;bAllow, dwFrom );; v; |. U+ p$ `9 V
        SendPacket( dwFrom, &amp;packet, sizeof(packet), TRUE, 0 );
    ; ?  J. h+ N: _9 o$ t}</P>; ?' `3 z: i: b( [" C8 K: a  B

    * J% E! j. I8 o* X  Q; s- }' L' m, u) p<P>( U1 b9 D. ?# r4 C7 b' X8 {
    //-----------------------------------------------------------------------------" f. W, Q( }  v4 Z
    // Name:
    , P' V1 I, N% t( z5 [' M7 e// Desc:
    7 \' f5 k9 @% j//-----------------------------------------------------------------------------
    $ Y1 D% j4 J7 u% HBOOL CMazeServer::IsClientVersionSupported( DWORD dwClientVersion )' b* u9 m; {5 j; ^( B) T
    {
    2 f& a: H; p+ |! x  M- c    switch( dwClientVersion )
    1 k; w1 s! B$ u6 A3 o! S6 G    {  ^- G& m+ X" H9 _
            case 107: // only v107 is supported7 Y0 r3 H/ t# X& r/ [
                return TRUE;
    ) d7 [6 ~) _& U7 H& |% `- E# O        default:
    8 p+ h4 O7 y4 a9 z1 q* j6 w            return FALSE;
    7 k. a. l- j. ~9 s    }9 S; X3 N; B  E! R8 ?1 y& x
    }</P>. t& y. m7 d5 o/ H! {: G5 `
    ' e' h" i$ \' Z; F
    <P>
    ' d+ `+ q' O& ]& h. v: m% ?//-----------------------------------------------------------------------------6 d6 W9 Z& i& c5 ^, ^
    // Name: ' ?0 W* F; z2 c1 m: ^0 Z8 K/ Q
    // Desc: , J4 v0 l6 |! J" V1 z
    //-----------------------------------------------------------------------------( B1 f3 j7 D: j  x6 K
    void CMazeServer::HandleUnknownPacket( DWORD dwFrom, ClientPacket* pClientPack, DWORD size )9 w. @4 z2 J% B! q! @; G6 m; I, J& U
    {2 @: q7 F9 ]0 h7 j7 M
        if( m_dwLogLevel &gt; 1 )
    $ V5 x2 K# y- ^4 |0 G. J' `        ConsolePrintf( SLINE_LOG, TEXT("ERROR! Unknown %d byte packet from player %0.8x"), size, dwFrom );</P>' Q4 ~+ O% b4 d# X/ @4 @
    <P>    m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );4 D9 t" a1 p8 i: }  J
    }</P>* _6 ~2 h1 n, r' [+ b, S0 q: D

    6 m3 y$ B5 _% _1 e. g) [& M<P>  r2 l+ R- Y3 s
    //-----------------------------------------------------------------------------1 t. q2 z8 d0 A
    // Name:   H$ B2 Y! s2 l- b/ i0 ]' y
    // Desc: + M3 k1 O' h# P4 `- K* a6 c6 G
    //-----------------------------------------------------------------------------0 a3 j$ o+ m- f3 `
    DWORD   CMazeServer::IDHash( DWORD id )
    / q0 s/ V0 h( D: G. W{/ y+ O. M2 p' t+ d0 d6 [' p( M5 {3 e
        DWORD   hash = ((id) + (id&gt;&gt;8) + (id&gt;&gt;16) + (id&gt;&gt;24)) &amp; (NUM_ID_HASH_BUCKETS-1);
    ; |3 Q3 Z5 e  ?( U* k    return hash;
    ' |9 F6 n/ k# V}</P>
    / y+ ?& ~, f/ l$ D5 w$ t# |3 B  ], i
    <P>
    , R1 E! D0 f3 k- y+ Z2 x+ \$ }5 }//-----------------------------------------------------------------------------2 W' P9 m$ `$ ]% U3 ^$ L/ H
    // Name:
    ) f6 M. b. D$ s// Desc: ; @% a) a; {: M1 j- `
    //-----------------------------------------------------------------------------
    % K0 b7 M4 \- _void CMazeServer::RemovePlayerDataID( PlayerData* pPlayerData )
    " s  m+ L/ h5 j+ [: }- j) o# z4 L{3 {1 W6 t& t8 }! Z* d
        // Hash the ID to a bucket number
    ( X* b+ q* `% v3 n, H% q: s; ^+ G    DWORD   bucket = IDHash( pPlayerData-&gt;NetID );</P>
    1 B1 h, R# J* E+ \3 v<P>    // Lock that hash bucket/ a6 X% }, ]' C! R( k# U
        const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;3 Y2 w" |* B3 g/ T  V+ C" ~& ]
        m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>
    ) U% S2 L7 R$ h<P>    // Loop though players in bucket until we find the right one. a% p. }" t) R" t5 l
        PlayerData* pPt = m_pstIDHashBucket[bucket];
    ' e, @3 }* F1 o& Y8 G' K' J  l    PlayerData* pPrev = NULL;% Q' V2 e$ Q" p- X& U
        while( pPt )
    ) R3 N' M& y- s* V' U4 K    {
    9 m% R$ \1 {0 M, r2 `        if( pPt == pPlayerData )& e8 r: ?/ {5 `6 {( ~
                break;* R2 l' p" P; b( V- D; b
            pPrev = pPt;' q0 q7 Z  {8 Y: V& u. T
            pPt = pPt-&gt;pNextInIDHashBucket;
    2 X7 \: A7 U( f) m) A1 J$ K    }</P>- `9 Q1 f3 s8 @, D
    <P>    if( pPt ), E: S; b/ p1 m# Y
        {
    + ?$ k# u5 |& s& ?        if( pPrev )# L8 ?* ^9 G! l" Q6 [
                pPrev-&gt;pNextInIDHashBucket = pPt-&gt;pNextInIDHashBucket;/ O; W- f9 f  o1 q
            else
    ( t$ Q  M9 A, t9 I4 w+ E            m_pstIDHashBucket[bucket] = pPt-&gt;pNextInIDHashBucket;
    0 t2 Z2 C* m- z* i0 i6 C5 w. T6 q6 V        pPt-&gt;pNextInIDHashBucket = NULL;5 w6 f" B, R7 _8 ^+ B; D. x
        }</P>
    ! `# Z+ B7 z% Z<P>    // Unlock the hash bucket
    1 \) G; |6 I, s' Q    m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();' d# W- K5 O/ j
    }</P>, m* m0 b" y  `

    5 ]: |; I5 `! t9 H<P>
    ) U/ }( J0 u$ H7 d  }& z/ Q9 \//-----------------------------------------------------------------------------/ S. A7 @9 I; Z* Y/ f1 a: \4 k3 P
    // Name:
    . C" i: a8 e2 u0 [0 j// Desc: 2 F& F; Z6 a. ^
    //-----------------------------------------------------------------------------1 y2 B" s& G# [" j* M
    void CMazeServer::SetPlayerDataForID( DWORD id, PlayerData* pPlayerData )$ l0 ~' r" l* ?4 e+ `9 q  m
    {, W9 m# |: F- q3 _; w, U
        // Make sure this player isn't added twice to the m_pstIDHashBucket[]9 B6 ~& R6 X8 H( g
        // otherwise there will be a circular reference9 o: @3 j9 q8 K8 A$ t
        PlayerData* pSearch = GetPlayerDataForID( id );( l, A" d& K" C  B
        if( pSearch != NULL )
    + D) h0 ]9 u. `' d0 g$ W7 F# N/ z        return;</P>
    . {/ W( a2 `0 d<P>    // Hash the ID to a bucket number$ e& k1 p7 ?$ t
        DWORD   bucket = IDHash( id );</P>) d& ]. {8 J, }6 n& ~: P
    <P>    // Lock that hash bucket
    3 e1 t, W( H) f7 q) F: f* E! O    const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;2 u( }7 D. e' f) X5 Z
        m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>$ Z& n' C' o* Y/ q/ i
    <P>    // Add player onto hash bucket chain
    ) H' q+ B7 Q8 `3 B6 W& Z1 z/ {    pPlayerData-&gt;pNextInIDHashBucket = m_pstIDHashBucket[bucket];8 \  o  j3 A( |
        m_pstIDHashBucket[bucket] = pPlayerData;</P>
    # ~& e5 b( x$ K1 W- ?<P>    // Store net id in player
    ' v8 [5 y* ^1 |4 l" q$ d, ^: C    pPlayerData-&gt;NetID = id;</P>! }4 Z& P7 n5 s6 G0 e  W! g
    <P>    // Unlock the hash bucket/ S, r& P/ C- ]( n  d! a& D
        m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();
    - ]: D5 U- S6 m* s4 D3 y}</P>* s' }) Z- p$ q( V$ g3 G: ~  B2 }

      E' C! R6 A  C6 |$ X% M<P>, \8 y% K3 Q9 V8 i. B8 X3 a6 f' q
    //-----------------------------------------------------------------------------8 F- c  u' @- M  l
    // Name: * J2 r+ \* ]8 P0 b3 k. ^* r. c- N
    // Desc: 9 w* l! ~" Q7 u" t
    //-----------------------------------------------------------------------------
    . L: h8 e" F1 |. _, J' T6 |1 z* dPlayerData* CMazeServer::GetPlayerDataForID( DWORD id )+ n( [" U, K: a* G
    {
    ) `/ z7 k8 G" X3 I    // Hash the ID to a bucket number" ]3 V5 q& x" J2 ~( C
        DWORD   bucket = IDHash( id );</P>
    3 \( [" x; ~+ Y9 `7 d<P>    // Lock that hash bucket
    9 i/ ]  u9 C' @2 `# \    const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;
    , h% K/ ^. ]: E4 X5 t    m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>
    % b! c% W3 _0 x7 k: _8 b0 @<P>    // Loop though players in bucket until we find the right one
    . d9 d7 y6 |8 F: f    PlayerData* pPlayerData = m_pstIDHashBucket[bucket];
    : W  d, T% x+ a  p( ~4 y3 n: ~  h    while ( pPlayerData )
    # V- ?+ y$ b  t: Q2 d    {) O4 ?9 E0 n# ?( s
            if( pPlayerData-&gt;NetID == id )
    + d+ n3 S* A9 |" H4 ]: h) f) j            break;
    ; I( R1 I" K) L        pPlayerData = pPlayerData-&gt;pNextInIDHashBucket;
    5 N9 H5 ^" K8 V; M    }</P>
    8 X" P- m  b  y. Q' s0 T0 i<P>    // Unlock the hash bucket8 n% D% h$ Y( z( K. ^$ u) l9 ]
        m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();</P>
    , q  V* B9 C; x<P>    // Return the player we found (will be NULL if we couldn't find it)6 j5 K4 L4 m9 A( ^, W6 m
        return pPlayerData;) e: s) ]* M8 o3 C0 F' s
    }</P>
    ) ]# r$ o9 G) z
    6 U& f( ^6 t: M4 p! T<P>% j+ _1 [! s4 i' ?" e( h* |6 M9 F
    //-----------------------------------------------------------------------------
    , \  L' Z: C0 M& y' T% R/ K// Name: ' `& G' ?( c, l: F
    // Desc: calls DisplayConnectionInfo for each connection in a round-robin manner& V( M% |7 m: V* ~% r# x; d9 i, f
    //-----------------------------------------------------------------------------0 `* W6 ~" s8 q' ]
    void CMazeServer:isplayNextConnectionInfo()- }" n- o+ c9 O
    {
    4 R* B- Y* e& Q    if( m_pNet )0 `$ B! u  v& ^! v: r
        {
    0 J' |1 v) q' d; j( o        // Find the player that was displayed the longest time ago, and display it.4 N% {, `2 _$ J
            FLOAT fCurTime = DXUtil_Timer( TIMER_GETAPPTIME );1 c$ S( g* J  a! P& Q2 E& a( }4 D
            PlayerData* pOldestPlayerData = NULL;
      A8 j  ?6 x! v& _        FLOAT fOldestTime = 0.0f;</P>; }( \( u) ]4 F/ r) S: y1 i
    <P>        m_PlayerDataListLock.Enter();</P>& ]0 \$ g0 R" Q: `" F% f  B, ]
    <P>        PlayerData* pPlayerData = m_pFirstActivePlayerData;
    1 K9 _& b3 [9 p        while ( pPlayerData )
    ! \) C, {5 N. o) G6 b, _        {
    ' e9 ?$ v* [# e            if( fCurTime - pPlayerData-&gt;fLastCITime &gt; fOldestTime )
    ( A* X0 M1 ]* c  M            {6 P, n, }0 ?. E0 y5 u. p
                    fOldestTime  = fCurTime - pPlayerData-&gt;fLastCITime;
    ) m, j/ F" l  _, q! O" B8 ^8 ~& Q                pOldestPlayerData = pPlayerData;) W2 F0 g( h( u  C. H& e
                }</P>
    / k8 u- D, T  K- b, j2 f<P>            pPlayerData = pPlayerData-&gt;pNext;8 g: t. ?! k6 P) i7 `/ p: {) ~
            }</P>
      d( Y8 [& j. m<P>        // Display the player with the oldest CI field, and update its CI field./ x4 {1 t0 v. y, \
            if( pOldestPlayerData )
    2 E, k* x& f; Y8 J5 M        {  _. Q- F% I7 G4 P$ {' U
                ConsolePrintf( SLINE_LOG, TEXT("Displaying connection info for next player") );
    / i2 G2 k$ i2 f9 d; X: s; u            DisplayConnectionInfo( pOldestPlayerData-&gt;NetID );
    % F. P/ X, u" P            pOldestPlayerData-&gt;fLastCITime = fCurTime;1 G# }: O7 Q' ~
            }5 B0 E9 W2 l4 d8 N2 G
            else& i1 Y4 z3 {' a0 b$ U" n
            {& K/ c- h' p8 a1 k0 @/ f+ J& t
                ConsolePrintf( SLINE_LOG, TEXT("No players found") );
    2 Y. n) D# M4 I) U6 s: t% {* {) R        }</P>
    - M) y# h. @' k6 R<P>        m_PlayerDataListLock.Leave();& ^% r4 h& N- I, E/ y& g0 C) @5 ^
        }& T4 `" K7 e6 Q0 C& X! ^3 R
    }</P>0 F& c+ {" J0 w% [  f

    / k: x5 ?/ R. F1 V8 A% C7 m7 W) n<P>+ L* V/ g2 O( f
    //-----------------------------------------------------------------------------
    8 E5 k" K9 `: L6 `3 L% `  N" Z$ O# p// Name:
    4 w2 e- B) ]8 o' g# O8 a+ {6 X1 e8 V// Desc: : D2 x0 M) }* E0 S3 {
    //-----------------------------------------------------------------------------
      Z* a" i: w. ?/ R5 |void CMazeServer:rintStats()# G) Q2 h3 |# b- p2 c& }
    {3 N, l! a- w: N7 ^1 N& i! k; S
        ConsolePrintf( SLINE_LOG, TEXT("Thread count: Active=%d Avg=%.2f Max=%d"),
    / Z# e' x3 S# K& R                                    m_wActiveThreadCount, m_fAvgThreadCount, m_wMaxThreadCount );+ v5 ]: ~& P# D4 ]
        ConsolePrintf( SLINE_LOG, TEXT("Thread Time: Avg=%.4f Max=%.4f(s)"),4 p; R1 P5 t& L# @- M6 y4 J" D0 M
                                        m_fAvgThreadTime, m_fMaxThreadTime );7 g; ~1 K' N. \% ~7 x2 n- G6 C! G
        ConsolePrintf( SLINE_LOG, TEXT("Players online (not including server player): %d"), m_dwPlayerCount );" K# }! T1 g. N
        ConsolePrintf( SLINE_LOG, TEXT("Peak player count: %d"), m_dwPeakPlayerCount );
    3 L, b* p# D. f  K# D% M4 [8 m. z}</P>
    9 Z) W+ {0 ^5 Q  ^8 L4 |1 {
    ! B8 B2 f+ W! M1 A! n: }" a<P>
    7 A7 h: I$ x' K% D0 `6 D. G: ^//-----------------------------------------------------------------------------; Q0 g/ \% _- x4 h7 {8 S* d& q
    // Name: 1 P& H. ?2 t) p4 @+ e' Z9 l
    // Desc: - Y! e! m) Z" q! l4 O0 g
    //-----------------------------------------------------------------------------
    & [6 s1 q; p! E8 gvoid CMazeServer:isplayConnectionInfo( DWORD dwID )4 y5 H7 g+ `' n# m) O
    {' z# j" t& m: t& j: i6 q/ o
        TCHAR strInfo[5000];
    & s7 L. F5 B' J9 X    TCHAR* strEndOfLine;
      u9 W+ X& x% @8 |4 h6 l    TCHAR* strStartOfLine;</P>4 K5 m. q; E/ {: w7 E1 L
    <P>    // Query the IOutboudNet for info about the connection to this user* M1 x/ v+ q' S' A/ R4 D: v% |, h
        m_pNet-&gt;GetConnectionInfo( dwID, strInfo );</P>
    * a0 ~( `6 A2 H. ^) U0 L4 J$ _<P>    ConsolePrintf( SLINE_LOG, TEXT("Displaying connection info for %0.8x"), dwID );
    " J5 `6 V: |2 w3 @" [+ D3 N; J    ConsolePrintf( SLINE_LOG, TEXT("(Key: G=Guaranteed NG=Non-Guaranteed B=Bytes P=Packets)") );</P>3 F1 ?2 m1 `; \2 o5 w' y8 Q' D* Y
    <P>    // Display each line seperately
    ; c- r! f$ {! d) e: @- V0 r    strStartOfLine = strInfo;* r/ W: ?$ r! m) C) H1 Z/ ?
        while( TRUE )
    # S6 K3 Q5 n8 s; Q) A    {
    & Z. j* w$ Y- C        strEndOfLine = _tcschr( strStartOfLine, '\n' );
    / D6 E% g4 D" g$ _# }        if( strEndOfLine == NULL )1 L0 [7 Z' t& ~! Y
                break;</P>. V" n; @; M; l8 V/ i
    <P>        *strEndOfLine = 0;
    ! K, g+ q+ |- [6 X% y: g! y        ConsolePrintf( SLINE_LOG, strStartOfLine );/ @* x1 K# v3 f
            strStartOfLine = strEndOfLine + 1;# X; I; [8 g& Z+ F8 z9 w- c7 z# v5 L
        }5 Z8 q5 D0 F5 B0 `: R/ t2 y2 j
    }</P>
    : O) u7 L+ i4 o) H- a7 y1 [1 l" V# M! _- k4 l$ ^  ]" d4 Q
    <P>3 L5 V, A! ~2 \0 ^4 i
    //-----------------------------------------------------------------------------5 t+ H7 F. a$ l7 }/ P, I' V. b6 V" p$ E( X
    // Name:
    5 _. R; e0 P% p// Desc:
    4 x  m% Y$ K9 d9 ]+ T/ {//-----------------------------------------------------------------------------
    : C& v2 D2 e. @. h6 tHRESULT CMazeServer::SendPacket( DWORD to, void* pData, / o- t' y8 A2 W: H9 S
                                     DWORD size, BOOL reliable, DWORD dwTimeout )
    1 y- X' w. }. X. A{
    * J" R5 f9 `( F0 p" c- A    // Chance of forcing any packet to be delivered reliably
    $ u% S2 C; d; ^$ t    if( m_Rand.Get( 100 ) &lt; m_dwServerReliableRate )/ I5 v6 F8 V8 D7 Z
            reliable = TRUE;</P>
    ! m- L2 m, v7 Y( d, U4 U& p# D<P>    return m_pNet-&gt;SendPacket( to, pData, size, reliable, dwTimeout );
    5 J% O% t# `6 ]3 `1 ~/ O' S+ g}</P>: I+ p/ w& A. K: Q, G" W8 c5 ~
    1 l8 b0 r* c/ H' O: _. B. k
    <P>
    , p% s8 o" c; O' ^" }7 D//-----------------------------------------------------------------------------
    2 G% W  M& T, l9 ^$ I$ f// Name:
    / r4 T6 A, h+ U! ]. B// Desc:
    # ^  }) \- P) z' Y8 `# |//-----------------------------------------------------------------------------" h) l0 \" {: X8 f( s2 ?4 _$ Y' m+ a
    void CMazeServer::SendConfigPacketToAll( ServerConfigPacket* pPacket )# f3 R! v. z/ }7 A1 d3 X
    {
    ! f$ E- i( u# T) I& R1 R    // If we're up and running, then send this new information to all clients( t, V6 ?( a) m6 |3 G8 `
        if( m_pNet )4 ]2 Q4 k' n5 b5 C$ R/ B3 w* c
        {
    : \- h1 g* j1 j- o' J        //Use the AllPlayers ID" q/ Y* C/ |+ n! j1 V; k& O
            SendPacket( DPNID_ALL_PLAYERS_GROUP, pPacket, sizeof(ServerConfigPacket), TRUE, 0 );
    2 z; r; b! Z. T% Q( n  }% d3 E! |( R    }
    # u0 \; {( q1 N' U, d2 V' F}</P>$ C4 U/ }2 U, D( y, `

    0 |) C9 i' E) k8 J4 G5 a<P>. u; x* X$ d+ B% e2 o
    //-----------------------------------------------------------------------------
    7 u0 o% T- [4 y8 [5 M8 Y0 h  O// Name:
    " W+ R7 g& _3 H: A0 p+ `// Desc: 3 D4 R7 {  \+ |: O2 J, e/ |/ l$ l
    //-----------------------------------------------------------------------------  n+ }, u. d2 ~! |2 c6 v2 z
    void CMazeServer::SetClientReliableRate( DWORD percent )$ A9 L, p6 s8 d  W
    {  X  f3 p+ o* S9 N
        // Update client config, and build packet containing that data7 g/ [3 w3 f! j1 [
        m_ClientNetConfigLock.Enter();! b% m7 I, d) e4 g( Y5 E& C, I8 B# \
        m_ClientNetConfig.ubReliableRate = BYTE(percent);" {4 v" h+ {4 v: V
        ServerConfigPacket packet( m_ClientNetConfig );
    & ~+ m- Z( z$ D8 K7 I    m_ClientNetConfigLock.Leave();</P>
    * a" m* _1 m! p6 t# {4 t, u<P>    SendConfigPacketToAll( &amp;packet );- J0 q$ O5 L4 t( A. Y& n3 {
    }</P>9 w- R8 V& R# d: y$ q: h

    / W: A) O' x1 g; }<P>
    4 e5 e- b( s6 Z//-----------------------------------------------------------------------------
    1 i* M0 U6 a0 w5 F2 m' u// Name:
    # f! |, s6 _! K// Desc:
    ' f4 c2 d+ f! _1 K//-----------------------------------------------------------------------------
    : L: U) T0 W' pvoid CMazeServer::SetClientUpdateRate( DWORD rate )
    . C/ m+ g9 _. m- x{9 T% V  b1 T5 S9 |, K) ~3 v2 s  R
        // Update client config, and build packet containing that data
    6 w. {( i9 z1 |2 _- C7 x5 T6 {    m_ClientNetConfigLock.Enter();+ o" t: n) g. A, X6 z" ?  g2 Q9 g
        m_ClientNetConfig.wUpdateRate = WORD(rate);
    * g7 W- c- t5 c    ServerConfigPacket  packet( m_ClientNetConfig );
    . M) l$ q8 o3 B0 M    m_ClientNetConfigLock.Leave();</P>6 n' j$ }3 g0 B$ n
    <P>    SendConfigPacketToAll( &amp;packet );4 a+ F$ h) u: J! H) x( w
    }</P>
    ( I& k8 @, H% }9 q# b9 S6 d+ t! |3 g! i
    , O2 O0 ]& @8 T* |( E/ E& _) c! M<P>2 F5 }% g6 ?( M( A: F
    //-----------------------------------------------------------------------------/ G% z8 l& M2 i* Z2 V+ k; N
    // Name:   I% Z% x# c# I, D5 K  Q4 L& z) Y2 ~* V
    // Desc:
    1 ?6 o, V4 L* I8 j: |% Y) r, ?' x5 u//-----------------------------------------------------------------------------
    ; A. D+ {, n, j8 y) t" q7 Ivoid CMazeServer::SetClientTimeout( DWORD timeout )- v4 O& R5 `/ O1 o7 Z
    {
    - K% f, o" b/ O  M, }3 t    // Update client config, and build packet containing that data
    % {; Y: ]/ i# h1 S    m_ClientNetConfigLock.Enter();
    5 i) `- l/ {$ q5 G; s    m_ClientNetConfig.wTimeout = WORD(timeout);
    " v; M9 Y5 B+ x" F$ m$ G$ z    ServerConfigPacket  packet( m_ClientNetConfig );" N/ I5 T# f. D, ?- H# h" C
        m_ClientNetConfigLock.Leave();</P>* f$ v, n( Y' `# s  i% J
    <P>    SendConfigPacketToAll( &amp;packet );9 a, f3 q/ G$ q6 x# d8 V3 B
    }</P>
    7 K( F' _" U1 C4 Z( M" Q4 h* D# U7 F, ^% i6 e3 w1 `# @% t
    <P>
    3 r! a# w9 @' T% O# y9 w//-----------------------------------------------------------------------------/ N4 f. T- \; w
    // Name: . U& W& I8 x( E* ^: {
    // Desc:
    - ]* L! h) O# E( l//-----------------------------------------------------------------------------
    3 ~9 Z; F3 W" u1 P3 s0 t/ a/ B' ivoid CMazeServer::SetClientPackSize( DWORD size )
    4 `" u+ y, Q' E1 G& e( t; o{- n( Z8 f. g/ x" G
        // Update client config, and build packet containing that data3 S9 E9 J) W0 o4 s+ }
        m_ClientNetConfigLock.Enter();
    & @& w6 }* Q% ~& n    ( }. _. \3 j3 C7 d
        m_ClientNetConfig.ubClientPackIndex++; //Increase index and verify location in array.4 r+ I- a; [& \! H1 Y/ C4 S
        if(m_ClientNetConfig.ubClientPackIndex &gt;= PACK_ARRAY_SIZE)   
    : v2 v7 Q  C9 a; b# I! ~4 n        m_ClientNetConfig.ubClientPackIndex = 0;</P>! u) L; Z5 W, @: n" n; T& h
    <P>    m_ClientNetConfig.wClientPackSizeArray[m_ClientNetConfig.ubClientPackIndex] = WORD(size);
    # s' P4 i7 c, |7 x: C    ServerConfigPacket packet( m_ClientNetConfig );
    6 C+ ]; G/ b2 K9 S( r0 c    m_ClientNetConfigLock.Leave();</P>
    6 l  z6 v5 a6 h6 N6 B1 y* D<P>    SendConfigPacketToAll( &amp;packet );9 a5 X9 A, Y  C' I' b+ y
    }</P>2 E- W& A3 p; E9 V

    8 O, p7 }/ G+ V- ]* ^<P># W( k9 G5 T+ m
    //-----------------------------------------------------------------------------. U! o7 c  {5 q5 F6 W( j( O
    // Name: 4 T# }* A1 |* Y9 K8 j" x% |
    // Desc: ! U' I6 z+ t/ {$ J( J
    //-----------------------------------------------------------------------------
    : ]( m# U" E) j( \void CMazeServer::SetServerPackSize( DWORD size )
    2 ~9 Q2 G2 _' }- X9 a! {: b4 P{! @0 c) t- M2 f9 Z  Z8 D9 _
        // Update client config, and build packet containing that data7 j5 M( ?5 M! g1 x4 U4 o
        m_ClientNetConfigLock.Enter();* ]) u) p) L& e0 A7 F
       
    * R0 E9 U9 d6 J, e# t. J    m_ClientNetConfig.ubServerPackIndex++; //Increase index and verify location in array.! y7 o5 l$ n9 m! F
        if(m_ClientNetConfig.ubServerPackIndex &gt;= PACK_ARRAY_SIZE)   , n. Q1 q' O2 J9 _7 H2 @" m$ s
            m_ClientNetConfig.ubServerPackIndex = 0;</P>8 g6 H% P0 b6 O
    <P>    m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex] = WORD(size);1 y; I/ e0 A4 l8 B
        ServerConfigPacket packet( m_ClientNetConfig );
    4 \- G6 P' W% ~4 k: j* J$ B, Q    m_ClientNetConfigLock.Leave();</P>( p" I) v$ k3 l3 g5 z+ I/ M- [+ a
    <P>    SendConfigPacketToAll( &amp;packet );; ~( \7 v+ G  X! v' `
    }</P>
    2 U  X1 ?3 R' B) B  x<P>
    * L9 N+ \8 O0 i//-----------------------------------------------------------------------------* R4 N& z2 }* a& b* r# e$ o
    // Name:
    / z# A* h" |# Y// Desc:
    7 K: C# P/ Z0 Q( }$ H0 n//-----------------------------------------------------------------------------& W8 ^$ k# O# A+ N
    void CMazeServer::SetClientThreadWait( DWORD dwThreadWait )
    0 E$ u2 Q' `# Z$ Y+ o5 I{+ R% ^  r: y$ R7 ?
        // Update client config, and build packet containing that data
    ' H. O9 O- N8 V, H5 @    m_ClientNetConfigLock.Enter();" P$ T3 z8 i. I. i& {) p
        1 Q: x7 v5 d4 ~: a) p1 l8 B. N
        m_ClientNetConfig.dwThreadWait = dwThreadWait;
    1 \% c- o2 ?3 ?    ServerConfigPacket packet( m_ClientNetConfig );0 D2 E! x9 \/ u  j$ t/ Y
        m_ClientNetConfigLock.Leave();</P>0 l+ l; O, [- [0 n" G* [
    <P>    SendConfigPacketToAll( &amp;packet );, A/ ~, v( [/ V* x9 c7 }
    }</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-4-15 03:08 , Processed in 0.475590 second(s), 51 queries .

    回顶部