QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 4185|回复: 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>* s( M. }+ S" J$ l
    <>// File: mazeserver.cpp
    5 K" v8 F0 x0 s" g. j+ ]//
    / Q+ V/ f  V+ R+ G/ ~// Desc: see main.cpp
    ) t* q, V) [  a5 @% r5 @//! r" n$ ~4 d& _$ F6 Q
    // Copyright (c) 1999-2001 Microsoft Corp. All rights reserved.
    6 F# l; r1 i% ^; ]: Q//-----------------------------------------------------------------------------& U6 P8 ]( r$ J9 X* m
    #define STRICT. }+ N8 o, o% w. j/ `6 i6 L
    #define D3D_OVERLOADS
    ) @+ }7 g: q) }: G- a2 `! Z#include &lt;windows.h&gt;
    2 k' g: P0 N4 R& s: {8 ?#include &lt;d3dx.h&gt;5 \6 J3 k4 h! i( J8 W" O
    #include &lt;stdio.h&gt;; n) n. f5 z3 @! g
    #include &lt;math.h&gt;8 ^) a, O4 q) u8 P
    #include &lt;mmsystem.h&gt;
    3 z' |2 ~# s* N, N9 n- s. m9 f: `#include &lt;dplay8.h&gt;
    % b3 K8 \8 ?  E( V9 G* A) A#include &lt;dpaddr.h&gt;
    " O' m1 e- ~. |! Z; |- K0 l#include &lt;dxerr8.h&gt;
    5 i! H6 e" {# m/ O5 Q6 {4 W#include "DXUtil.h"
    / ^8 C( T- w8 J+ p#include "MazeServer.h"
    7 U: Y- ~+ K& ]" F5 x0 w( W#include "ackets.h"1 E/ L. E3 ?% F9 C
    #include "Maze.h"1 L6 }0 l- B$ k# z. ^6 P0 h& V
    #include &lt;malloc.h&gt;6 N) x/ C& s+ Y- G" P5 [! c3 k. Q, ~
    #include &lt;tchar.h&gt;</P>" D: m+ S8 p" [. p# T
    + l# g7 Z& c3 i7 h
    <>//-----------------------------------------------------------------------------
    # k" A& G- t! T  M' B* }7 R! f% i+ Z// Name:
    % [$ P  _8 O$ F2 h7 b) a( a// Desc: 3 N) z- V* F+ e3 s& {- @
    //-----------------------------------------------------------------------------: R: m2 Y6 |+ U, Z9 p6 E% F, V& x
    CMazeServer::CMazeServer()+ D1 H; @) a( C/ g
    {2 ?- x, Q$ O8 c! d* Y! r
        m_dwPlayerCount         = 0;+ E$ x! {8 }7 \2 A5 {7 }4 s- s
       
    : h7 ?2 H0 n0 l( @+ g) P    m_wActiveThreadCount   = 0;
    3 B- T5 j' `0 z2 S" J" a. Z# j/ B5 y    m_wMaxThreadCount      = 0;
    . o  {4 o9 \3 R) f, l- D6 \7 _1 `    m_fAvgThreadCount      = 0;
    2 i+ k2 c  w: f6 p    m_fAvgThreadTime       = 0;
    ! D, i! t2 I$ _3 _* {    m_fMaxThreadTime       = 0;</P>" O; y0 ~' w3 k+ u4 a3 e
    <>    m_dwServerReliableRate  = 15;" p# E0 h# Y% _; R& r5 Y" b6 e
        m_dwServerTimeout       = 150;1 y+ `. J3 M: T. p2 y/ @# R
        m_dwLogLevel            = 2;
    ) S9 e4 A' j# e6 G1 e% E8 B5 ?# g    m_pMaze                 = NULL;</P>
    ' q% U) K- K& ]<>    m_ClientNetConfig.ubReliableRate = 15;4 _; _! j+ d4 [+ U
        m_ClientNetConfig.wUpdateRate    = 150;1 Z5 y( E( n0 ^; l& {7 o
        m_ClientNetConfig.wTimeout       = 150;</P>
    8 s" r! q7 w- q! S: r% b<>    m_ClientNetConfig.dwThreadWait = 0;</P>5 h  K: L: E! _$ r& U( q& g8 z) l
    <>    m_ClientNetConfig.ubClientPackIndex = 0;' R7 ?6 z1 b+ ?" a( Y
        m_ClientNetConfig.ubServerPackIndex = 0;
    ; m3 f8 J' o2 i( I# u+ h    for(WORD x = 0; x &lt; PACK_ARRAY_SIZE; x++)
    " |! e4 s& P) H2 p# w! L    {5 N6 A% J. Z' S/ t
            m_ClientNetConfig.wClientPackSizeArray[x] = 0;
      k2 j. c0 _' K% s# b0 h        m_ClientNetConfig.wServerPackSizeArray[x] = 0;
    6 m3 k8 T, Z) w) T0 ~    }
      b  G% E9 I, w: A: ^+ m}</P>
    ; G7 M. P$ H; R5 Y4 |/ H. o: J0 o  v; I. \( M* m
    <>
    5 x' Q6 a; c* v0 g. B$ E//-----------------------------------------------------------------------------
      G, w! L' K5 u( ^' X3 U// Name:
    % F/ y2 ~) }' G+ |% Q// Desc:
    : l- e8 t5 o5 m1 w" r//-----------------------------------------------------------------------------; T- \/ v9 `1 e. X- C6 w# `; U
    HRESULT CMazeServer::Init( BOOL bLocalLoopback, const CMaze* pMaze )2 q$ i7 ?1 S- M9 I: p4 E
    {! x' T9 ]6 z* n) Z6 N( n
        m_bLocalLoopback = bLocalLoopback;
    " x1 l  `, d1 `) e( t. R    m_pMaze = pMaze;
    ! O1 K4 @+ o3 t$ T- a9 G  r3 _    if( m_pMaze == NULL )
    - B% O! J( k1 A        return DXTRACE_ERR( TEXT("aram"), E_FAIL );</P>8 h7 |+ Z: F1 Z; H" T- h
    <>    // Grab height and width of maze
    $ G- b' ^; [$ ~% U. n    m_dwWidth = m_pMaze-&gt;GetWidth();
    ' m" f4 E2 l5 n6 L3 H( V  E    m_dwHeight = m_pMaze-&gt;GetHeight();</P>3 U) u1 F3 ^& Q" i
    <>    m_ClientNetConfig.dwMazeWidth  = m_dwWidth;
    3 g8 M& t2 N' O+ C' j0 d( k- x' G    m_ClientNetConfig.dwMazeHeight = m_dwHeight;</P>) B  i( u, L; _0 P2 s3 S
    <>    // Validate size. Must be a power-of-2 times LOCK_GRID_SIZE. Compute the shifts.  S1 U1 y8 z3 W: C$ a- K: S
        if( m_dwWidth &gt; SERVER_MAX_WIDTH || m_dwHeight &gt; SERVER_MAX_HEIGHT )6 D' ?! N# k0 {& [. y( M
            return DXTRACE_ERR( TEXT("Maze height and width need to be less than 128"), E_INVALIDARG );
    $ ^' {+ u9 o- m    if( (m_dwWidth % LOCK_GRID_SIZE) != 0 || (m_dwHeight % LOCK_GRID_SIZE) != 0 )
    # A6 v  I3 N0 o: f% E0 u# P        return DXTRACE_ERR( TEXT("Maze height and width need to be divisable by 16"), E_INVALIDARG );</P>" K' O3 c. c0 ~0 ~
    <>    DWORD scale = m_dwWidth / LOCK_GRID_SIZE;
    & ^! e; p! p5 _& k/ {: s# b) U    m_dwMazeXShift = 0;
    & Y3 q$ o- b4 h, ?0 H! a    while ( (scale &gt;&gt;= 1) )% X8 M0 @' D4 U" f3 M
            m_dwMazeXShift++;</P>
    5 Q" S3 G) \- h# E<>    scale = m_dwHeight / LOCK_GRID_SIZE;8 C% A/ S8 O0 Z6 \1 W' d  [0 k
        m_dwMazeYShift = 0;
    6 L- U5 n1 u  j8 v    while ( (scale &gt;&gt;= 1) )9 E' h- u! y) p* j
            m_dwMazeYShift++;</P>% m8 u5 g6 v' n4 X
    <>    if( ((DWORD(LOCK_GRID_SIZE) &lt;&lt; m_dwMazeXShift) != m_dwWidth) ||
    ; P6 D; `+ V" f' S2 s        ((DWORD(LOCK_GRID_SIZE) &lt;&lt; m_dwMazeYShift) != m_dwHeight) )! q/ Z7 a7 N+ |: h6 Q# `- m
            return DXTRACE_ERR( TEXT("Maze height and width need to be power of 2"), E_INVALIDARG );</P>" l8 }  z+ O; W
    <>    // Initialise the player list
    : }3 b- j8 l' j4 @  t. _3 X" P    ZeroMemory( m_PlayerDatas, sizeof(m_PlayerDatas) );2 P% D' l* \% D: O( ?& m. |- c
        m_pFirstActivePlayerData = NULL;+ G- W1 O( E7 D1 E8 W
        m_pFirstFreePlayerData = m_PlayerDatas;
    . l7 z- F  T! h% ?- \7 u" e; k# O- s2 H    for( DWORD i = 1; i &lt; MAX_PLAYER_OBJECTS-1; i++ )) |% j) G  ^) u
        {7 z6 D* _- f' p3 T
            m_PlayerDatas.pNext = &amp;m_PlayerDatas[i+1];! h) _$ F0 x( s' n
            m_PlayerDatas.pPrevious = &amp;m_PlayerDatas[i-1];
    1 k! @# j7 X6 I    }</P>0 a: ]+ M- |& u& u# h
    <>    m_PlayerDatas[0].pNext = &amp;m_PlayerDatas[1];
    % F  C& Z4 S6 j$ k3 f1 j+ P    m_PlayerDatas[MAX_PLAYER_OBJECTS-1].pPrevious = &amp;m_PlayerDatas[MAX_PLAYER_OBJECTS-2];2 B7 f0 ]# A; u8 O% L4 B  d/ p
        m_dwActivePlayerDataCount = 0;0 T0 |3 B/ x* G) ]
        m_dwPlayerDataUniqueValue = 0;</P>1 c4 H& o' u' v5 R
    <>    // Initialise the cells
    0 A6 @% F# V+ g/ T! K9 i    ZeroMemory( m_Cells, sizeof(m_Cells) );
    # t* Z, G  R4 Q' [0 i- m    ZeroMemory( &amp;m_OffMapCell, sizeof(m_OffMapCell) );</P>
    ; Y! i& D9 g# u4 p* F<>    return S_OK;
    * s  E; ~" B( V! @}</P>
    9 x  e: H) Q# y
    ! ^7 `0 n# G( E7 o; z: G2 e<>
    + ]+ D- {2 M- V+ m; _2 c" m8 m//-----------------------------------------------------------------------------5 r7 p# q: C$ ]1 h* w
    // Name:
    7 P" y; b) y, Q% [+ V6 ?// Desc: : Z2 R* g" k8 P& H: o: T0 h0 K
    //-----------------------------------------------------------------------------0 d( d4 T2 Z5 h1 n; |; B
    void CMazeServer::Shutdown()
    * `2 j, F4 T: S" L* e+ l. b5 a- M{
    8 R7 S* O+ Q% Q; M( k& h6 L}</P>
    : v1 w) Z# Z! E6 R1 P8 \" q- z3 L" Y
    # f  Y9 N' d6 w. u7 m2 P# C1 D<>
    ! F8 N/ ~1 X" E; B  v6 C0 e9 N//-----------------------------------------------------------------------------
    ; l' G2 _9 @0 ^; A8 J// Name:
    8 Z' C1 D/ N2 \' }4 X+ d" `// Desc: / V, N" H6 U; b6 P& ~: s3 N- O( S
    //-----------------------------------------------------------------------------
    , l( T) R2 T& ^, ?5 dvoid CMazeServer:ockRange( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )
    4 g! B# s6 s% W{
    % s0 W5 ~' N; f4 z1 d: @  G" I9 s    m_LockGrid.LockRange( x1&gt;&gt;m_dwMazeXShift, y1&gt;&gt;m_dwMazeYShift ,
    ; v2 L) ]1 [" y9 f                          x2&gt;&gt;m_dwMazeXShift, y2&gt;&gt;m_dwMazeYShift );
    ; Q6 ~/ `& z# ~6 R, ?  y}</P>
    . w+ l# z+ S! x( e8 B4 k- \
    / ?! K" {+ J7 E5 y% a<>) K" {% F. S( a2 ^1 z
    //-----------------------------------------------------------------------------
    # e' f2 ^5 F2 e4 `+ m% ^// Name: 8 i4 v/ X* q) }% V* E
    // Desc: ! v# `7 ~) H3 o! n- l
    //-----------------------------------------------------------------------------
    $ v5 M  ~# E% S3 ^( u; X6 [4 |void CMazeServer::UnlockRange( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )
    ! ?6 F" a; }7 Z9 i/ L- p- h5 z4 E{
    9 }$ F# g- u2 a1 v2 ^) a4 u    m_LockGrid.UnlockRange( x1&gt;&gt;m_dwMazeXShift, y1&gt;&gt;m_dwMazeYShift ,
    7 M# P/ c# T3 S1 ^                            x2&gt;&gt;m_dwMazeXShift, y2&gt;&gt;m_dwMazeYShift );
    " m8 V7 C( t1 q$ j, D% R}</P>
    1 W0 C7 E  l* F2 ~0 O" F; s2 G( D/ S  \7 H- |$ D6 H
    <># v7 a. w: n+ t% N# ?$ Y
    //-----------------------------------------------------------------------------: L5 ~! l& m: P; @6 d. M/ r
    // Name:
    - `4 d: C" ^6 H8 U% g& F- y// Desc:
    7 Z  J; U/ C7 x//-----------------------------------------------------------------------------8 W/ E5 }: E( o( {' c6 n
    void CMazeServer:ockCell( DWORD x, DWORD y )
    + Q* r! B8 P" ^  Z4 F{* J$ Q6 j) U, S$ n) |7 n) O
        if( x == 0xffff )9 e1 [; G. a+ \7 j: h9 H. W
            m_OffMapLock.Enter();
    % E  V% @; i% o0 F    else+ E* Z  d( W' y# L7 l2 x* o
            m_LockGrid.LockCell(x&gt;&gt;m_dwMazeXShift,y&gt;&gt;m_dwMazeYShift);8 B+ f2 X0 G5 R- Z% X! G) v" `5 F
    }</P>
    - g0 Q0 k' U5 u  p( E! O2 D- }2 t% H2 p6 \! G' I  H4 V- M4 q
    <>; V* Y2 B9 r1 g4 U3 f
    //-----------------------------------------------------------------------------
    6 D/ t8 u3 n: z6 y+ q// Name: , ^( C) s, Q: d$ Y9 ^  w
    // Desc:
    " V; H8 `/ p: D7 F//-----------------------------------------------------------------------------9 S* o! H2 U( n0 Y3 C: N. E5 b
    void CMazeServer::UnlockCell( DWORD x, DWORD y )
    * ]2 z- L4 q+ x5 m$ L{  Y' R+ y1 c4 |9 }: E6 ~
        if( x == 0xffff )
    1 u  h# [, ~' j. _) j        m_OffMapLock.Leave();
      _5 f% I2 f- E" b' O* _# T3 t    else
    ) m2 g. F" J7 }3 C( K        m_LockGrid.UnlockCell(x&gt;&gt;m_dwMazeXShift,y&gt;&gt;m_dwMazeYShift);
    5 r/ w2 `% z/ k; w6 A) R8 F}</P>0 s7 |: `- H  d2 _1 i3 W3 x
    9 }9 o7 c/ e8 f% _0 j# D1 e& z2 y
    <>% ~) {, j% T+ G' d, A; L, }
    //-----------------------------------------------------------------------------
    + s) _& e1 m0 t* ?7 s// Name:
    ' o# y6 M8 X% d// Desc:
    / T* Y/ g( X" m% e7 J% T# D. r//-----------------------------------------------------------------------------
    ; C/ f5 g- D. w' y# r7 }4 nvoid CMazeServer:ockCellPair( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )
    9 O! q; l' q$ A; T+ t2 ]{
    ( x; ~, L4 g# `6 L! s7 a+ z# }    if( x1 == x2 &amp;&amp; y1 == y2 )) f" x3 M5 k2 C) C8 J+ A
        {# U: |' x$ O4 i: e) b2 P) S  j! m
            if( x1 != 0xffff &amp;&amp; y2 != 0xffff )
    3 b$ ^3 }* L: T5 u# w            LockCell( x1, y1 );5 i2 o9 Z- v; H- V
            else) W$ |3 N7 W) s/ T' g/ S4 X- a/ p
                m_OffMapLock.Enter();</P>
    1 K8 B% {9 ~) q9 Z2 m( ?& r7 z4 }<>        return;
    6 A% T; A# B5 X7 z( H9 m0 u    }</P>
    . ~) A! k/ o4 i( V0 O4 \<>    DWORD x1shift = x1&gt;&gt;m_dwMazeXShift;
    " [9 T* Z$ k( k7 V. |. R    DWORD x2shift = x2&gt;&gt;m_dwMazeXShift;
    4 h3 e# o/ Q3 `1 i    DWORD y1shift = y1&gt;&gt;m_dwMazeYShift;
    , r% }1 o0 z# [    DWORD y2shift = y2&gt;&gt;m_dwMazeYShift;</P>
    ! v3 B7 ~: o# Y+ h! z<>    if( x1 == 0xffff )
    / J: s3 \3 j  w9 g. M    {
    ( i6 q3 V! p: K# _! E        m_OffMapLock.Enter();
    ( Y3 W, R( {" [5 D+ _" n. j9 \8 F        m_LockGrid.LockCell(x2shift,y2shift);, b( n0 B4 s- ?. ~/ d8 X  g
        }
    : `8 A% T3 f5 x1 R- c" x" ]7 x    else if( x2 == 0xffff )
    ' p5 B: H' P9 T5 ?! p. w    {$ y0 f- X, S- Z4 F7 z
            m_OffMapLock.Enter();
    " M( Q0 I% y9 U" N7 j: y& S        m_LockGrid.LockCell(x1shift,y1shift);. ?3 `2 }+ Q: D6 G) u- @& s
        }+ x$ v6 D# U  H/ z2 I& l
        else . M3 `& P  \) e# D+ z
        {
    9 R0 W/ i1 H: I        m_LockGrid.LockCellPair(x1shift,y1shift,x2shift,y2shift);6 G$ R' U7 D2 {% M" E
        }2 Y4 T5 g3 X6 B6 o0 E  q8 V
    }</P>
    5 \% F' b9 Z3 Q0 S8 U& L( Z, S& R; i/ X% A* p# B) g* W: m$ \
    <>, T9 }: O. G* ?% D1 v1 `
    //-----------------------------------------------------------------------------* W$ D1 B2 ?6 }- E! x
    // Name: ) R( d, }5 A, Z/ c# j8 N
    // Desc: 3 s" ^) Y9 z3 H# s8 I# T3 B
    //-----------------------------------------------------------------------------6 y% o. i) j' L
    void CMazeServer::UnlockCellPair( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )& r6 _+ B$ o8 O! x  L. s
    {3 P7 \7 v7 t$ D
        if( x1 == x2 &amp;&amp; y1 == y2 )  b/ @' e1 H% M$ g4 r) m
        {
    6 p$ H8 j! g+ }1 a5 w7 r        if( x1 != 0xffff &amp;&amp; y2 != 0xffff )" k: O! X5 h& t2 q" ?
                UnlockCell( x1, y1 );9 O: q5 e% x: Z8 v6 z* m0 x) I
            else
    5 M$ S  u6 M+ x7 r3 d. I            m_OffMapLock.Leave();</P>
    : C. j' f, j# O4 _+ L  {<>        return;
    , t; m  e, {: O: g& v1 O* u    }</P>
    7 F( r# z, B) Y' |<P>    DWORD x1shift = x1&gt;&gt;m_dwMazeXShift;
    - ]) s& F) V& i& |6 P    DWORD x2shift = x2&gt;&gt;m_dwMazeXShift;
    % D% y& }, a0 f9 v- |    DWORD y1shift = y1&gt;&gt;m_dwMazeYShift;
    . d" L; r( e: S7 e    DWORD y2shift = y2&gt;&gt;m_dwMazeYShift;</P>
    ) R9 ^5 ~" V9 E9 K$ P# ]<P>    if( x1 == 0xffff )5 E6 k; }! t2 {7 t/ C
        {
    4 j+ U$ D, [. z5 M) d        m_LockGrid.UnlockCell(x2shift,y2shift);
    8 [4 h! ?: i# x1 L( I) f        m_OffMapLock.Leave();/ s& i2 }4 j; w  G7 o& _5 q
        }  C. q/ d7 r: I- H* [! S
        else if( x2 == 0xffff )2 B7 K3 v+ k7 x4 ^' l
        {  Q% i: ^6 A5 H7 t$ l3 Y4 Y, T
            m_LockGrid.UnlockCell(x1shift,y1shift);
    / a8 a# H$ u+ Y, b9 ?4 b. R        m_OffMapLock.Leave();: I( n4 M, M: Q
        }' h- L' Q, ~! M8 l0 B, g; W1 O- [
        else
    " j4 u; l0 `, Q: b! q$ b    {
    7 z/ j, M: p2 z9 K        m_LockGrid.UnlockCellPair(x1shift,y1shift,x2shift,y2shift);
    - k" d+ U2 ^: C8 h7 Z. B    }
    7 j* _. S2 @0 K% ]- \}</P>3 j  K& ?: E" W2 z+ O8 R
    ! a6 G5 R* L! J9 p/ Z- `! u9 \. O* N8 U
    <P>. U' R0 F/ f' d5 Q
    //-----------------------------------------------------------------------------! N! |! c0 ~9 A& H+ E
    // Name:
    , ~' E# I! Y$ y6 [// Desc:
    4 \# I2 q0 o0 R//-----------------------------------------------------------------------------/ s/ z  [, k/ j4 `1 F2 `' \. Q4 c
    void CMazeServer::OnAddConnection( DWORD id )7 ^# U+ W1 X+ B, J7 A- N
    {
    9 R: E. T6 R* k3 h/ }) v# q    m_AddRemoveLock.Enter();</P>/ |$ j- D1 {6 [0 V
    <P>    // Increment our count of players
    " G5 x$ L3 }. |    m_dwPlayerCount++;
    # U) _: C1 a$ V+ m" }    if( m_dwLogLevel &gt; 0 )
    ' B' T7 V3 s9 j% P  l: @: u    {
    : C6 s& \5 V" K: U        ConsolePrintf( SLINE_LOG, TEXT("Adding player DPNID %0.8x"), id );
    + I! Q( O% m6 j: |- O6 L        ConsolePrintf( SLINE_LOG, TEXT("Players connected = %d"), m_dwPlayerCount );
    0 d7 }& \9 F+ i2 T+ Y+ {7 R    }</P>
    . s3 @0 T) L$ }3 x; O6 ?: }<P>    if( m_dwPlayerCount &gt; m_dwPeakPlayerCount )
    / b: u1 a" ], g6 O! \& X        m_dwPeakPlayerCount = m_dwPlayerCount;</P>
    $ e% e6 g9 ^) w+ }4 e% b7 t<P>    // Create a player for this client
    5 M# g3 d. o) x9 L. D0 I    PlayerData* pPlayerData = CreatePlayerData();
    , z$ m4 x. S" E/ b' Z; J    if( pPlayerData == NULL )
    6 f! n- [. v, w$ n5 A    {) E* M, X9 j; d) ~- q3 F
            ConsolePrintf( SLINE_LOG, TEXT("ERROR! Unable to create new PlayerData for client!") );
    . B. O" u3 u# \0 g2 ~$ [9 u/ x        DXTRACE_ERR( TEXT("CreatePlayerData"), E_FAIL );
    / p2 @( m  J! g3 K- ?        m_AddRemoveLock.Leave();, u/ s' x* U( R6 K
            return;. P' m9 i1 g0 q
        }</P>/ C3 Y$ O8 M# f1 B- {% o" @" D* b2 E4 K
    <P>    // Store that pointer as local player data
    2 s% h1 m* P9 T7 R/ `* g    SetPlayerDataForID( id, pPlayerData );</P>' N5 ?4 b, H# ?/ D" {
    <P>    // Grab net config into to send to client
    7 r9 |" ?7 D. \' w; A    m_ClientNetConfigLock.Enter();
    . L7 u: I# S3 }0 D    ServerConfigPacket packet( m_ClientNetConfig );
    6 s2 o) T. u1 n: Q& C& |3 D% r    m_ClientNetConfigLock.Leave();</P>5 N  g5 x; U0 u0 g6 D( w
    <P>    // Send it
    7 r! O4 ?( s* l    SendPacket( id, &amp;packet, sizeof(packet), TRUE, 0 );</P>
      j$ x: W3 `  d9 S4 j! N& \<P>    m_AddRemoveLock.Leave();
    " U  F) H: K9 f" v" C1 X2 C}</P>
    1 Q+ m* ]6 l) G
    : i3 G! M+ O. H  z% b) M: J( J<P>2 S3 ?, {2 y( G( c  r0 w: A* o3 ]. f
    //-----------------------------------------------------------------------------' B) e: e; e0 ]  G
    // Name:
    3 V2 c$ d2 z% |9 n, O// Desc:   X6 X- w6 Q7 S2 x9 n
    //-----------------------------------------------------------------------------
    6 y) K0 c! H4 |, I5 b  w+ ]9 `void CMazeServer::OnRemoveConnection( DWORD id )% v% S6 q8 x5 l3 {8 ^
    {
    0 y0 i  ]% y  _    m_AddRemoveLock.Enter();</P>
    ( E% Z' T2 A- O' q# A+ |<P>    // Decrement count of players
    7 ~, D3 G# T5 X4 n  r3 @    m_dwPlayerCount--;</P>
    / X8 i, y! t6 Y+ w$ I<P>    if( m_dwLogLevel &gt; 0 )7 l, W3 n) S0 @. M( o# b
        {4 t0 [$ C- `/ C$ M. P
            ConsolePrintf( SLINE_LOG, TEXT("Removing player DPNID %0.8x"), id );  V9 m( t  o- y& d9 d
            ConsolePrintf( SLINE_LOG, TEXT("Players connected = %d"), m_dwPlayerCount );8 z1 Y; f* f+ n* @: E  q# r- w
        }</P>
    . j( T% ^3 \9 \<P>    // Find playerdata for this client
    0 u# |3 a; Y7 h' T" E# {    PlayerData* pPlayerData = GetPlayerDataForID( id );
    " s9 N; u% d1 ~! p: O    if( pPlayerData != NULL )
    ; y: k6 K' b; o. q7 N1 E) {$ X. u    {: o& [0 \6 O6 s- `3 d1 `
            // Destroy it
    , h* ?5 @+ K+ B- c  |* A        RemovePlayerDataID( pPlayerData );7 ]8 Q! U" P9 {- c4 H
            DestroyPlayerData( pPlayerData );
    & D% q( C4 T0 }/ x" h3 L3 Z0 W  d    }</P># `2 r9 y( t4 h. h, C6 m
    <P>    m_AddRemoveLock.Leave();
    + f/ G2 [. d7 T; {* g4 v8 V" J}</P>
    , n1 K" t% w& L& w' W. I1 C$ |- @
    1 T- y' L1 ^. l+ ?( z8 S- n% \<P>2 T+ y* a% ?. B' k* B5 r1 k) _/ H
    //-----------------------------------------------------------------------------; i$ x7 F! V, K# \* I3 J+ z2 O8 B. ]
    // Name:
    7 P& Q. J/ l8 a. M// Desc: , n/ F! R8 V( g4 p8 B1 d4 F
    //-----------------------------------------------------------------------------
    - f8 O& a& {7 t0 }7 XHRESULT CMazeServer::OnPacket( DWORD dwFrom, void* pData, DWORD size )/ x: ?4 N2 \& Y* }
    {; q9 I0 L3 Y: K% ^# v6 A+ U" t) \  q, D
        BOOL fFoundSize = FALSE;</P>
    - Y  y8 I& d; s2 t, H, o  r2 l  j6 U<P>    // Increment the number of thread we have in this process.
    , P8 t1 c2 {8 [3 ~$ @2 T( E) T" R    m_csThreadCountLock.Enter();</P>: g6 {- [2 W6 g* X! h) R( v+ U
    <P>    //Get the start time of when we entered the message handler.1 J% O3 X* Z5 b' s" c
        FLOAT   fStartTime = DXUtil_Timer( TIMER_GETAPPTIME );</P>
    5 p/ v, J' u! [2 C<P>    m_wActiveThreadCount++;; r7 t, S' L( o& E0 C
        if(m_wActiveThreadCount &gt; m_wMaxThreadCount)  V/ n: h8 }& _* H% T) m% m
            m_wMaxThreadCount = m_wActiveThreadCount;: l7 B" {7 k; C9 {/ @5 u
       
    ! E2 T. d, Q/ V# f    // Calculate and average.
    + A( K; o) r- ]' h8 D( X+ `    FLOAT fdiff = m_wActiveThreadCount - m_fAvgThreadCount;5 ~9 V6 l8 }' ~* L3 v1 O2 L+ l
        m_fAvgThreadCount += fdiff/32;" a" b1 z' T" I. t5 r
       
    - L. S: W1 G0 m, n2 L$ t" C/ J. f    m_csThreadCountLock.Leave();</P>
    / z3 R& M' o( j<P>
    : v# ~. j/ {7 [( }    ClientPacket* pClientPack = (ClientPacket*)pData;
    & @" [# h' C5 l1 W- w- t    switch( pClientPack-&gt;wType )
    3 \% M! N" n$ ?: f) f    {
    * F5 d8 Y7 R& |# i5 W' O        case PACKETTYPE_CLIENT_POS:
    # L! t7 _$ q& A' ^5 j% [            
      A2 J! w$ v& Q' M# {5 `            // Check to see if the packet has a valid size. Including : `# x# \, f% o! L* [  x! |+ b% p% F
                // the custom pack size.
    , b3 f, a( w+ J            if( size &lt; sizeof(ClientPosPacket))' H. f7 U( r. ^1 ?) a* X/ n
                    fFoundSize = FALSE;6 j$ N* A8 z% }
                else if( ! IsValidPackSize(size - sizeof(ClientPosPacket)))5 V6 C4 s0 u+ [
                    fFoundSize = FALSE;& ~$ }  g- V- F9 W1 b+ l6 l
                else$ r" k, _4 ?  y' X
                    fFoundSize = TRUE;</P>, ]5 a. J! N7 F, U
    <P>            // If valid sized packet, handle the position.
    ( r+ Z0 z* y, S0 ^8 J            if(fFoundSize)# Z# R  C3 p0 W$ _
                    HandleClientPosPacket( dwFrom, (ClientPosPacket*)pClientPack );/ E. X( G- O0 R. Q( a. ]1 g% ~/ S/ N( V
                else
    . e3 w2 b) x. R9 ^* s$ m" s2 Q                m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );</P>
    * k0 O9 I8 b  q% s<P>            break;</P>
    , Z( x& Y# ~9 S' I* h% t2 A<P>        case PACKETTYPE_CLIENT_VERSION:
    ! p+ Z( s; _" b4 S+ l) f" w9 U  n            if( size == sizeof(ClientVersionPacket) )$ u# o5 @8 P3 l
                    HandleClientVersionPacket( dwFrom, (ClientVersionPacket*)pClientPack );
    1 Z- U) K5 ^1 v2 p' e5 J; P/ W            else" o& f. t6 {9 Y) b; ]; w
                    m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );+ L* D$ p0 @4 Y" \
                break;</P>9 X8 l) j  A0 e9 |4 [) q. J3 g+ w
    <P>        case PACKETTYPE_SERVER_CONFIG:</P>
    3 B* V" `; M# G! ^9 @<P>            // Server config packet sent to all users (including server). Just ignore and continue.</P>
    # I" k5 l+ C$ v9 u) B$ s<P>            break;
    7 X4 R" B& z' |9 b  y        default:: N2 h5 D' S5 x; C0 \1 b( p0 l& ^( W
                HandleUnknownPacket( dwFrom, pClientPack, size );
    3 [1 i: t1 v1 k# l3 x            break;
    * ~" X' U0 u' J    }</P>
    4 ~  w5 B$ O$ y! @<P>    //If the user wants to hold the thread, Sleep for given amount of time.+ H$ E- l) _1 P4 l! n6 e% p
        if ( m_dwServerThreadWait &gt; 0 )
    6 |; G4 }4 M. R6 n* E    {
    * i  |5 D8 g9 d        Sleep( m_dwServerThreadWait );7 x, X1 [7 n8 M5 w  q" A- G
        }
    3 s+ m% M8 U( ?! K6 G& o; I3 s: K   
    5 Y$ z8 F1 T+ y$ B2 U* X. ^$ U    // Retrieve thread data for this process.
    1 S' p: F( M% B0 {    m_csThreadCountLock.Enter();</P>
    7 \0 z; s$ B- X$ Q4 z, {9 U<P>    m_wActiveThreadCount--;</P>
    " h* S: _# R' J" g# Z8 h4 _! S! D<P>    FLOAT fDiffTime = (DXUtil_Timer( TIMER_GETAPPTIME ) - fStartTime) - m_fAvgThreadTime;
    1 X! y0 y  G) h* h9 [' P    m_fAvgThreadTime += fDiffTime/32;</P>
    ) \1 z1 _. W! B& V0 j7 p<P>    //Get the Max time in the thread.; t2 ]  P+ g& k
        if ( fDiffTime &gt; m_fMaxThreadTime )
    3 b* ?3 q2 n4 Q5 l    {
    4 O& o# W3 e* U  x& \. x        m_fMaxThreadTime = fDiffTime;
    0 V7 T  \0 K4 P' o0 l: K  j8 T& i    }</P>
    6 H3 K2 v/ g# A4 b* o6 _9 i<P>    m_csThreadCountLock.Leave();</P>9 G, H* g& ?& }) x+ q
    <P>    return S_OK;
    1 m. ?$ D" i3 B  ~  y}</P>
    8 n4 q. l: h( s$ n6 N& J5 ~6 x* ?6 y$ Z
    <P>//-----------------------------------------------------------------------------
    4 X$ H8 \1 a" C. C" V& e2 B8 A& ?// Name: & m% l4 t7 B: X, o7 f2 z$ O) N/ G
    // Desc:
    6 n! ]% q4 p& i. `2 o//-----------------------------------------------------------------------------
    ) k9 j) ]4 A' zBOOL CMazeServer::IsValidPackSize( DWORD dwSize ). i8 c# o6 W8 @9 n0 a+ m
    {
    1 R. @. D4 n+ Q4 L  J) S    BOOL fFoundSize = FALSE;3 {  y/ b8 ~% {- b6 X9 t+ ?
        BYTE ubPackLocation = m_ClientNetConfig.ubClientPackIndex;
      X. d' i, z# e    " h6 f4 O$ N# R0 D& w6 ~
        // Check through the array of valid pack sizes.
    # S4 B% p0 |/ b" [    if(dwSize != m_ClientNetConfig.wClientPackSizeArray[ubPackLocation])+ A; N. S" ?  z; {* R
        {
    ( C$ A) [0 T7 ?' u, ?( X% i        for( --ubPackLocation; ubPackLocation != m_ClientNetConfig.ubClientPackIndex; ubPackLocation--)" h" E' `- M7 }5 V  l! h- z
            {
    - M+ g, o& u: [, N! ]  S5 _            if(dwSize == m_ClientNetConfig.wClientPackSizeArray[ubPackLocation])! Z7 @& W' \. L$ p' o7 c) M
                {
    . q6 u: o, @+ N" [" Y                // Found valid size in the array." F: A. C6 O0 E
                    fFoundSize = TRUE;# U! q" Y1 k: p& }# Z
                    break;
    ( l4 s& X0 r8 q3 o" h            }! Z9 u* }6 U0 u! c% ~
                if(ubPackLocation &gt;= PACK_ARRAY_SIZE)  ubPackLocation = PACK_ARRAY_SIZE;  //Wrap the array.& ^# c6 y. ?- F2 _9 {6 G7 E# h! ]
            }
    ' P4 O# A. c9 K, g, G    }
    5 m; t% r% b* e* u8 Y    else7 e3 c: K* ]% L8 @  E
        {* F- E% E6 C* g1 C* ]
            fFoundSize = TRUE;
    # I! I: n* }7 }- z2 @( F    }</P>
      c& c+ `' i4 \1 L<P>    return fFoundSize;1 M* R) m. W3 J% c/ e7 k; r: e
    }</P>
    / I. P$ e- A, o" c( h& C7 O<P>
    $ h. u9 S$ Q; f( t//-----------------------------------------------------------------------------
    $ y4 M8 _6 k& d; X; U- h// Name: 1 X; h; n8 Q; T# e1 {; ^2 f! A
    // Desc: " Y# D* ~! }" O
    //-----------------------------------------------------------------------------1 @/ u# M! ?  l. t" ~
    void CMazeServer::OnSessionLost( DWORD dwReason )0 P- D" w: x# |  l0 e$ x# N
    {
    : y, n( e' T7 v# u0 R* C    ConsolePrintf( SLINE_LOG, TEXT("ERROR! Session was lost") );2 |( H8 o. f' I& B8 I7 ^
    }</P>9 N/ d' G" ?- G$ T) \

    ; t- i0 }5 \6 W<P>
    # Q0 e' y& z" P//-----------------------------------------------------------------------------1 F. u" X9 @: m! _7 H
    // Name:
    * m2 a) |0 o$ z7 V2 m// Desc: 2 a* K# l9 B( J, Q5 Z
    //-----------------------------------------------------------------------------2 ^& T/ E/ v  G& w5 y( l" J9 i
    PlayerData* CMazeServer::CreatePlayerData(); ^) N) I: H8 F3 e# r! P
    {9 V$ i+ E8 K2 t* n% b6 {
        m_PlayerDataListLock.Enter();</P>( q2 J* N& F6 K2 c# n
    <P>    // Grab first free player in the list
    ; `) O8 \$ B% u5 u% j5 ]$ A    PlayerData* pPlayerData = m_pFirstFreePlayerData;</P>
      L" D6 k* ^$ D- y<P>    if( pPlayerData )
    & Q  m2 K% c: U    {  n8 X& Q/ J* ]% `9 x+ }  }
            LockPlayerData( pPlayerData );</P>
    ) r  N+ p  K: P9 |<P>        // Got one, so remove it from the free list: d" f0 C. D( m( E
            if( pPlayerData-&gt;pPrevious )- j9 f/ J: \" u5 u6 ?5 ]
                pPlayerData-&gt;pPrevious-&gt;pNext = pPlayerData-&gt;pNext;  V& F6 l& l9 ~$ @
            if( pPlayerData-&gt;pNext )
    ) ?* F8 c- a8 V1 v9 P            pPlayerData-&gt;pNext-&gt;pPrevious = pPlayerData-&gt;pPrevious;
    " t# z" b  g# [        m_pFirstFreePlayerData = pPlayerData-&gt;pNext;</P>, E! K6 k3 h% ]/ y
    <P>        // Add it to the active list/ x! K* a8 {8 H4 B
            if( m_pFirstActivePlayerData )
    2 K! c9 u" @! {3 w5 x8 c5 U. o7 t            m_pFirstActivePlayerData-&gt;pPrevious = pPlayerData;
    1 U! N1 r2 e! y9 R7 B, |3 p        pPlayerData-&gt;pNext = m_pFirstActivePlayerData;( Y! M/ Z3 p, B6 O" N8 m! h1 F: E
            pPlayerData-&gt;pPrevious = NULL;9 e* T3 A+ t  y% d0 T  z
            m_pFirstActivePlayerData = pPlayerData;</P>
    " K$ l; I. I  P. @. j<P>        // Update count of players
    : T$ i- j* G  ]' T9 ~        m_dwActivePlayerDataCount++;</P>+ B! m  r+ z  X$ q7 H; }% F5 Z  b
    <P>        // Generate the ID for this player* Q) b) \  j2 @+ ?+ M! g6 }, J
            m_dwPlayerDataUniqueValue++;
    / U! x: J. P! D        pPlayerData-&gt;dwID = (DWORD) ((pPlayerData-m_PlayerDatas)|(m_dwPlayerDataUniqueValue&lt;&lt;PLAYER_OBJECT_SLOT_BITS));</P>/ ^' X1 G8 W- R3 E+ `* ^0 Q' t
    <P>        pPlayerData-&gt;pNextInIDHashBucket = NULL;& h- i) g: W- O" M! {) Y
            pPlayerData-&gt;NetID = 0;$ P5 c3 [$ t0 Q% f+ s9 V5 ]
            pPlayerData-&gt;dwNumNearbyPlayers = 0;</P>
    ( `7 F8 H$ b8 S; q4 F2 ^* v: s<P>        // Insert into the "off-map" cell' h/ G4 u7 G* n4 [; r
            pPlayerData-&gt;fPosX = pPlayerData-&gt;fPosY = -1;! `7 s& Y( |( F# z% G6 ]
            pPlayerData-&gt;wCellX = pPlayerData-&gt;wCellY = 0xffff;1 y" \$ p, [5 |) d  [: ^
            m_OffMapLock.Enter();
    + X7 t1 O  @& v" b" H        pPlayerData-&gt;pNextInCell = m_OffMapCell.pFirstPlayerData;* b  ?( U% f: c  S, B" M3 L
            m_OffMapCell.pFirstPlayerData = pPlayerData;
    # n/ r: W6 t- ~+ `- G        m_OffMapLock.Leave();</P>7 f+ z& l3 O( G6 B5 v; Q
    <P>        // Mark as active
    6 P1 T" p. v& J9 A2 r4 `        pPlayerData-&gt;bActive = TRUE;</P>" k1 G4 f3 t- Z! Q
    <P>        UnlockPlayerData( pPlayerData );% u" w, k) Q- g, D
        }</P>2 [5 K; R- x  `; j
    <P>    m_PlayerDataListLock.Leave();</P>" Y) x# ~: _5 Q6 y1 b7 J
    <P>    return pPlayerData;
    * p3 P" u5 S% w4 V+ E}</P>7 s8 E" |5 L7 k4 _( X

    % \3 _+ E% l- m* ]) T# V6 `<P>
    2 D3 e8 C" Z% Q" d4 p8 h( s//-----------------------------------------------------------------------------* ^8 A* J) a3 R! u5 \5 ?% K8 A1 a
    // Name:
    0 f1 a+ ~& v( r3 X' c- ?2 U* V& ]  H// Desc: + Q  K1 {0 @: I6 s
    //-----------------------------------------------------------------------------  H* x1 @! `0 K5 }& b
    void CMazeServer:estroyPlayerData( PlayerData* pPlayerData )6 K8 n3 Z. e8 K# h/ X
    {
    * m( F) g2 L$ N    m_PlayerDataListLock.Enter();
    3 l+ \. t% ?% `9 R' k+ M    LockPlayerData( pPlayerData );</P>) T0 F7 M& W* n! ]3 Q
    <P>    // Remove the player from its cell+ x2 L' R* ^% c, L' N$ @1 \: _# ?
        RemovePlayerDataFromCell( pPlayerData );</P>, V; x) W, W3 d6 k- m; o
    <P>    // Mark as inactive9 R7 l  v! M* K
        pPlayerData-&gt;bActive = FALSE;</P>( D! c; M3 V" b5 o
    <P>    // Remove player from active list# A5 L: n  A  @
        if( pPlayerData-&gt;pPrevious ), e, X+ P7 G0 V) t/ J
            pPlayerData-&gt;pPrevious-&gt;pNext = pPlayerData-&gt;pNext;1 ]0 W# k( H. L0 L1 \
        if( pPlayerData-&gt;pNext )
    0 [1 p* U4 `/ M$ O% ^        pPlayerData-&gt;pNext-&gt;pPrevious = pPlayerData-&gt;pPrevious;</P>* T- J0 r. R5 a' q: A& e* T; D
    <P>    if( m_pFirstActivePlayerData == pPlayerData ): e' v3 v0 c% ^
            m_pFirstActivePlayerData = pPlayerData-&gt;pNext;</P>; N5 @) E$ z0 A+ V" z4 [
    <P>    // Add it to the free list
    $ j4 q; s* y9 j8 ^& [    if( m_pFirstFreePlayerData )+ A) h! I9 |' a, L. l0 s
            m_pFirstFreePlayerData-&gt;pPrevious = pPlayerData;
    / Y2 ^3 s+ z: Y; j9 J+ B2 a% u    pPlayerData-&gt;pNext = m_pFirstFreePlayerData;" D1 d# ^/ j# S
        pPlayerData-&gt;pPrevious = NULL;/ Y- f2 T* g7 \: y( U* T
        m_pFirstFreePlayerData = pPlayerData;</P>
    & F) [* N, K/ ^' U; |/ B<P>    // Update count of players
    ; a  t0 g/ p: P* ~* q1 C    m_dwActivePlayerDataCount--;</P>
    7 {* A* B( N! P5 p1 I3 Z& G<P>    UnlockPlayerData( pPlayerData );5 \5 U: {  @+ H) o# o6 l
        m_PlayerDataListLock.Leave();
    % Q7 d4 V9 @! {- z& o: i, ]$ g8 f2 n}</P>: [) n: s# p! t% t* L! L5 l
    7 ]* L6 A, b5 h3 P  V8 q2 Y. _& ]
    <P>
    0 W2 |- \! D) w( f  |% M//-----------------------------------------------------------------------------  a- G% ]! c. ], O4 F' Z
    // Name: 2 o. t8 m" V/ n3 @6 p
    // Desc: ; ~% Y9 ~. g$ U  l* W
    //-----------------------------------------------------------------------------4 w  a! k" r8 Q1 }3 l9 f- A
    void CMazeServer::RemovePlayerDataFromCell( PlayerData* pPlayerData ); U, r  ~% W1 y4 ]2 H& o% a
    {+ C7 e' a0 M8 u- q: Z5 O+ q, p7 [/ W
        // Lock the player- L  P$ g8 g- m
        LockPlayerData( pPlayerData );</P>' B  a7 e3 E! H1 t
    <P>    // Lock the cell the player is in  S3 T$ N; \7 Q/ t5 j; L  n
        ServerCell* pCell;% L- E/ V/ ~( P9 A0 i3 O1 q" k
        if( pPlayerData-&gt;wCellX == 0xffff )3 m: j+ l# @0 y9 [& H4 }0 G
        {
    3 g* C1 v" G" A0 x1 Y5 g+ z        m_OffMapLock.Enter();; t8 x$ [; X  l* r3 Y
            pCell = &amp;m_OffMapCell;
    7 a& ?' s" V' E4 F+ F* o    }
    8 q- d% i$ C5 ^4 D, n    else+ U* T2 x+ }( W# W, Q2 H
        {
    ; J% g+ \- i  Y6 Z$ r6 t$ Z. i# ?        LockCell( pPlayerData-&gt;wCellX, pPlayerData-&gt;wCellY );
    ) W( ]3 ?+ ]7 X        pCell = &amp;m_Cells[pPlayerData-&gt;wCellY][pPlayerData-&gt;wCellX];
    ; M( H. m  h8 [% u( j! {% r% f    }</P>& B2 s0 O" r. R
    <P>    // Remove it from the cell+ v' |! K) Y+ h/ O3 \2 l
        PlayerData* pPt = pCell-&gt;pFirstPlayerData;
    9 R  n' U' n, r% G; K    PlayerData* pPrev = NULL;( J9 o0 T3 h4 S8 h+ I' R
        while ( pPt )! A: E; w, O# y9 u5 ~
        {
    $ G8 |1 V( [5 k  ]% j0 W        if( pPt == pPlayerData )7 s0 A5 u. e' I+ `# A0 L
            {
    ( S7 D" i7 G4 B2 P( \% B            if( pPrev )' h3 ~9 K& A8 J% ?) \
                    pPrev-&gt;pNextInCell = pPlayerData-&gt;pNextInCell;
    2 D' W$ D# p1 E% ]. a            else" g! Q2 s7 L5 ?" }" }
                    pCell-&gt;pFirstPlayerData = pPlayerData-&gt;pNextInCell;</P>
    / y5 y4 c" K; `1 Y8 A4 C" b<P>            pPlayerData-&gt;pNextInCell = NULL;
    # e  M. x2 K& T" U" B0 n2 y            break;0 z5 W0 N9 i. z
            }
    2 p: ~( k. y' k$ t* I        pPrev = pPt;
    + `, m4 \/ Y4 i        pPt = pPt-&gt;pNextInCell;
    , I0 L2 R/ |$ s    }</P>
    ' B  R" j$ M( `" T$ W$ V<P>    // Unlock the cell7 L+ e0 r' h& c& z; a4 a$ W
        if( pPlayerData-&gt;wCellX == 0xffff )+ C, v# T/ B% R% G  y
            m_OffMapLock.Leave();
    / l  x5 z0 G# P    else. H2 `/ F% [% p4 N0 ]" `1 c
            UnlockCell( pPlayerData-&gt;wCellX, pPlayerData-&gt;wCellY );</P>  }# g- f6 W& F  O
    <P>    // Unlock the player
    5 s! W' u$ I; x8 M/ d8 C+ C    UnlockPlayerData( pPlayerData );4 K4 t; w4 s1 M$ Y* P6 Y7 l
    }</P>
    0 k" n  @! {/ `3 ]0 i: Y! f) `& j) |
    <P>5 u' u9 k8 x, S
    //-----------------------------------------------------------------------------! m( B! p* e* G3 L+ X5 `0 ~
    // Name: , M! B! q" i* c7 B( u) m: T
    // Desc:
    / s) O; R% `5 ]% s; Q//-----------------------------------------------------------------------------
    - N/ [/ X2 o2 c# @( i$ P( m+ Rvoid CMazeServer::UnsafeRemovePlayerDataFromCell( PlayerData* pPlayerData )
    ! u, t; q- a: s" K! ~{9 f& Y: v) w! P: o9 z$ u
        ServerCell* pCell = GetCell( pPlayerData );
    + t& e- Y* T. x. G' ~* e$ M    PlayerData* pPt  = pCell-&gt;pFirstPlayerData;
    : C# b, j8 @! Q2 O    PlayerData* pPrev = NULL;5 u7 X3 x+ C$ }
        while ( pPt ), Y, T* I2 c( A: O+ ~% a3 {
        {
    # L8 s7 g2 b  r4 Z( O! x        if( pPt == pPlayerData )1 t8 K8 X' G8 W3 R' W+ U
            {$ B7 K2 a5 y; z) G+ R6 ~, r
                if( pPrev )
    / g& {3 x. Y0 k+ C2 a                pPrev-&gt;pNextInCell = pPlayerData-&gt;pNextInCell;& l2 p$ C4 x5 q; Q9 V
                else
    $ l9 z3 Z5 L9 P/ l5 m  L                pCell-&gt;pFirstPlayerData = pPlayerData-&gt;pNextInCell;
    : S4 B' l% q) b' a& v% }            pPlayerData-&gt;pNextInCell = NULL;) b- i/ X: [' D$ [6 {/ O8 c
                break;8 K- D! v6 ^% ~; O
            }
    ' j# o' s# f% F- H' i0 S/ a        pPrev = pPt;6 G; w# X! J* l* {- Z$ ~0 X
            pPt = pPt-&gt;pNextInCell;
    1 r4 |+ [$ V/ q8 N" [    }$ t: i" e* ?6 t
    }</P>9 k3 h" h8 |( Y" Y9 S0 o+ B3 Z

    . V& q8 ~4 K- X5 |+ F<P># Y& g) r" J% q; m% _: K! a
    //-----------------------------------------------------------------------------: F8 {2 ]# s. l( H
    // Name: - q7 L9 j& K# o/ D; E6 b# j" [( |2 \
    // Desc:
    , T' G5 c, i- u3 Y+ m3 W4 l6 P//-----------------------------------------------------------------------------3 X5 H9 k0 @6 v6 v7 n; U
    void CMazeServer::UnsafeAddPlayerDataToCell( PlayerData* pPlayerData )* M9 M* j2 g( u7 H; n: e4 _
    {
    ; n6 W0 u+ w" w3 \/ }$ g    ServerCell* pCell   = GetCell( pPlayerData );
    9 o9 T- r8 o4 q/ [' W    pPlayerData-&gt;pNextInCell = pCell-&gt;pFirstPlayerData;
    1 o/ g% V6 h' U* h+ w    pCell-&gt;pFirstPlayerData = pPlayerData;1 l; C( ^3 ?- n0 W. P
    }</P>
    * u. L! J0 J& S
    ' G% k, {  y0 ]( J9 v: D<P>
    ; o6 O4 q2 W4 x8 q0 ?//-----------------------------------------------------------------------------
    : O- K7 I- p/ x// Name: 4 }4 E0 @7 n9 N- u' P
    // Desc:
    2 u2 ?" ~5 i$ R2 q! X; o//-----------------------------------------------------------------------------+ r! @9 k3 `" Q& x* w
    void CMazeServer::HandleClientPosPacket( DWORD dwFrom, ClientPosPacket* pClientPosPack )
    8 g7 G3 m" U: J. w5 Z! N' r{
    + E; B7 ~3 g( H$ [% y4 Q    // Grab player for this client and lock it0 B# o  M7 Z' P5 h' i4 P$ w
        PlayerData* pFromPlayer = GetPlayerDataForID( dwFrom );
    : _+ _9 u: |, V; P    if( pFromPlayer == NULL )6 q8 U* R$ n) `* U. v2 M% L
        {
    ; ]) r$ l7 D" p& l, [4 ?! K5 ^3 s        if( m_dwLogLevel &gt; 1 )! e! |4 J8 `# z+ x
                ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Could not find data structure for this player"), pFromPlayer-&gt;NetID );
    . B4 O9 s+ v4 X* J- ?$ n        return;
    " E8 H7 l  Q- L  L) Y- U. Y4 m, Y    }</P>
    . Y8 e# e# f# W+ ~<P>    LockPlayerData( pFromPlayer );</P>
    $ t1 F5 Y6 o$ u: C: P<P>    if( FALSE == pFromPlayer-&gt;bAllow )
    7 a8 W+ G2 _) B& r8 t/ `# h  j/ F    {
    4 t! Y* F, Q2 g" G( L/ R+ N$ p        if( m_dwLogLevel &gt; 0 ), ]4 r9 ^. ?$ z" m5 O3 H
                ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Got position packet from bad client.  Rejecting client"), pFromPlayer-&gt;NetID );</P>) ?2 I/ C( o- l% p! c
    <P>        m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );
    8 d( _: E7 ]! J6 ?* @* ?0 [2 f/ D9 k; e$ g        UnlockPlayerData( pFromPlayer );  r; C( T0 n6 e
            return;# @9 Y* w) S+ [, p
        }</P>
    ; |( I* Q! u# x! H6 w7 T, u5 U, f. v" A<P>    // Compute the cell the player should be in now
      |+ k& ]6 h' e! p6 {# I/ A- q    DWORD newcellx = int(pClientPosPack-&gt;fX);
    ) z3 J# p/ {0 K; U6 Q4 m& r5 M2 S    DWORD newcelly = int(pClientPosPack-&gt;fY);6 u2 e  k  N, d  R
        DWORD oldcellx = pFromPlayer-&gt;wCellX;
    ) a# Q0 f6 O# `0 j/ h& g    DWORD oldcelly = pFromPlayer-&gt;wCellY;</P>
    . S. f+ {' r5 V: b, v3 s- H<P>    // Have we moved cell?- l9 Q" Q: [5 ~
        if( newcellx != oldcellx || newcelly != oldcelly ); P1 V1 d9 W, q/ O4 p: ?: `
        {
    / ~) P1 M; X* V3 {) @; q        // Yes, so lock the pair of cells in question0 P( L, G+ w- [# o+ S+ L
            LockCellPair( oldcellx, oldcelly, newcellx, newcelly );</P>
    - C% Y: t, S# ?$ m- Q. h<P>        // Remove from old cell and add to new cell; j& C/ y3 ]. T4 {6 s
            UnsafeRemovePlayerDataFromCell( pFromPlayer );  F# x/ W" @3 X  ^# L& C' N; j
            pFromPlayer-&gt;wCellX = WORD(newcellx); pFromPlayer-&gt;wCellY = WORD(newcelly);
    ! \# M- Q1 q$ b8 M" {/ i        UnsafeAddPlayerDataToCell( pFromPlayer );</P>+ c* z- M1 U6 y" P0 r6 K
    <P>        // Unlock cells
    + r; x& M/ z9 I$ W  b        UnlockCellPair( oldcellx, oldcelly, newcellx, newcelly );- l! [) Q9 \6 v% f) v; V
        }</P>
    1 |. Z, l, n! i3 y* i5 ^  }" _6 a<P>    // Update player position+ R6 {3 t7 T6 J
        pFromPlayer-&gt;fPosX      = pClientPosPack-&gt;fX;# \. O' ~$ i6 G; p& B9 H& {
        pFromPlayer-&gt;fPosY      = pClientPosPack-&gt;fY;
    - b) \3 j' a4 u    pFromPlayer-&gt;aCameraYaw = pClientPosPack-&gt;aCameraYaw;</P>
    , O' H( h9 S+ h" F. A4 U8 q' [<P>    // Allocate space to build the reply packet, and fill in header 5 |5 @$ p. j2 Z# H: E
        DWORD dwAllocSize;) t( ~( u5 }& y8 }/ k! U; J
        ServerAckPacket* pSvrAckPack = NULL;</P>4 b2 M3 O/ e" h% O; g6 k; W3 G
    <P>    // Begin by allocating a buffer sized according to9 n3 s& j4 [. e) w1 {
        // the current number of nearby players + 4.  This will give
    / {* R  [+ t1 @& ?9 e; a8 w* x" s    // a little room for more players to come 'near' without resize
    6 h3 a! L5 k1 Q! m2 Q5 D    // the buffer.& I) P+ T2 K) M8 c9 i) a. R  ?
        DWORD dwMaxPlayerStatePackets = pFromPlayer-&gt;dwNumNearbyPlayers + 4;</P>: F- p, R% P9 C
    <P>    dwAllocSize = sizeof(ServerAckPacket) + dwMaxPlayerStatePackets*sizeof(PlayerStatePacket);8 @; ]5 m3 V8 j+ K& B7 _# D8 T, Q
        pSvrAckPack = (ServerAckPacket*) realloc( pSvrAckPack, dwAllocSize );
    6 _- _; X' T; R8 S6 @/ y    if( NULL == pSvrAckPack )
    * [8 }- x# J) Z4 w5 J) z) w/ m$ G& D( R    {
    # [8 V' I2 y, x        // Out of mem.  Cleanup and return4 a- M9 o% `% Y$ {: s' N" x  g& i4 a
            UnlockPlayerData( pFromPlayer );6 y) j3 X8 H7 J3 X1 }9 N1 j5 b4 Y
            return;      
    . D* e# B4 C$ h3 Y7 z6 N    }- F: D) L" W$ E: r; Y
        ZeroMemory( pSvrAckPack, dwAllocSize );</P>
    . o$ M  B: S* z, G# E* ?" r# z<P>    *pSvrAckPack = ServerAckPacket(m_dwPlayerCount);( {) u  P' S6 S6 n7 P
        pSvrAckPack-&gt;wPlayerStatePacketCount = 0;5 _3 k, L6 D% J
        PlayerStatePacket* pChunk = (PlayerStatePacket*)(pSvrAckPack+1);</P>
    - _3 a5 w. {  p# \/ ^<P>    // Compute range of cells we're going to scan for players to send! S: P: d4 Q8 A. ]$ V- Y" q2 H
        DWORD minx = (newcellx &gt; 7) ? (newcellx - 7) : 0;
    % T! |; U& _# m1 J    DWORD miny = (newcelly &gt; 7) ? (newcelly - 7) : 0;
    4 K3 j( H' q; Z$ o' _$ {    DWORD maxx = (newcellx+7 &gt;= m_dwWidth) ? m_dwWidth-1 : newcellx+7;
    8 F, `9 J  c, f9 m$ U: e5 K4 C1 K    DWORD maxy = (newcelly+7 &gt;= m_dwHeight) ? m_dwHeight-1 : newcelly+7;</P>
    ; N. M$ R2 s) E8 Y* I! N( c9 Q<P>    // Lock that range of cells& O  p! C3 I* X3 T# }# A
        LockRange( minx, miny, maxx, maxy );</P>
    . p6 D- a8 `# o$ s( i* K<P>    // Scan through the cells, tagging player data onto the end of
    ( _. z/ s5 p( |9 n# h4 {    // our pSvrAckPacket until we run out of room1 s- l- A: b& |+ `
        for( DWORD y = miny; y &lt;= maxy; y++ )! Z% i8 L7 @/ p& x) b& m# K/ G5 [
        {
    0 Z/ D- `/ ]2 A" [2 V  D" L        for( DWORD x = minx; x &lt;= maxx; x++ )
    ) K, @" s" ]3 w        {
    / x' X/ j( i+ D2 O! \            PlayerData* pCurPlayerData = m_Cells[y][x].pFirstPlayerData;
    , c% q1 r/ k! o, [# K            while ( pCurPlayerData )" i7 F9 w, }4 Z% {* W" T( ^
                {, ^+ b/ m# ]. G! k+ g0 x% ]
                    if( pCurPlayerData != pFromPlayer )
    : t/ l1 `! _; }  r0 y3 l                {
    # b& p9 R* T+ I# u, Z                    if( pSvrAckPack-&gt;wPlayerStatePacketCount &gt;= dwMaxPlayerStatePackets )
    " \( ?) c- }6 h8 p                    {
      c. u3 l0 j4 R: _+ `                        // Make sure pChunk is where we think it is
    & P6 m5 J  z/ Y4 E( C                        assert( (BYTE*) pChunk == (BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket)) );</P>
    1 ~6 W5 T$ Q2 ^& s; W4 r& e6 ]. t8 O<P>                        // There are more than just 4 new nearby players, so resize the
    ' N9 X3 |, {7 [9 Y. e$ C                        // buffer pSvrAckPack to allow 16 more PlayerStatePacket's., O& [; l9 F$ ~4 U0 u- R8 J7 D& {1 j
                            dwMaxPlayerStatePackets += 16;- i) K3 C7 ^1 `6 w( a1 l: [& E* x
                            dwAllocSize = sizeof(ServerAckPacket) + dwMaxPlayerStatePackets*sizeof(PlayerStatePacket);
    9 b0 _8 G' U; _4 y' i1 o                        ServerAckPacket* pNewSvrAckPack = NULL;, N( t, @% M; `
                            pNewSvrAckPack = (ServerAckPacket*) realloc( pSvrAckPack, dwAllocSize );
    " o/ O; S9 O& S  p) R/ W6 v$ z                        if( NULL == pNewSvrAckPack )* T! J2 J1 f( D0 t: z. A/ E8 h
                            {+ m& {# H1 R4 H! C
                                // Out of mem.  Cleanup and return
    2 ~- y) I! J/ R                            free( pSvrAckPack );
    : U/ \# J& W7 N& |: A                            UnlockRange( minx, miny, maxx, maxy );" e; d* c" N4 {3 q; ]  J! P3 ?
                                UnlockPlayerData( pFromPlayer );
    ' H$ G5 m  z. V( R0 @: c                            return;       - J# r/ {0 t/ M5 ^
                            }</P>
    * @9 p6 |+ Q# {9 i" j7 p2 J6 _<P>                        pSvrAckPack = pNewSvrAckPack;, [" W: Q# F. ?  f" G6 _0 t# z
                            pChunk = (PlayerStatePacket*) ((BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket) ) );</P>$ y) N1 A0 a5 h
    <P>                        // Make sure pChunk is still where its supposed to be0 x' F3 \, O9 b0 w
                            assert( (BYTE*) pChunk == (BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket)) );/ o( B; |" ~2 s1 g
                        }</P>$ p  K6 W$ X  y
    <P>                    pChunk-&gt;dwID       = pCurPlayerData-&gt;dwID;( e6 y9 U6 j" p* w
                        pChunk-&gt;fX         = pCurPlayerData-&gt;fPosX;
    ! S1 }# g6 F: [. V5 G  v) H                    pChunk-&gt;fY         = pCurPlayerData-&gt;fPosY;1 h2 V7 B) D6 u* Q) S
                        pChunk-&gt;aCameraYaw = pCurPlayerData-&gt;aCameraYaw;' e2 g: k8 l/ Q* t/ I# z$ P
                        pChunk++;: V) F8 S# [; J8 p2 W2 g) v
                        pSvrAckPack-&gt;wPlayerStatePacketCount++;
    + S/ s  |" H! ^2 [0 h                }; i4 t" A) c' Q8 H2 ~0 V2 h
                    pCurPlayerData = pCurPlayerData-&gt;pNextInCell;6 i0 ]0 K  D% @& V$ y( \
                }! J: D2 ^1 ~) h* V
            }
    " d/ A. F) j+ f    }</P>
    $ T3 ?$ ^; D! a( v$ s( o( V( q; y<P>    // Update the dwNumNearbyPlayers for this player- V# L4 G- t, ]( u( x' R( f
        pFromPlayer-&gt;dwNumNearbyPlayers = pSvrAckPack-&gt;wPlayerStatePacketCount;</P>
    ; Q+ ]8 r" v, H$ _' u<P>    // Unlock range of cells
    " ^" v( l2 _% T% o$ _7 G- l    UnlockRange( minx, miny, maxx, maxy );</P>% g5 t/ [+ |6 V: N# L6 S$ S
    <P>    if( m_dwLogLevel &gt; 2 )
    5 j2 W! {. F( U% `; ?1 P+ P    {0 i6 Z+ {& `4 m* X
            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Position is (%0.2f,%0.2f)"), pFromPlayer-&gt;NetID, pFromPlayer-&gt;fPosX, pFromPlayer-&gt;fPosY );9 B" H& j* T0 ?" ?4 ?6 ~$ S
        }; S: _- _& W7 q- a3 r
        else if( m_dwLogLevel == 2 )# X4 u. m8 ]9 Y! T/ Q% h3 R5 w
        {% a9 H& S  H8 d/ u
            FLOAT fTime = DXUtil_Timer( TIMER_GETAPPTIME );' {' P& |( Q2 [5 Z! W2 ^: M
            if( fTime - pFromPlayer-&gt;fLastDisplayTime &gt; 60.0f )
    : e0 f2 e2 w" i, g        {. h; a& f6 f# i# B: a: d& X" I
                ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Position is (%0.2f,%0.2f)"), pFromPlayer-&gt;NetID, pFromPlayer-&gt;fPosX, pFromPlayer-&gt;fPosY );' G) p; i& s. p) H- a* c8 g" c# Y* l
                pFromPlayer-&gt;fLastDisplayTime = fTime;* ]( |: q$ ^/ u  n- A: j
            }. o+ e- b: c/ G" f
        }</P>: w7 O7 A( _8 l" d) ]& e: z) H
    <P>    // Unlock the playerdata) u. w# l6 c3 a6 P: m  z* j+ x
        UnlockPlayerData( pFromPlayer );</P>4 w( h" L- M5 a2 I
    <P>    // Send acknowledgement back to client, including list of nearby players
    2 G) V! d8 L, k5 r# ?' A7 ~. W    DWORD acksize = sizeof(ServerAckPacket) + (pSvrAckPack-&gt;wPlayerStatePacketCount * sizeof(PlayerStatePacket));, h8 ?8 y; Y/ R2 v/ t' G4 }7 ]
    , ]8 X% `0 [8 u, {, O, p
        // Pack the buffer with dummy data.
    1 C9 z) f) X9 d) ~    if(m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex] &gt; 0), j, i; e5 i- S! m, J% m3 a7 q
        {$ _+ Q* x/ s5 {* }# ^  C, m4 m
            DWORD   dwBufferSize = acksize + m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex];
    " z; z( N6 F+ g* G3 q# z1 o* F        VOID*   pTempBuffer = 0;</P>1 L7 a7 K+ B: ]  J4 `" L
    <P>        pTempBuffer = malloc(dwBufferSize);
    4 r) K# y; p; ~% w6 }2 v* w- H        if( NULL == pTempBuffer )
    5 h; k+ K3 R: a4 |% u% }9 c        {& K0 K5 B$ J9 {- R3 I) L3 e# I
                //Out of memory, V, c3 R: M9 h! p# |% C+ j
                DXTRACE_ERR_NOMSGBOX( TEXT("System out of Memory!"), E_OUTOFMEMORY );1 R% L% E) a: B
                free( pSvrAckPack );
    , f) o! n/ M4 b. _3 z8 G            return;
    0 G* }( |0 V$ Y' d& X( ]5 X4 K* O        }</P>
    ; h, |' {7 }7 i1 e<P>        FillMemory(pTempBuffer, dwBufferSize, 'Z');
    6 ~7 Y2 P5 T) N3 {        memcpy(pTempBuffer, pSvrAckPack, acksize);</P>
    1 I" v$ D, ~# E<P>        SendPacket( dwFrom, pTempBuffer, dwBufferSize, FALSE, m_dwServerTimeout );# c- S+ D$ R  h; l& w- p, e
        ) U+ S. Q/ e. o* o: p
            free(pTempBuffer);
    ( b. X8 g6 u: ?    }   
    + z$ ~; l# ?+ q" ^( r% }    else
    " y* V6 R9 K9 s3 v( s5 k  z    {! `& Y% _$ }! W  Y2 G
            SendPacket( dwFrom, pSvrAckPack, acksize, FALSE, m_dwServerTimeout );. x5 w0 W/ {" Z  }! v5 q% r
        }</P>
    # S2 ^; |& t& r8 v& j2 L! M<P>    free( pSvrAckPack );</P>4 }7 f0 P; B' \' k- n0 i. Y
    <P>}</P># ~% F% ^4 M3 c" o& ~( w, Q3 d- n+ Z

    2 U" m4 o0 Q- a8 Q, b# @<P>6 o. V9 M4 i- }& @
    //-----------------------------------------------------------------------------3 r. b# |& }) N& M
    // Name:
    / n$ m' E3 `$ q, b' k1 I// Desc:
    $ N. i, h' C" J) ~/ g/ r9 T//-----------------------------------------------------------------------------2 a% s2 {, e: Y+ t2 T9 G
    void CMazeServer::HandleClientVersionPacket( DWORD dwFrom, ClientVersionPacket* pClientVersionPack )
    - W2 n( o: @) M! X$ A1 F7 g{5 a+ u! B1 G8 z$ [; Y1 j# O) X
        // Grab playerdata for this client and lock it4 V  a  M* ]( H" L" ]( h
        PlayerData* pPlayerData = GetPlayerDataForID( dwFrom );- P+ Z3 T" K( C6 a5 f
        if( pPlayerData == NULL )
    $ X/ i) B2 {2 N% M4 c* i3 C        return;
    ( S: u" d' A" H2 Q. u7 V9 g    LockPlayerData( pPlayerData );</P>
    8 T' s# W5 B6 B3 L8 C3 l<P>    // Record the version number
    : Z" V8 l5 C* M5 ]: s    pPlayerData-&gt;dwVersion = pClientVersionPack-&gt;dwVersion;</P>
    8 a% }9 l3 }  d<P>    if( m_bLocalLoopback )
    4 V1 W9 L% j; \5 k9 R' |  Z        pPlayerData-&gt;bAllow = TRUE;1 Q/ r/ i8 E4 f" ?* Q
        else# s. S9 x; ^5 l  T% v
            pPlayerData-&gt;bAllow = IsClientVersionSupported( pClientVersionPack-&gt;dwVersion );</P>- P) y0 h  f& w. u0 b  L  v
    <P>    if( m_dwLogLevel &gt; 0 )
    # F2 u- ?& j) ^( h" T        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 A4 x. h& F' B2 B  `+ w7 J* V4 [
    <P>    if( FALSE == pPlayerData-&gt;bAllow )  b: q* ^$ I- s) W# A
        {" R+ P$ A0 j( Z4 o) U2 ]
            if( m_dwLogLevel &gt; 0 )
    ( W3 c2 f+ }  c            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Rejecting client"), pPlayerData-&gt;NetID );</P>
    5 s! V* d) @, I3 _9 Q- p<P>        m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );7 y# H; J6 \5 c
            UnlockPlayerData( pPlayerData );
    & A3 q2 R! e5 t( W3 b& W" u* i6 x        return;5 w2 F( W' o8 J
        }</P>) o; {2 t' q( Y! c& |( t# L, r/ C) L
    <P>    // Unlock the playerdata! K* n- B; u! {7 d2 J$ W& Z
        UnlockPlayerData( pPlayerData );</P>+ G+ D4 j! q+ j# ~8 R$ N& U
    <P>    // Send acknowledgement to client that the client was either accepted or rejected5 c5 Y! n$ H0 y4 Y/ X0 D
        ServerAckVersionPacket packet( pPlayerData-&gt;bAllow, dwFrom );
    - ]1 U7 T. c% m/ r  g' r    SendPacket( dwFrom, &amp;packet, sizeof(packet), TRUE, 0 );
    6 H  Y) z( H7 a% u4 y}</P>* T5 s+ V- ?. ~) g2 S& u
      R9 u: o$ n4 T" _: p% N2 b
    <P>
    ; p( V/ n9 D* R  e, i' Q//-----------------------------------------------------------------------------; A* O& a5 K1 I$ D( u: v" o; a, `
    // Name: 9 L3 v  H& S) n; o) j! D* L7 H
    // Desc:
    9 e, z2 q9 \( D1 m# E, D//-----------------------------------------------------------------------------: T7 Z" j* s7 N% s3 |
    BOOL CMazeServer::IsClientVersionSupported( DWORD dwClientVersion )7 g1 k! ^. R) _) k6 D  i$ Z4 l
    {& ~! _& d* M5 ]0 y$ I; ^) m
        switch( dwClientVersion )- b5 o# s9 N9 F
        {+ d6 t( I4 g8 ?, x5 ~
            case 107: // only v107 is supported: |, S2 L3 w8 m% m4 G* x
                return TRUE;% F  |' Z, S" V. [. E8 n
            default:% ~8 U- y( ]. f) x1 y
                return FALSE;
    0 D8 \+ U; G4 _/ A; j% x* e" r    }
    ; k- B9 q6 e$ g$ b}</P>
    $ z' K6 N- g7 q* m; [0 D; X" X& W7 S& I& n. [+ W9 i8 ~
    <P>( r$ P, `' n. z
    //-----------------------------------------------------------------------------3 w: o: V3 t0 i+ s3 R
    // Name:
    6 v0 \! l% H5 i3 N. U// Desc:
    , v& x0 B) A8 r% u# O7 L//-----------------------------------------------------------------------------+ s1 K5 u( d2 S" U9 d* e+ u- P
    void CMazeServer::HandleUnknownPacket( DWORD dwFrom, ClientPacket* pClientPack, DWORD size )6 j0 Z7 Y1 b$ c% D
    {% I4 U! T4 H7 S* h
        if( m_dwLogLevel &gt; 1 ), s# d0 L4 n. H; [
            ConsolePrintf( SLINE_LOG, TEXT("ERROR! Unknown %d byte packet from player %0.8x"), size, dwFrom );</P>: R8 T" w) y0 v8 N* [1 y8 p$ l
    <P>    m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );% T  R8 \2 o! r5 }/ V  W- k
    }</P>. g8 |2 q; F" |3 D. i  V) q

    % w+ J8 u+ K* Z9 V$ c9 ]# V<P>
    $ ~  }5 Q) p, M+ X! T//-----------------------------------------------------------------------------
    0 g  E1 B: g, M// Name:
    6 E* `/ @- A& F' Q" r// Desc:
    0 A4 _1 \' |- s% _  q1 [! q//-----------------------------------------------------------------------------
    % o/ K% K. D! E+ `( P- F& Z- ~& gDWORD   CMazeServer::IDHash( DWORD id )
    5 m5 x1 N9 Y5 O1 }) d& B5 a{
    8 w6 l2 Q/ ]" o7 D& Y# ^6 k) v    DWORD   hash = ((id) + (id&gt;&gt;8) + (id&gt;&gt;16) + (id&gt;&gt;24)) &amp; (NUM_ID_HASH_BUCKETS-1);1 D- i! c0 _9 B+ p: D) G! J* y6 G' C
        return hash;; z& v/ c; O' s+ b
    }</P>
    5 x1 J/ D0 F2 j
    ! X7 n4 X8 e7 C* k<P>
    & k& A( m* O0 g4 h+ p/ v//-----------------------------------------------------------------------------
    9 K2 J' R: n' w" H  P6 j// Name: * f6 N( ]# b7 n/ q" H
    // Desc:
    9 ?$ s7 g0 s' B: M! w//-----------------------------------------------------------------------------* z; I- X- R- _' Q+ R
    void CMazeServer::RemovePlayerDataID( PlayerData* pPlayerData )/ ]3 H2 K4 W9 W; G  z) i- g+ u
    {. A3 ^' g1 ^: |- R, k) ^5 K  y) Q
        // Hash the ID to a bucket number
    % P0 ^+ p0 J) ]4 p9 y) t    DWORD   bucket = IDHash( pPlayerData-&gt;NetID );</P>
    8 d1 z9 L1 K0 X$ s8 w% x<P>    // Lock that hash bucket
    + _+ w6 m/ e8 P7 F; c6 A    const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;! J) y8 Z# r+ M
        m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>
    5 P5 }  w9 E: y7 F# S8 L<P>    // Loop though players in bucket until we find the right one
    1 i) r. N  V8 O& g1 G3 T    PlayerData* pPt = m_pstIDHashBucket[bucket];" B. \( M( w$ _* J8 q& u! a
        PlayerData* pPrev = NULL;5 D4 e- ?' F% h0 @: `; [1 i4 B5 {
        while( pPt )% V- D4 `3 D  j, Y9 ~0 @) ^) E
        {: Q4 m# ^5 V6 i: h0 L
            if( pPt == pPlayerData )
    5 r* W' a$ U( d- b# G  y+ O            break;
    8 w+ p2 e. R, a( M        pPrev = pPt;( Y0 Z  f  t  z6 x
            pPt = pPt-&gt;pNextInIDHashBucket;3 B" t, \! \6 {* Y+ m4 Y6 K
        }</P>
    & p7 h3 t5 C+ t<P>    if( pPt )8 J# |- Q# t2 G5 E
        {; {5 C6 ]% `4 z
            if( pPrev )$ H: H8 X/ e- k& q: N; g% G5 U
                pPrev-&gt;pNextInIDHashBucket = pPt-&gt;pNextInIDHashBucket;8 }. v2 v8 f, Y3 _
            else
    & N) o) Q6 s0 x% a" `            m_pstIDHashBucket[bucket] = pPt-&gt;pNextInIDHashBucket;5 A; a0 D5 A( H9 y9 O$ [
            pPt-&gt;pNextInIDHashBucket = NULL;  v" s- E& H; d) @8 V  k' C
        }</P>
    - k( H! ]3 `9 D) Z<P>    // Unlock the hash bucket
    + t6 x$ b; q$ f, e/ W  _    m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();( r# X9 j+ @5 h& ]+ b/ u8 |0 q
    }</P>
    # g. @! G: e; w, Z9 e4 n( @3 Z8 w8 _1 F; B' ^% q0 Q
    <P>
    $ F8 h# Q# i$ @; `$ D3 Y//-----------------------------------------------------------------------------' _8 m$ L* `# V, U1 q( _! e4 b3 {
    // Name:
    " ]1 u: }- w8 I7 X9 {% R0 v, k+ G// Desc:
    8 U' e8 @& t& U//-----------------------------------------------------------------------------; Z8 n) K+ \* _( U- M/ I* T
    void CMazeServer::SetPlayerDataForID( DWORD id, PlayerData* pPlayerData )2 v+ |0 ?' v& j& X" j- Z' v+ K( i& L
    {
    6 ~/ p6 m) P- W! o    // Make sure this player isn't added twice to the m_pstIDHashBucket[]
    - _/ \1 J' g. g5 G" N5 N1 E$ @5 g    // otherwise there will be a circular reference7 k. {  }/ X. f8 J$ k* a5 d+ b
        PlayerData* pSearch = GetPlayerDataForID( id );: }9 }) V  o$ S* Z
        if( pSearch != NULL )
    ( u1 H5 R) L2 Z% M& i9 a; x        return;</P>
    8 E2 V# m( Z# Z! C! Q( b5 f<P>    // Hash the ID to a bucket number; O$ {( N9 w' r) u
        DWORD   bucket = IDHash( id );</P>
    ) b( D1 }' \7 a, X, h$ ?<P>    // Lock that hash bucket9 R% I5 k* h4 h& v1 h, ^
        const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;7 f* i3 o3 y& l$ g# A
        m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>
    ) l8 V! s0 \. ?) g6 c<P>    // Add player onto hash bucket chain0 n8 B  `7 |7 T4 v
        pPlayerData-&gt;pNextInIDHashBucket = m_pstIDHashBucket[bucket];2 _* B0 Z4 M+ e/ ]" k
        m_pstIDHashBucket[bucket] = pPlayerData;</P>
    " U$ m7 J0 g* l/ M! L6 R6 G- v  K<P>    // Store net id in player
    - V% ~. B# I1 i3 N1 }    pPlayerData-&gt;NetID = id;</P>
    3 I8 X4 ?, R+ \8 X" a4 _<P>    // Unlock the hash bucket% J) _" t  D" t+ ?: H2 a- t; S
        m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();2 }4 d" _. a4 F) x& p( u
    }</P>3 T) Y8 h: ~& c# d
    + s- `6 I+ T+ V; G; _
    <P>
    , Z, D+ ]- j6 O- _* }7 p3 y//-----------------------------------------------------------------------------1 [6 W$ d8 v" o. c. j
    // Name: / Q; B1 q' J# [
    // Desc: / n8 b- {: g9 B5 A% E; N
    //-----------------------------------------------------------------------------
    4 H9 {' [3 v  I6 UPlayerData* CMazeServer::GetPlayerDataForID( DWORD id )
    7 |2 `2 x0 L  V! Y8 }{, D0 B$ c; N" Q9 Z2 V0 D, D, r
        // Hash the ID to a bucket number
    4 x9 v2 l+ A& R    DWORD   bucket = IDHash( id );</P>' Z1 B/ z& F- ~
    <P>    // Lock that hash bucket
    , A  Q) e" G9 o: d$ p9 L" Z    const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;" c3 S1 `( {0 o+ K( T8 P5 s
        m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>3 J1 z1 L2 A2 f. N/ V
    <P>    // Loop though players in bucket until we find the right one8 p8 r  }; s  s
        PlayerData* pPlayerData = m_pstIDHashBucket[bucket];
    ( D2 i8 I1 @, l! c. e7 p    while ( pPlayerData )
    : |3 x( g" n, m' U# s! a: J* f    {% y4 u. G* Y* w  b! c- N- ^/ Q
            if( pPlayerData-&gt;NetID == id )2 Z5 v/ O6 X; h, a" |
                break;
    6 A' d# N. K- m6 M5 Q, B# {        pPlayerData = pPlayerData-&gt;pNextInIDHashBucket;$ W0 [- ]; n, r0 ~
        }</P>. g1 l! O! ~5 M3 S9 q) b3 o
    <P>    // Unlock the hash bucket' \" b2 [7 J: W6 R" ^
        m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();</P>3 k( Y. p, Y& S4 m: {
    <P>    // Return the player we found (will be NULL if we couldn't find it)
    9 U# k9 J! o& K( F" e    return pPlayerData;0 \3 s% s  _# x
    }</P>
    3 ]! v  S5 H! J$ k$ X% R% X0 ~  X2 C$ Q3 E/ _3 E, J6 m
    <P>7 @0 A7 d, _* ]- S$ w& c2 S
    //-----------------------------------------------------------------------------
    0 h: @. b4 T. K! p// Name:
    ( @3 z; X7 e' E9 ?- B0 G3 Z! c// Desc: calls DisplayConnectionInfo for each connection in a round-robin manner) x% b" Y3 c/ K) g0 |0 t7 a
    //-----------------------------------------------------------------------------
    % O, v' F* u9 t" q3 Evoid CMazeServer:isplayNextConnectionInfo()6 D- v- o' l  u+ w. c) M1 ^
    {
    # h4 I/ T6 }/ Z    if( m_pNet )
    " p5 l6 o, j$ C( Z9 g( [    {
    ! X; D9 J5 w& y1 o% G        // Find the player that was displayed the longest time ago, and display it.1 Y( u8 J$ N. x  k9 f
            FLOAT fCurTime = DXUtil_Timer( TIMER_GETAPPTIME );( {& n5 a+ _7 {% d
            PlayerData* pOldestPlayerData = NULL;
    ( V$ r3 P9 i# }        FLOAT fOldestTime = 0.0f;</P>
    2 C# Z. a6 T! G; l7 l<P>        m_PlayerDataListLock.Enter();</P>( _3 K4 D2 t) `3 m
    <P>        PlayerData* pPlayerData = m_pFirstActivePlayerData;8 b: T! m9 m  ~2 l" N) p4 t6 S
            while ( pPlayerData )4 q4 }% y5 e5 r0 M6 K3 Z6 M, r
            {( B& V. w) z* Y: p
                if( fCurTime - pPlayerData-&gt;fLastCITime &gt; fOldestTime )
    7 N2 X6 U/ Z$ I& z1 @, D            {; u+ L, L6 @1 F* _
                    fOldestTime  = fCurTime - pPlayerData-&gt;fLastCITime;2 I+ j5 L1 A/ T+ O3 M
                    pOldestPlayerData = pPlayerData;
    ; R2 P( D; E7 w/ T  }            }</P>; m. |' }) h, q  M" Q& Y' q
    <P>            pPlayerData = pPlayerData-&gt;pNext;
    % H- e% }) i# f0 x        }</P>8 W+ {8 ~; p  @
    <P>        // Display the player with the oldest CI field, and update its CI field.
    4 t! K+ T6 U1 [# U! r  v/ ~2 T5 E        if( pOldestPlayerData )+ O: g1 f; `% V) \5 _/ K' F) [
            {5 a) S: C4 Y- ?9 }1 R( P! F
                ConsolePrintf( SLINE_LOG, TEXT("Displaying connection info for next player") );
    - n7 K" B9 P& x# |6 ^9 ~7 C* W) H            DisplayConnectionInfo( pOldestPlayerData-&gt;NetID );0 ^9 s- ?% p) j
                pOldestPlayerData-&gt;fLastCITime = fCurTime;
    8 [, S% R% G  m; z7 C- t4 O        }+ X1 \- ~! A) I( _/ F
            else0 J0 u/ h" @$ b  d
            {9 t2 @; N6 i& g4 l* X. {7 V
                ConsolePrintf( SLINE_LOG, TEXT("No players found") );
    / }/ |, q9 ?2 U( R5 o3 ]        }</P>
    6 f: |$ x, A8 V2 a, l- x* n<P>        m_PlayerDataListLock.Leave();' z3 U$ t7 g  \2 s2 Z, v
        }3 R" Z0 L2 W0 \
    }</P># C* [$ W* [* ^+ {
    1 c* x1 n! {$ o# q  Q. z* |
    <P>+ V) f. \) L! B
    //-----------------------------------------------------------------------------. t! x1 z$ }8 x5 S& [) f2 Q
    // Name:
      p( h, ^1 h% d( D/ Y; d// Desc:
    - p: u6 k( e; E7 E# g//-----------------------------------------------------------------------------0 w3 \$ H) U% D: _8 b& n: N
    void CMazeServer:rintStats()
    ) m9 h1 O+ X! L# T{
    ' R0 t0 o  B" z. _    ConsolePrintf( SLINE_LOG, TEXT("Thread count: Active=%d Avg=%.2f Max=%d"), 7 K& u) `3 e* g7 |% J
                                        m_wActiveThreadCount, m_fAvgThreadCount, m_wMaxThreadCount );6 P# Y. I0 j7 y/ Q7 i
        ConsolePrintf( SLINE_LOG, TEXT("Thread Time: Avg=%.4f Max=%.4f(s)"),1 G3 H1 |4 X1 W& b4 L
                                        m_fAvgThreadTime, m_fMaxThreadTime );! y8 e: o4 x( n3 z: f% B! s
        ConsolePrintf( SLINE_LOG, TEXT("Players online (not including server player): %d"), m_dwPlayerCount );
    ; q' }% `, z/ z4 W" w4 x9 p    ConsolePrintf( SLINE_LOG, TEXT("Peak player count: %d"), m_dwPeakPlayerCount );
    9 l. Q% g/ D5 ^9 n- R6 y: i& L}</P>
    ( I0 e% x  r2 ?% E1 B' F, Y* l' w+ Y3 r/ K6 C/ G
    <P>" u4 ~0 o) y: s7 G6 g
    //-----------------------------------------------------------------------------
    0 ?( p3 r7 i$ M+ R; Q( }2 y& Q// Name:
    $ a, b4 {2 W. Q! c. ?7 M- _, N' K// Desc:   j" _, r& Y7 A- ?. Z! D
    //-----------------------------------------------------------------------------* t) u4 S% Y  c& m2 i- l$ c
    void CMazeServer:isplayConnectionInfo( DWORD dwID )
      [& Z$ F5 @) z& W- J, ~; L/ ^2 Y* `- t{4 s' r# z- v, F3 Z& ^6 E) ?! v! p
        TCHAR strInfo[5000];- j/ Y) ^) S, }8 k& a% O
        TCHAR* strEndOfLine;% |9 c6 P( G' j5 e' ~8 o9 f) r
        TCHAR* strStartOfLine;</P>
    1 R. I% T& z4 j3 P" e) }<P>    // Query the IOutboudNet for info about the connection to this user
    9 i% N+ S3 R, D1 U, g% z/ c8 w    m_pNet-&gt;GetConnectionInfo( dwID, strInfo );</P>6 z& ]: L( O# q4 {; }7 Z5 a% y
    <P>    ConsolePrintf( SLINE_LOG, TEXT("Displaying connection info for %0.8x"), dwID );9 J/ E; ~, p7 T( P; I, @# d
        ConsolePrintf( SLINE_LOG, TEXT("(Key: G=Guaranteed NG=Non-Guaranteed B=Bytes P=Packets)") );</P>
    5 g" o( X8 _4 B+ D! S( E" S+ X/ B<P>    // Display each line seperately3 S! I  y% a( }* o& w0 v% q
        strStartOfLine = strInfo;
    / z, e: f6 ~! Z( q    while( TRUE )$ A, ~4 B1 W0 T+ v
        {9 [# [7 `+ b1 B
            strEndOfLine = _tcschr( strStartOfLine, '\n' );
    7 t8 Q, \# t4 i' z        if( strEndOfLine == NULL )( X! e8 p& n6 i0 f% G
                break;</P>
    $ C% e2 A/ f, E6 v0 E<P>        *strEndOfLine = 0;
    6 U) r1 s  X* K9 u2 v! O        ConsolePrintf( SLINE_LOG, strStartOfLine );
    3 X& m' Z0 z! J$ E        strStartOfLine = strEndOfLine + 1;, t. b" ?1 s7 C0 ~, ]
        }
    - i6 ^' i& v+ c! K; R}</P>
    : y/ D% c6 ^9 S4 ?' t" R
    0 |( G7 p; `* }4 S8 G0 J% r1 N+ m) }/ X<P>
    3 D& K2 y; h0 H- H% r//------------------------------------------------------------------------------ ^' o! ]& X9 f/ e. k! D) T
    // Name:
    3 q' i* p% W7 S( Y0 G5 A// Desc:
    # K+ I2 V9 l, O" u9 Z3 g- s3 |//-----------------------------------------------------------------------------
    ( k! [) D; w( T0 }) m; d. I; QHRESULT CMazeServer::SendPacket( DWORD to, void* pData,
    - k5 F1 t6 Z2 J4 ^+ m! K                                 DWORD size, BOOL reliable, DWORD dwTimeout )5 c% N1 ~' r6 w" }8 e' B
    {0 h+ X  D( B' ]2 m
        // Chance of forcing any packet to be delivered reliably
    # l+ l5 D& y* Z# s# B" W5 j/ Q    if( m_Rand.Get( 100 ) &lt; m_dwServerReliableRate )
    $ w" F# z! Q. j' \# v# L        reliable = TRUE;</P>
    ( G. N- T2 R) |<P>    return m_pNet-&gt;SendPacket( to, pData, size, reliable, dwTimeout );3 a: X/ r5 k7 C5 F: l& k
    }</P>2 N3 I& ~  X  D1 Q5 z( n. m

    ' @; U( o0 W5 y& _& r<P>6 N0 f& c! I- d: ~1 ]3 E
    //-----------------------------------------------------------------------------
    ; c' I. o: M, h4 [// Name: ( D7 G: y, r) R& K
    // Desc:
    & }- d) R6 F$ c6 f* g//-----------------------------------------------------------------------------
    4 b% z: J* |% m# q) lvoid CMazeServer::SendConfigPacketToAll( ServerConfigPacket* pPacket )
    7 X7 j5 t( [# n# h1 K4 ?+ j{$ }- O' R7 |! k* r" r
        // If we're up and running, then send this new information to all clients3 }8 Q: U- _5 y+ K; A0 O
        if( m_pNet )% j0 _, Z* v; n* ]& T. H5 R& t
        {
    + Y( w- y$ x. ^  P' Z9 ]% K        //Use the AllPlayers ID3 o, D6 A! b% J9 n' M! H% o
            SendPacket( DPNID_ALL_PLAYERS_GROUP, pPacket, sizeof(ServerConfigPacket), TRUE, 0 );
    5 E* D6 K7 a' Q    }2 a' C( U/ y7 ^0 @9 S1 y" ]
    }</P>. y) r  d& _3 ~( a8 y2 U; x1 F

    & s0 t+ w/ l6 P  [* \1 _" D<P>
    6 k$ M4 Q( U7 j7 V3 ~9 `4 S//-----------------------------------------------------------------------------
      b0 h' }* @+ O' @/ @9 o, t// Name:
    ) k# }$ {1 l+ w0 f1 ^// Desc:
    + m/ Q, z' t4 c; t( Z6 A//-----------------------------------------------------------------------------
    + r: q* A8 J. K4 @# Bvoid CMazeServer::SetClientReliableRate( DWORD percent )2 G. m0 O3 g  S/ V4 w2 F
    {
    % ]. V$ Q$ a/ T- _  G2 c' O7 ~    // Update client config, and build packet containing that data! ]' ]- c# i  h! v1 ^; Q0 K6 f! ~1 U+ g/ o
        m_ClientNetConfigLock.Enter();
    . M0 T& o0 W% z, U* h    m_ClientNetConfig.ubReliableRate = BYTE(percent);
    , {; P$ J- \+ j3 ]; q    ServerConfigPacket packet( m_ClientNetConfig );
    0 }! }2 n1 n8 r8 r9 o# c    m_ClientNetConfigLock.Leave();</P>/ e. H2 _  d  K/ X% C3 j5 C1 ?) ]
    <P>    SendConfigPacketToAll( &amp;packet );. {' }: r& d/ o" B
    }</P>
    , D; c2 |1 N8 A8 W( E5 a/ S
      t% i5 @* n- @- N/ ?+ W<P>$ M6 N  n) C3 ~* s
    //-----------------------------------------------------------------------------
    : Y. I% k6 K9 @4 ^0 @// Name: ' I) B" Z1 k/ ]  C. U
    // Desc: & s2 x. s- L; \+ t5 r) {! S% K
    //-----------------------------------------------------------------------------4 r% `+ C# V+ F' c+ X0 c( `* U
    void CMazeServer::SetClientUpdateRate( DWORD rate )% v0 k9 i$ q6 _% R
    {
    - N6 X7 P9 @9 r( p    // Update client config, and build packet containing that data
    6 Y6 Y9 `' J  x- d. s' v    m_ClientNetConfigLock.Enter();
    ! c/ ?" E' s/ G" z    m_ClientNetConfig.wUpdateRate = WORD(rate);
    $ u3 ~( @. Z2 E7 h$ T' |/ n    ServerConfigPacket  packet( m_ClientNetConfig );
    9 r8 z; |/ J* ~! Q4 O; ^4 u  S    m_ClientNetConfigLock.Leave();</P>
    % p, \( p" Y. |6 x<P>    SendConfigPacketToAll( &amp;packet );; P( t/ M' `) C; r
    }</P>
    : P0 }* W2 v) g, B- s( A
    " L2 k+ b$ j8 z  b<P>  n$ g# x0 Q' v) m" n0 k
    //-----------------------------------------------------------------------------
    * }- P0 J, i4 c5 h; B3 k; h// Name:
    $ }; m8 K7 K9 A* Z/ b% }2 |/ s+ W2 o// Desc: ' l5 K) }: D: n+ I8 a
    //-----------------------------------------------------------------------------
    . @1 E! {4 d/ t4 o8 W% F0 D2 Avoid CMazeServer::SetClientTimeout( DWORD timeout )
    : O& E0 C$ [# G9 X# g, Y) f{3 ~8 h$ F" z3 H! m
        // Update client config, and build packet containing that data
    / q1 {# r) e3 a    m_ClientNetConfigLock.Enter();* k' [/ C% K- H5 J5 [
        m_ClientNetConfig.wTimeout = WORD(timeout);
    * I3 w5 ^! F, v# ]8 X9 p  g    ServerConfigPacket  packet( m_ClientNetConfig );
    + M( g2 K' l8 B, Z- Z- i4 u    m_ClientNetConfigLock.Leave();</P>
    ) n* @8 \2 d" n! t8 Z3 ~$ W8 M<P>    SendConfigPacketToAll( &amp;packet );
    . l0 `( r% I4 N% d! J- p}</P>  J( U; F; {: v3 a+ P
    ! _. Y% Y$ d. x0 V; t' u+ U
    <P>' O( m. A* ]* y
    //-----------------------------------------------------------------------------
    ; U4 S/ F0 f0 H// Name:
    & k, G4 J& J# O3 o& _, ?3 s; M// Desc: * M  R: s1 J% Y4 i
    //-----------------------------------------------------------------------------, ~0 m2 v: h" \) T
    void CMazeServer::SetClientPackSize( DWORD size )# q, ~8 ]. H& u* x- S( O1 |" a' z4 |
    {2 C1 D) b  H' Q% c; n6 X
        // Update client config, and build packet containing that data
    : r, L' l" o6 K, {$ t    m_ClientNetConfigLock.Enter();
    ; h. p+ f# o  t5 ~1 {/ F2 N    ! V/ K& R$ g' |4 [
        m_ClientNetConfig.ubClientPackIndex++; //Increase index and verify location in array.! O& z9 ]! S; F
        if(m_ClientNetConfig.ubClientPackIndex &gt;= PACK_ARRAY_SIZE)   / C3 R& |. V5 M; w" G5 s: P0 j
            m_ClientNetConfig.ubClientPackIndex = 0;</P>) m& Z2 T1 \6 g2 `2 I8 D8 T
    <P>    m_ClientNetConfig.wClientPackSizeArray[m_ClientNetConfig.ubClientPackIndex] = WORD(size);! a  N' x  S/ j$ q) @3 Z3 C
        ServerConfigPacket packet( m_ClientNetConfig );" G4 z' ?- ?) `1 z
        m_ClientNetConfigLock.Leave();</P>
    * p  n6 J2 v: W+ O) {<P>    SendConfigPacketToAll( &amp;packet );3 s* ~9 U6 ?7 ^' Q: D7 u) p  e
    }</P>1 d# z6 L& G& f6 R0 s+ q! h

    $ F- ^! ^  a9 |) k. P9 G, N2 E) a<P>
    ( S+ g' v* c% Z8 f, ?0 l//-----------------------------------------------------------------------------1 V; d9 m. s% p6 U9 g
    // Name: * }* \0 O* @; V# f
    // Desc: 1 I3 C1 N. F. u5 M
    //-----------------------------------------------------------------------------' H, ?" S' W2 T% _& g1 w3 Q: Q9 n
    void CMazeServer::SetServerPackSize( DWORD size )
      w' h# {( `! Y4 y9 H2 ?{) l& s" m2 A0 X6 w3 X; |
        // Update client config, and build packet containing that data
    5 c0 [8 d0 C0 t) z    m_ClientNetConfigLock.Enter();4 N) x8 B# [$ o9 Q, j
        * l7 B/ }8 Y& w! c' k, |6 S$ K& A
        m_ClientNetConfig.ubServerPackIndex++; //Increase index and verify location in array.
      @6 h* W" m! k6 m0 z, F# e    if(m_ClientNetConfig.ubServerPackIndex &gt;= PACK_ARRAY_SIZE)   
    6 d( J# z( o6 L& j5 C/ ^# X        m_ClientNetConfig.ubServerPackIndex = 0;</P>0 {, q+ `) H" R4 Z
    <P>    m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex] = WORD(size);  `. r1 O- [1 H: u$ C8 l
        ServerConfigPacket packet( m_ClientNetConfig );
    $ ~# Q4 C: N" C, E    m_ClientNetConfigLock.Leave();</P>9 r$ U* `9 D( D  \9 Q; q. }
    <P>    SendConfigPacketToAll( &amp;packet );4 o3 M$ A/ B* `
    }</P>
    ( I. I) I" C' W2 v  f<P>' B0 v9 ]9 x% r( Y. u9 e( \7 ?
    //-----------------------------------------------------------------------------
    8 i( n+ S- j: Z  t  Z  `. p, P// Name: 7 c1 I# ]7 v+ m" q5 ^
    // Desc: 5 E3 [. g7 @/ i: {
    //-----------------------------------------------------------------------------4 P6 ?7 c' V: R4 ?
    void CMazeServer::SetClientThreadWait( DWORD dwThreadWait )
    : X( @3 ]# K( X3 v- b: e{
    $ K7 a/ Y: _8 e    // Update client config, and build packet containing that data' f* R, r; f+ Q  M" A" W0 S
        m_ClientNetConfigLock.Enter();# `/ o  ?/ e* v
       
    + s" _* l: F  n    m_ClientNetConfig.dwThreadWait = dwThreadWait;
    0 n3 g9 Q3 d, G9 m( a" Y. T( D% E    ServerConfigPacket packet( m_ClientNetConfig );% |. d7 I: D$ d( b. ~- m' ~
        m_ClientNetConfigLock.Leave();</P>
    0 u/ D; y, D4 D& u' l<P>    SendConfigPacketToAll( &amp;packet );
      F+ w4 Q9 L+ M# |, |6 g}</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-14 11:09 , Processed in 0.597608 second(s), 50 queries .

    回顶部