QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 3840|回复: 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>
    - d$ R& b1 e0 `9 p' |' b<>// File: mazeserver.cpp# g+ z% K; x. V6 Z! L
    //
    * ]* q  B' T# [& A! f4 Z0 y  w* U// Desc: see main.cpp/ u4 I3 q' l/ J! A6 ]
    //9 t) G% C3 l. `
    // Copyright (c) 1999-2001 Microsoft Corp. All rights reserved.7 W; ]* M" a, o/ g) D
    //-----------------------------------------------------------------------------
    0 O! ?$ }/ A; g% p& H! b#define STRICT. p, A" r4 [2 a
    #define D3D_OVERLOADS+ ]7 m' i5 `/ f
    #include &lt;windows.h&gt;
    4 p. w- p5 u" n) x: u#include &lt;d3dx.h&gt;
    ; r+ }3 O# |2 O1 c4 _#include &lt;stdio.h&gt;: Y# `/ o6 G3 P4 j
    #include &lt;math.h&gt;8 @5 n0 t+ j- o1 W/ u8 U# X
    #include &lt;mmsystem.h&gt;
    8 _) @0 z- g- D1 ^: y#include &lt;dplay8.h&gt;
    ' B. ?7 e( Q: ]#include &lt;dpaddr.h&gt;
    9 m* g9 A/ p3 \  E: |: f#include &lt;dxerr8.h&gt;$ B1 T2 N3 M9 c0 F
    #include "DXUtil.h"6 Z5 k* h5 y4 s) e
    #include "MazeServer.h"
    ( T" E' ~* M# E1 h: f" `5 R#include "ackets.h"+ e2 O2 I" v( D' o, U/ U# P2 p
    #include "Maze.h"- z+ a+ F8 w2 L0 x' Z3 J6 m
    #include &lt;malloc.h&gt;
    ! n. C5 c% p3 k9 y7 Q& r" p#include &lt;tchar.h&gt;</P>
    , D7 [- \+ ?- E0 ?; Z' M$ i) r( q/ w- W; \! E; `
    <>//-----------------------------------------------------------------------------0 x$ F  E; H) N. ?7 M7 K
    // Name:
    4 i- W" ^0 i$ g; d( g// Desc:
    / L6 F& E9 w  x+ A& g' [//-----------------------------------------------------------------------------/ `+ E- J9 u: M0 \' p, `4 t6 ]; D; I
    CMazeServer::CMazeServer()* c7 L/ m, J" |( j9 {$ J4 Q
    {5 a7 b4 g' G8 M/ D6 H- L( e
        m_dwPlayerCount         = 0;1 O/ Q) K, R9 j+ s
       
    0 Z: K# w. R4 A2 b3 [  B  W    m_wActiveThreadCount   = 0;6 \8 L7 G6 H5 x0 U/ S4 v- V
        m_wMaxThreadCount      = 0;! ]( M  d3 P9 d: B' G* |
        m_fAvgThreadCount      = 0;- M8 _5 f5 z- B
        m_fAvgThreadTime       = 0;. P4 J/ U) Y& _7 a
        m_fMaxThreadTime       = 0;</P>
    4 H3 |) U% J  A<>    m_dwServerReliableRate  = 15;
    + c- a+ f& y2 i  h1 N6 p( [9 d, ^    m_dwServerTimeout       = 150;( j7 ~" N+ S: r: D" J
        m_dwLogLevel            = 2;( D  b9 f9 E) H& K( a
        m_pMaze                 = NULL;</P>. b6 s% b; _' R
    <>    m_ClientNetConfig.ubReliableRate = 15;) }$ h/ q: x$ {2 j2 G+ J
        m_ClientNetConfig.wUpdateRate    = 150;" T9 K  R: p0 O/ {$ ~* \
        m_ClientNetConfig.wTimeout       = 150;</P>
    2 n" T5 j* w6 J# y<>    m_ClientNetConfig.dwThreadWait = 0;</P>5 g: O+ J  A3 B
    <>    m_ClientNetConfig.ubClientPackIndex = 0;& S5 W5 r4 a3 J2 R3 ?) T. R9 c; r+ i
        m_ClientNetConfig.ubServerPackIndex = 0;8 M& ]: Q( P: a" \+ c
        for(WORD x = 0; x &lt; PACK_ARRAY_SIZE; x++)3 u  N9 c: S4 i
        {7 e# G3 j* u  a! B: |) F
            m_ClientNetConfig.wClientPackSizeArray[x] = 0;
    # \0 Q* ]: y( I8 A. ^        m_ClientNetConfig.wServerPackSizeArray[x] = 0;- {5 T: {; o) ~# D+ [' Y
        }2 e6 h/ N; M* X+ G/ L
    }</P>
    # m. e/ a+ q3 L( j' ~
    3 I9 B) l- x! j4 Q<>
    4 W+ ]8 g' a) [( T0 H  c3 w//-----------------------------------------------------------------------------/ l( C8 f4 |5 g
    // Name:
    / C; @7 Q/ a2 ?/ k5 }4 r0 [// Desc:
    9 O1 b# E, _2 l. p6 ]" ]: ?$ V& w! C//-----------------------------------------------------------------------------% O8 R8 ^: ^: V6 o
    HRESULT CMazeServer::Init( BOOL bLocalLoopback, const CMaze* pMaze )5 ?' V6 c4 S3 N8 {" [* p
    {
    & q! G& Y2 k  Z8 }$ C- r% X( _8 W  o  d    m_bLocalLoopback = bLocalLoopback;, O: S) a6 j$ D% o" i2 ]! Z# ?% Y
        m_pMaze = pMaze;( c( [; s1 a, s$ B# z. s) o* k
        if( m_pMaze == NULL )4 N  i* B$ N0 u3 D, ^$ H
            return DXTRACE_ERR( TEXT("aram"), E_FAIL );</P>
    ! c5 q, I7 I$ z4 O/ a- @* |$ d! `4 ~<>    // Grab height and width of maze
    ( o: y% {+ A; R! ?" c* x: @    m_dwWidth = m_pMaze-&gt;GetWidth();
    ; R1 \0 w! A- ]6 A" V( t    m_dwHeight = m_pMaze-&gt;GetHeight();</P># q* U9 W1 w( Z- B! F( V
    <>    m_ClientNetConfig.dwMazeWidth  = m_dwWidth;3 d9 z9 E) J4 F0 C
        m_ClientNetConfig.dwMazeHeight = m_dwHeight;</P>
    ) A3 s' i0 c: M7 X$ x' j8 g<>    // Validate size. Must be a power-of-2 times LOCK_GRID_SIZE. Compute the shifts.
    ) ~& }+ w3 ~; C" ]8 N5 h* o    if( m_dwWidth &gt; SERVER_MAX_WIDTH || m_dwHeight &gt; SERVER_MAX_HEIGHT )
    6 v8 w6 V$ o& _. n7 v6 c* f1 i        return DXTRACE_ERR( TEXT("Maze height and width need to be less than 128"), E_INVALIDARG );
    4 u5 \6 i( V* n1 e# l    if( (m_dwWidth % LOCK_GRID_SIZE) != 0 || (m_dwHeight % LOCK_GRID_SIZE) != 0 ), d+ c4 |8 N" M8 E# j7 r- Z
            return DXTRACE_ERR( TEXT("Maze height and width need to be divisable by 16"), E_INVALIDARG );</P>7 \( Y" ^8 Q' W+ V
    <>    DWORD scale = m_dwWidth / LOCK_GRID_SIZE;
    ! B' z" \) Q! s) K    m_dwMazeXShift = 0;0 K: _  |0 f; ~  g, u0 y
        while ( (scale &gt;&gt;= 1) ): s, {9 [& D* U7 o9 a! N$ J' i! q) j
            m_dwMazeXShift++;</P>  U" I) e5 l: x5 L: h
    <>    scale = m_dwHeight / LOCK_GRID_SIZE;
    % W$ i1 J, Q3 w/ X$ {, k5 x    m_dwMazeYShift = 0;
    4 ~7 w; o; \9 W2 J* w; x) A( Q    while ( (scale &gt;&gt;= 1) )+ t5 L  }/ P! N; C' i3 ~  _9 V0 g4 `5 L
            m_dwMazeYShift++;</P>
    3 w7 X5 [/ J/ w' u<>    if( ((DWORD(LOCK_GRID_SIZE) &lt;&lt; m_dwMazeXShift) != m_dwWidth) ||
      o6 G8 c, z* r4 ]        ((DWORD(LOCK_GRID_SIZE) &lt;&lt; m_dwMazeYShift) != m_dwHeight) )
    / l. ?( z& v7 |6 p' U        return DXTRACE_ERR( TEXT("Maze height and width need to be power of 2"), E_INVALIDARG );</P>% ~, i. K6 L/ g- @
    <>    // Initialise the player list
    5 b  g9 ~! f1 L" g    ZeroMemory( m_PlayerDatas, sizeof(m_PlayerDatas) );7 E, n8 G1 Y% B7 f! ^! K) ?: S
        m_pFirstActivePlayerData = NULL;! k& W$ N' ~2 `* A: T+ G4 C) Z0 H+ S% Q
        m_pFirstFreePlayerData = m_PlayerDatas;& j% Q- U% M6 A1 u! j% ~9 o, E5 z
        for( DWORD i = 1; i &lt; MAX_PLAYER_OBJECTS-1; i++ )7 [( }  e9 Z- ^6 y, s
        {. |9 o. \4 \3 H/ T
            m_PlayerDatas.pNext = &amp;m_PlayerDatas[i+1];
    + U4 c" h$ z4 m, d% Z        m_PlayerDatas.pPrevious = &amp;m_PlayerDatas[i-1];
    - L, K3 G1 g# q0 P, Z6 j0 r/ G# p    }</P>' r# K4 o0 w% s1 K" t7 l
    <>    m_PlayerDatas[0].pNext = &amp;m_PlayerDatas[1];
    6 P) C# T* h* E2 ^    m_PlayerDatas[MAX_PLAYER_OBJECTS-1].pPrevious = &amp;m_PlayerDatas[MAX_PLAYER_OBJECTS-2];! Q& a4 m% d7 N6 C/ ?+ n% h
        m_dwActivePlayerDataCount = 0;! Z# @: ?2 e& t" ^# _
        m_dwPlayerDataUniqueValue = 0;</P>+ F$ r: R8 f/ z, f2 u3 X+ }3 R% E+ w
    <>    // Initialise the cells
    0 y  P3 f) f3 C0 [, G    ZeroMemory( m_Cells, sizeof(m_Cells) );9 D3 i% [9 U5 H
        ZeroMemory( &amp;m_OffMapCell, sizeof(m_OffMapCell) );</P>1 d& X/ a5 w6 {" ~8 @
    <>    return S_OK;- y$ E$ h, Z) p
    }</P>  W) u, A) a: k. P( R
    7 B; I4 d4 q6 l' ]: {, x* E
    <>+ ~- @. H' V" n2 Z$ A# Y
    //-----------------------------------------------------------------------------
    3 ^& S$ ], r9 ]/ E// Name: - `% s9 b& u4 P/ G2 X
    // Desc: " l% c, y/ B: J- K% C, @; p
    //-----------------------------------------------------------------------------7 ]6 G! C7 |8 ^( ?! i
    void CMazeServer::Shutdown()
    # T/ \6 J/ x2 a  _{
    + R( k1 ^! R' }* c+ E}</P>
    ) V9 U5 a2 [! a+ u8 ~! s7 V8 F9 X% @$ e5 O5 f
    <>1 ?7 p2 h! x, t3 h
    //-----------------------------------------------------------------------------
    9 I3 Z7 W/ [% Q& Z% V7 Y  z- C: z' s, q// Name:
    " y2 v) [' b6 a: J// Desc:
    8 o0 K! x4 W6 F, ~3 e5 N/ b//-----------------------------------------------------------------------------$ D  q' w8 C- U' i, v1 \# K
    void CMazeServer:ockRange( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )
    - m  c# o9 J3 F1 a$ o% ?{
    ' B9 K% |" v8 y, p& v    m_LockGrid.LockRange( x1&gt;&gt;m_dwMazeXShift, y1&gt;&gt;m_dwMazeYShift ,! i9 ^& l$ v7 U( E! _. S; n
                              x2&gt;&gt;m_dwMazeXShift, y2&gt;&gt;m_dwMazeYShift );1 B( _# a, @- ?7 H, d
    }</P>5 g' J' s; r3 ?9 W. q: M8 I7 @
    9 }, X, U7 ^( m7 p  w: ^
    <>
    7 x) g$ T* D& e0 o/ S7 o% t8 E4 j//-----------------------------------------------------------------------------8 ^5 m/ {" C0 }* g$ [8 g2 B
    // Name:
    % }* M6 {8 @4 S3 t; Z" s8 N3 i// Desc: 5 R% T+ Q  Z& e5 V( L
    //-----------------------------------------------------------------------------
    - Q; s4 k* @* s% s/ @1 qvoid CMazeServer::UnlockRange( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )9 [, j) [8 u7 E" _0 @
    {
    0 Y" B  `6 J# O# k3 t    m_LockGrid.UnlockRange( x1&gt;&gt;m_dwMazeXShift, y1&gt;&gt;m_dwMazeYShift ,
    ( [$ M- T! K7 Z( I* I) y- b! Z9 d* Y                            x2&gt;&gt;m_dwMazeXShift, y2&gt;&gt;m_dwMazeYShift );( I# x% X. _5 D2 i5 h6 s) A1 @
    }</P>
    , V# p1 Q9 P0 |8 S2 s9 o- s: U1 J* {' N; Q" |/ E) C
    <>
    " q7 J+ n& D. h+ X! W% P//-----------------------------------------------------------------------------
    7 S  Q( O) s' F2 d% x// Name: . c8 P, R$ L2 M  O8 W' ~) m5 F& T+ M
    // Desc: # Q) B8 D$ u" r" g( ]& \- P/ u
    //-----------------------------------------------------------------------------8 V1 [5 j6 X8 }1 s
    void CMazeServer:ockCell( DWORD x, DWORD y )6 f5 t6 V3 k* a% N- I
    {
    + m$ f; y- N7 B6 m0 V    if( x == 0xffff )
    ( _4 {2 y, f9 H) C4 o        m_OffMapLock.Enter();) U4 p; J) M. W
        else
    " w' `7 X! i& L+ o% [        m_LockGrid.LockCell(x&gt;&gt;m_dwMazeXShift,y&gt;&gt;m_dwMazeYShift);
    ; `9 `: _+ I8 N7 z8 X2 u7 q% ?}</P>  S9 `8 x( u  U9 D% L

    * n5 N: S( N( O9 ?% |) X<>7 B8 C  q/ p" _& y# V2 U" b6 j- A
    //-----------------------------------------------------------------------------* F! @3 [# C8 L. ?. J4 l
    // Name:
    - B7 {+ Q* E# H// Desc:
    3 q9 |6 f- p" H" j0 t//-----------------------------------------------------------------------------
    , T" m- P2 e' W' \0 v+ k6 Jvoid CMazeServer::UnlockCell( DWORD x, DWORD y )0 y7 T; s! x2 |8 V1 k& p
    {
    2 i( t; q* O! v" ?    if( x == 0xffff )
    * ?$ X  [* _$ [# n        m_OffMapLock.Leave();- }5 l/ |* s7 A# v# x6 x1 y
        else
    & \1 J, T  D1 q9 u" p        m_LockGrid.UnlockCell(x&gt;&gt;m_dwMazeXShift,y&gt;&gt;m_dwMazeYShift);9 a7 p) W6 W" B% b. }7 {" O/ b& L
    }</P>& D5 l/ g$ n/ V8 Q

      j: {$ ]+ F+ g  l6 W; ^/ l$ g5 ~) R<>4 n; d, X/ h" [/ v  ]6 w  P# N* a+ d
    //-----------------------------------------------------------------------------8 P; H. Y4 ?" h
    // Name: ' D/ X, s: q3 U) Y' N( y) l5 `' H
    // Desc: " i' X7 D( F2 a; k# @. N/ y
    //-----------------------------------------------------------------------------
    3 w9 ^4 I' f/ r$ y% L$ Wvoid CMazeServer:ockCellPair( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )
    * m% \' F  G  N7 E{
    ; M# R& B# Q  w) o- H* K# m7 ]    if( x1 == x2 &amp;&amp; y1 == y2 )
    : m$ p" o7 l' v. `6 }! g- \    {
    2 S% T; k3 d- j( ~        if( x1 != 0xffff &amp;&amp; y2 != 0xffff )! P" f7 ^4 L  Q& ~* |, O
                LockCell( x1, y1 );. `7 D9 b( z# `2 U+ {2 N: s
            else3 D) h/ r. U8 e
                m_OffMapLock.Enter();</P>
      T4 O4 k& l7 B2 k<>        return;
    , Q6 S1 ~0 Y6 K. z    }</P>/ c( a+ \; V; L# o& {/ G" g
    <>    DWORD x1shift = x1&gt;&gt;m_dwMazeXShift;5 p3 |+ [9 v$ s6 b3 u
        DWORD x2shift = x2&gt;&gt;m_dwMazeXShift;# ~* W. l# L! n
        DWORD y1shift = y1&gt;&gt;m_dwMazeYShift;( _: C$ s4 t3 i# A9 r
        DWORD y2shift = y2&gt;&gt;m_dwMazeYShift;</P>
      h3 h+ I. j+ t( a+ t0 |! k<>    if( x1 == 0xffff )3 V. i+ f( ^/ o0 q
        {+ v; {$ ?: W; W; j* J
            m_OffMapLock.Enter();' s( v$ y$ Z& `' S/ t7 @6 X3 c4 S
            m_LockGrid.LockCell(x2shift,y2shift);
    / r- ]6 ?- p! E* V$ m9 N2 u    }5 U5 ^, }; W; q* d3 a+ Y% {
        else if( x2 == 0xffff )7 o; {& O! t7 a4 k6 m" a
        {
    8 u* g, f& E: `7 Z: ^% P        m_OffMapLock.Enter();+ x/ ]0 m8 f( m+ k+ ?3 n0 O
            m_LockGrid.LockCell(x1shift,y1shift);4 Z) I0 t3 |, r& g, c
        }" X4 K6 I  v& T% b# H1 P. g) l
        else : o$ M2 d8 _; K$ W; E  V7 g
        {
    9 S# `" V9 l! y  p0 q$ h        m_LockGrid.LockCellPair(x1shift,y1shift,x2shift,y2shift);" l+ D; x3 Z& N4 T+ B9 `: U
        }
    . f& Q3 y% [8 \" `4 K}</P>! \4 U. J) i# o3 s9 Y

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

    - L8 q) w' D' q: r<P>
    7 |, S) i0 S8 `//-----------------------------------------------------------------------------
    : `; A0 |8 g3 r, J$ |+ z// Name: 3 Q/ ?* f6 G. G& B# A
    // Desc:
      o* R8 O- t. b+ R" @! a/ E6 s//-----------------------------------------------------------------------------9 ^  z3 t. p: p8 U3 p% @
    BOOL CMazeServer::IsClientVersionSupported( DWORD dwClientVersion )
    ' l$ `: U6 x% r8 e{
    1 p3 p( J8 ^$ ?" ?. ?4 t1 R0 {    switch( dwClientVersion ), N# u# r( A, j3 ^4 F
        {
    ' N' W# J6 @: g2 T' ~$ T0 @        case 107: // only v107 is supported
    * `+ ?/ H' d3 ?6 X            return TRUE;0 ~0 B$ l% a3 l  C/ f+ O" [
            default:* g* o% n6 M2 g( ^
                return FALSE;; z+ M+ q% b2 p$ O8 w
        }1 B, e( F- D6 o( e/ T" S& g
    }</P>7 [" n9 g3 r  m9 e( B! B( T1 D
    : V5 \; M4 Y% M# A
    <P>
    $ @; f6 f6 \7 u) a# K( e" p//-----------------------------------------------------------------------------" K! q- ]) z8 U5 F; O! a6 D1 ^
    // Name: 1 V) W* @8 Z& U& k2 _/ a) K: d' V% N
    // Desc:
    . h: [# k9 R5 W: C& C//-----------------------------------------------------------------------------
    ) i+ y9 V' e: d( fvoid CMazeServer::HandleUnknownPacket( DWORD dwFrom, ClientPacket* pClientPack, DWORD size )4 }( r7 _$ E: C3 i$ X) t8 l8 E, ~0 {
    {0 y) Y9 R1 C& b+ c7 G
        if( m_dwLogLevel &gt; 1 )2 y/ N& R$ r5 o
            ConsolePrintf( SLINE_LOG, TEXT("ERROR! Unknown %d byte packet from player %0.8x"), size, dwFrom );</P>0 j/ @* w. j% {6 ]6 r0 g) S
    <P>    m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );
    " L$ X- a# _, |- M% j}</P>
    8 y1 S8 o) y7 l% m$ F& a5 \
    0 U1 r! @! p; q<P>
    ' U# {( }" u" A1 H//-----------------------------------------------------------------------------
    / e7 ~/ X- h- j7 x// Name:
    7 {7 X8 j- I: [7 h- c// Desc: ' `9 i  y+ X, _& ^, G
    //-----------------------------------------------------------------------------& j9 j1 @5 B6 S1 `, Z
    DWORD   CMazeServer::IDHash( DWORD id )
    4 A- C$ x7 L  D' @{
    & q9 B+ M( W' S& j! k4 {    DWORD   hash = ((id) + (id&gt;&gt;8) + (id&gt;&gt;16) + (id&gt;&gt;24)) &amp; (NUM_ID_HASH_BUCKETS-1);: p0 B- Y6 S/ h8 M+ ^0 j
        return hash;, `7 V: C. w) x! V" h
    }</P>
    5 r7 G- E/ w; \1 s6 j0 K! ?! D8 t! q; v, b1 H3 G" b
    <P>
    * u# k! E4 z- v9 L( t4 D+ ^7 F2 \//-----------------------------------------------------------------------------: Q& G5 C8 y3 Z0 j
    // Name:
    5 ?& s7 j4 ]' r" H1 e4 Y- B) B// Desc: ! U) g0 Y! ?8 V+ ~# I- R  ^' _
    //-----------------------------------------------------------------------------
    * j0 f. j# B% r) Z. Cvoid CMazeServer::RemovePlayerDataID( PlayerData* pPlayerData )
    - M* t4 j/ o: u{
    ! x  t, r4 y  @8 v( [* x    // Hash the ID to a bucket number: Y0 S% Y& g# {1 p7 Q. w
        DWORD   bucket = IDHash( pPlayerData-&gt;NetID );</P>
    " K% e* `$ m  J7 c+ p+ a  C. E# e; J<P>    // Lock that hash bucket9 a$ F- ~% \$ n) \/ x
        const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;+ z" I, ]" G( [, g  k" z
        m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>- C( h' W" M( N  h
    <P>    // Loop though players in bucket until we find the right one
    ! n4 M7 E2 b) `    PlayerData* pPt = m_pstIDHashBucket[bucket];
    8 V2 k/ |) I# M    PlayerData* pPrev = NULL;
    ! i& t6 Z4 c4 x; ^$ x    while( pPt )
    4 {# }" [3 U# E6 O2 K4 E1 J  h1 X    {; `/ M% \( B' n5 o7 f5 U; N0 w
            if( pPt == pPlayerData )
    % A7 v. q, A! i3 {; e            break;
    - c1 R, v* [( ^: C; Q        pPrev = pPt;+ M1 o0 P3 v# E& t
            pPt = pPt-&gt;pNextInIDHashBucket;
    ! ?  I$ G  e4 M8 K; c    }</P>/ n9 a) m) w' Z' H! @3 d3 ^" m
    <P>    if( pPt )
    . r* x) U# ~- N8 F    {& S+ i" W' N5 t* w
            if( pPrev )
    6 {( F# Z2 L  J( [8 B& h' r& {            pPrev-&gt;pNextInIDHashBucket = pPt-&gt;pNextInIDHashBucket;* p. |9 z4 S2 x
            else
    ) E- d, E# L- r* d) h6 C% E            m_pstIDHashBucket[bucket] = pPt-&gt;pNextInIDHashBucket;
    ( C3 o5 ~) `8 W% H" f* A7 c8 W, E        pPt-&gt;pNextInIDHashBucket = NULL;
    / \' B) D9 O8 l# y8 g2 Q    }</P>
    & `: B( j. Q/ ^7 H0 d. F" B<P>    // Unlock the hash bucket
    2 O7 w$ [* S1 X0 Q! G* z) C% ?3 _* S    m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();
    & n4 w( u, o# L}</P>
    - z6 S% Y0 ^" P6 a1 a. |& \8 m1 z2 W3 `" P' d$ |
    <P>$ U, L2 ?$ K& J2 ?# @8 @) \
    //-----------------------------------------------------------------------------  A. D2 j2 G5 r: i# z
    // Name:
    # [2 i# M, i( s; a// Desc: 6 d" J& F2 P6 P8 }2 I. ^
    //-----------------------------------------------------------------------------8 M0 ?$ `; x/ `$ d% D
    void CMazeServer::SetPlayerDataForID( DWORD id, PlayerData* pPlayerData )
    1 z3 L+ d" ^1 f+ m/ f! c{
    ; }2 [* \! o  p5 B5 \+ N+ `  L" r    // Make sure this player isn't added twice to the m_pstIDHashBucket[]
    " n* V5 W* t; q3 E1 n7 S# c% ]    // otherwise there will be a circular reference9 f. B, d8 S6 i. |
        PlayerData* pSearch = GetPlayerDataForID( id );
    2 ]( r! b) u% X: M    if( pSearch != NULL )
    % e/ B4 @+ a3 d* h9 ~. p2 a" l        return;</P>9 o2 R  N3 ?9 Y, B* H+ I9 P) i; b
    <P>    // Hash the ID to a bucket number, O1 `( h2 d' R, Q
        DWORD   bucket = IDHash( id );</P>
    & ?1 {* c9 A6 Z4 d<P>    // Lock that hash bucket
    3 I8 X9 K+ D! g, n4 E" L7 U) Q: S+ f    const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;* N! d0 p* f- a
        m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>: F* y, A5 T! n
    <P>    // Add player onto hash bucket chain+ G0 m' W$ g) V
        pPlayerData-&gt;pNextInIDHashBucket = m_pstIDHashBucket[bucket];) O! Z0 g' i: Y- _9 G) Q9 W
        m_pstIDHashBucket[bucket] = pPlayerData;</P>
    - x& X, R0 A9 ?1 I5 i' h! i0 ?<P>    // Store net id in player
    2 n1 q3 u0 y5 x) i. H* E5 D" h0 a    pPlayerData-&gt;NetID = id;</P>
    * l; d. m: G* d$ G9 k<P>    // Unlock the hash bucket
    3 p' {" H6 u( Y' S6 B6 d5 ]    m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();
    5 Z1 z0 Y$ |! U# X4 A}</P>
    1 ]8 U1 t- f0 Y2 d( z+ d: L9 a$ o* A; b
    <P>5 j7 v' p9 n" Z
    //-----------------------------------------------------------------------------+ w+ ]) R( a% G; H: Y: o
    // Name:
    0 l1 F& ~) r5 c' {1 N/ s2 s+ x// Desc:
    9 V: u  r' p1 x) G6 a9 I) N2 V//-----------------------------------------------------------------------------+ n' M% ~! f! x2 ]: Z# a
    PlayerData* CMazeServer::GetPlayerDataForID( DWORD id )9 S% r. E& d& c  |
    {9 ~! |: i" ~/ T% N1 {
        // Hash the ID to a bucket number
    - `/ q( y) t$ ^    DWORD   bucket = IDHash( id );</P>7 Q0 `% O0 T/ r0 l9 h
    <P>    // Lock that hash bucket% S% O' k( n$ H- x' A5 y
        const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;- z% k6 V- J) }. m
        m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>
    6 U8 H5 P; _0 ~* }; N7 O<P>    // Loop though players in bucket until we find the right one) ]' ^! i9 m6 D8 x+ A. S$ h
        PlayerData* pPlayerData = m_pstIDHashBucket[bucket];
    " T5 D* {- g+ P$ y    while ( pPlayerData )  x2 |! T$ g8 j/ B1 j8 A
        {
    ! e7 r2 f, s6 T        if( pPlayerData-&gt;NetID == id )
    2 L6 q: F5 ~" q8 e            break;0 K) U1 e+ T; D' v2 h
            pPlayerData = pPlayerData-&gt;pNextInIDHashBucket;
    - P/ _! C' ~, ~3 H) K    }</P>3 B/ U7 F4 S8 d  u) ^1 N! y7 W
    <P>    // Unlock the hash bucket
    & U" s3 \9 N7 t    m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();</P>2 g" ]$ C8 c0 E5 w
    <P>    // Return the player we found (will be NULL if we couldn't find it)
    ) p2 e: m" z+ u2 G$ b    return pPlayerData;9 Y% ?3 y# ~& F" M  z' B2 M) e
    }</P>
    ( l# V; D4 B6 J8 d, Y0 @  k' X/ {
    + h/ M1 h: z* T8 @* X<P>6 N2 E/ ?. |" {, x& o3 T) u
    //-----------------------------------------------------------------------------. o9 W8 s# f9 L& a% d
    // Name:
    ! o$ A. h; b3 |' M& Z// Desc: calls DisplayConnectionInfo for each connection in a round-robin manner) {) S# k2 l% s, i4 D: S4 V
    //-----------------------------------------------------------------------------
    ! J# i2 I# ^: u2 d5 H; C# d  F4 Avoid CMazeServer:isplayNextConnectionInfo()
    & C; s; T: n+ v, ]7 T{
    0 E% a, a5 D  o4 L    if( m_pNet )! Y5 l; l- l1 K
        {
    ' u! F0 T$ V+ N6 b, A5 D        // Find the player that was displayed the longest time ago, and display it.0 b; Z4 Q( L. m) E; D
            FLOAT fCurTime = DXUtil_Timer( TIMER_GETAPPTIME );
    5 o5 l6 P- H$ J) `1 \9 L        PlayerData* pOldestPlayerData = NULL;
    & z) L! u8 }$ u0 d+ c& j        FLOAT fOldestTime = 0.0f;</P>
      \, v# R' k5 x5 Z1 Y/ \* K<P>        m_PlayerDataListLock.Enter();</P>
    % S& n; w" L" I2 n" B0 J<P>        PlayerData* pPlayerData = m_pFirstActivePlayerData;+ U8 s% ~5 }- U( q$ R9 y- g
            while ( pPlayerData )
    ' B( o" a9 g) r0 F$ j  n        {
    6 `) u0 G0 E. Y! o5 q- ^! K' J3 f            if( fCurTime - pPlayerData-&gt;fLastCITime &gt; fOldestTime )
    " D! p: m0 {2 Q, |            {
    - F+ @# i: g( i                fOldestTime  = fCurTime - pPlayerData-&gt;fLastCITime;
    / N. N( R5 R  \* W! {7 |; j) D                pOldestPlayerData = pPlayerData;
    ) u2 @$ o( x2 c) K; _            }</P>
    * c! |" U1 q4 p5 \' @<P>            pPlayerData = pPlayerData-&gt;pNext;
    + f" d) m6 M7 x1 y" t        }</P>
    $ D- b$ l0 ~* P3 ]! o/ C# I<P>        // Display the player with the oldest CI field, and update its CI field.7 A) z5 Y" l& h! X5 d
            if( pOldestPlayerData )
    5 {1 n( o+ \8 I4 j- l        {5 m& f( q. @3 D9 k! O( z7 W% l
                ConsolePrintf( SLINE_LOG, TEXT("Displaying connection info for next player") );
      {  S2 O6 T. e; j' x8 M            DisplayConnectionInfo( pOldestPlayerData-&gt;NetID );
    ( K, i: G) u; K! `            pOldestPlayerData-&gt;fLastCITime = fCurTime;
    : F. D- m% [) d! I" H1 c$ T4 o- {        }
    ( @! L8 R" d; W6 p% S# x* Z4 u        else
    ; _/ o/ r' M( q        {
    8 E& q* u( y% s; t            ConsolePrintf( SLINE_LOG, TEXT("No players found") );" T% q* U1 g9 R  j+ N/ t
            }</P>
    & t- G, s" G: D, E+ b# ^+ r<P>        m_PlayerDataListLock.Leave();1 `- L7 b! ?( i  o3 N, n
        }& |; b1 r! h4 m1 }
    }</P>2 S. L) }/ @8 Y' {% @1 i0 _
    : T0 n) q9 Z5 T. r) G7 b7 Y& D
    <P>* C3 Z& c- d/ q) a& p) A% y
    //-----------------------------------------------------------------------------
    , F( V7 v" F1 s4 b( x0 P// Name: 9 j6 X$ I& N; Y1 _& ]
    // Desc:
    ( G6 W1 T6 X$ o//-----------------------------------------------------------------------------
    8 P+ q; u; b7 S2 P3 F. avoid CMazeServer:rintStats()* r: t: x4 Q$ m$ R& v5 D
    {
    , V" w8 N6 G8 s- x/ r% ^1 k    ConsolePrintf( SLINE_LOG, TEXT("Thread count: Active=%d Avg=%.2f Max=%d"),
    9 k6 M% Z9 f6 e9 t; a# s                                    m_wActiveThreadCount, m_fAvgThreadCount, m_wMaxThreadCount );) _# y. I8 X+ w" S# m/ B. }2 J- E
        ConsolePrintf( SLINE_LOG, TEXT("Thread Time: Avg=%.4f Max=%.4f(s)"),; p1 F6 t7 a% r5 A5 L  J+ f) F
                                        m_fAvgThreadTime, m_fMaxThreadTime );
    ) X3 W- }# Z" y7 z1 S    ConsolePrintf( SLINE_LOG, TEXT("Players online (not including server player): %d"), m_dwPlayerCount );- K1 m& E+ {; n3 M; [6 d* {
        ConsolePrintf( SLINE_LOG, TEXT("Peak player count: %d"), m_dwPeakPlayerCount );
    . N" r" S1 h) i" b% O0 }}</P>/ W0 R$ N4 o& n/ d* B

    $ f8 A" N; h. T& B0 S3 |3 I* B6 A8 R<P>! ?0 E0 N& V1 s
    //-----------------------------------------------------------------------------4 Y5 b- ^  _6 }+ P$ |
    // Name: ( `& K1 S. u, _' n
    // Desc: " z7 a. Y/ ]3 T+ E% N1 Z$ t4 k
    //-----------------------------------------------------------------------------
    . {+ H$ Q& x" F& k1 yvoid CMazeServer:isplayConnectionInfo( DWORD dwID )
    4 Y/ t: d# A6 j( y- W6 J& A/ c{% j3 n0 J& n  @2 o
        TCHAR strInfo[5000];
    : g9 N  [/ c* U$ E# C. v    TCHAR* strEndOfLine;
    8 k/ p$ D5 Y  u. Q/ }, {, C    TCHAR* strStartOfLine;</P>' p# ^. k" E6 M/ _" E4 ~3 j. g
    <P>    // Query the IOutboudNet for info about the connection to this user6 c8 P+ E4 Z9 }! n0 M
        m_pNet-&gt;GetConnectionInfo( dwID, strInfo );</P>; s1 q- Y$ T; {3 T7 A) [* T
    <P>    ConsolePrintf( SLINE_LOG, TEXT("Displaying connection info for %0.8x"), dwID );3 {2 Q" j% T* Z- D9 Q/ h
        ConsolePrintf( SLINE_LOG, TEXT("(Key: G=Guaranteed NG=Non-Guaranteed B=Bytes P=Packets)") );</P>
    ) `% `* H! U9 K1 C9 @<P>    // Display each line seperately
    6 O7 p  O0 W% ~9 @' `9 B    strStartOfLine = strInfo;" K5 \$ O: E! l6 {6 Q/ d
        while( TRUE )4 Y4 {4 _1 B% [8 r3 L; J
        {/ k# r& L! J2 e( d
            strEndOfLine = _tcschr( strStartOfLine, '\n' );
    9 b' B% ~% |! S! a        if( strEndOfLine == NULL )
    ! N! @9 a6 m, |7 U  r2 ?& \% s6 B            break;</P>
    6 m/ L2 L3 e/ J& [<P>        *strEndOfLine = 0;5 d: T, R. F3 G1 J5 `* Z4 i
            ConsolePrintf( SLINE_LOG, strStartOfLine );: U4 K9 D8 z2 H9 j* [2 V
            strStartOfLine = strEndOfLine + 1;2 Q, \$ W/ {. ?! @
        }1 v, _3 I  }! v( Z0 P
    }</P>
    ) _! i8 _' L. C( W! @, u) O5 G9 P& l7 D7 g  r
    <P>
    ( v3 x8 D, K; K//-----------------------------------------------------------------------------( [" i3 e' J& _+ v
    // Name: 5 B1 i1 L# F* E2 P7 ^
    // Desc: $ ]: Z$ v) J4 ~  G
    //-----------------------------------------------------------------------------1 ]: h  X2 T2 `  o5 X) h
    HRESULT CMazeServer::SendPacket( DWORD to, void* pData,
    1 i& D5 f: D' \9 d/ B6 I                                 DWORD size, BOOL reliable, DWORD dwTimeout ). V  m) U7 j6 i9 X$ M8 T2 P& y- v
    {
    9 k9 t+ s9 T8 ]- f    // Chance of forcing any packet to be delivered reliably/ @3 t; L: X* b8 B. Z
        if( m_Rand.Get( 100 ) &lt; m_dwServerReliableRate )& L3 [; O( a$ w' n6 m
            reliable = TRUE;</P>6 J+ s, K' e7 z& Q6 i4 Z' E; G$ p) o
    <P>    return m_pNet-&gt;SendPacket( to, pData, size, reliable, dwTimeout );1 K) }' f, ?# z  _2 R
    }</P>5 q( |* O+ E5 N! y# T* b
    ( Q0 A; j- G" D9 c
    <P>
    % _: g5 g5 S8 R/ k4 j7 r' Y//-----------------------------------------------------------------------------/ K( z9 R3 x- F
    // Name:
    * S: l, T8 K4 o// Desc: , s  S. p+ k$ s" b" T7 q
    //-----------------------------------------------------------------------------# W) q, e. q  a# z
    void CMazeServer::SendConfigPacketToAll( ServerConfigPacket* pPacket ): P+ D# V. Q  _' X: c
    {" Q% L' M' ]- K' C
        // If we're up and running, then send this new information to all clients5 Z8 e% @1 x' P$ E
        if( m_pNet )7 i+ K) X( U! X: u3 g$ S
        {
    6 C! Y$ p$ e. U" p8 q        //Use the AllPlayers ID" h5 K# \0 p7 q! g, \/ v, u8 p
            SendPacket( DPNID_ALL_PLAYERS_GROUP, pPacket, sizeof(ServerConfigPacket), TRUE, 0 );  {2 i% ^# c9 }6 C2 |2 o
        }% i4 o0 @8 R+ h5 N; b% P
    }</P>
    4 g' N% R) n3 B
    ! E% h3 n- q( R  l! W5 ^<P>
    ) d4 A2 _. J) c4 p//-----------------------------------------------------------------------------5 {' ~" u0 p' o6 J1 ?, [
    // Name: 0 Z: E5 R# B0 Y1 S. W( e0 w
    // Desc:
    2 S* _) m; U& y- m' ~+ v  j7 o//-----------------------------------------------------------------------------6 [8 W* j- T/ [- J1 }1 |
    void CMazeServer::SetClientReliableRate( DWORD percent )9 P' m4 p8 g% m5 S/ W
    {
    2 s2 f$ I9 ?, j5 Q    // Update client config, and build packet containing that data6 z, n4 _; n/ G0 B( q' M
        m_ClientNetConfigLock.Enter();0 [& Z! }" V, O9 n7 {: n3 k8 N
        m_ClientNetConfig.ubReliableRate = BYTE(percent);
    8 y3 P) R) R4 Y, X1 h4 M( c0 H    ServerConfigPacket packet( m_ClientNetConfig );
    : B6 b9 P7 A/ x" o5 i    m_ClientNetConfigLock.Leave();</P>7 j: _. d% n! d" Q' N9 q" v
    <P>    SendConfigPacketToAll( &amp;packet );  n: E6 u6 Y# p$ s
    }</P>
    ) o/ P, {& N# q
    ! }, }+ e7 c5 \2 q2 i4 q<P>
    2 b1 @( T3 k' r$ h5 M- |& z$ @0 H//-----------------------------------------------------------------------------, @  H5 z5 ^# s9 ~- d
    // Name: ' E* B4 z/ N( \: `: X) V
    // Desc:
    . A0 I( w2 b) E4 Z//-----------------------------------------------------------------------------/ u5 i5 `$ Y6 Y" L1 Y
    void CMazeServer::SetClientUpdateRate( DWORD rate )! G2 V/ `( @% C% y3 Z2 k5 z
    {$ A: r) L9 |/ d0 Z
        // Update client config, and build packet containing that data
    9 U8 b- D7 y3 T6 Y* V1 e    m_ClientNetConfigLock.Enter();; L6 C3 j# N" O% t+ a
        m_ClientNetConfig.wUpdateRate = WORD(rate);
    ; T) h0 G8 C2 \, J+ J( N    ServerConfigPacket  packet( m_ClientNetConfig );* N. d4 m$ G( ^$ l
        m_ClientNetConfigLock.Leave();</P>
    # ^3 p2 p; M2 M0 G; M<P>    SendConfigPacketToAll( &amp;packet );5 S- O3 h7 i0 c5 t* h
    }</P>
    4 D2 p- N& M: \0 ^/ H; S) F5 T- l; W" T$ O/ T7 S
    <P>
    . \$ N% K9 z& l//-----------------------------------------------------------------------------
    , W. z. v8 N; [; p% M9 m1 p// Name: . ^+ v$ `4 y1 h9 M5 ]
    // Desc:
    " W" x$ |/ H- T/ Z//-----------------------------------------------------------------------------
    ! x1 c) m% X8 kvoid CMazeServer::SetClientTimeout( DWORD timeout )% t0 I: ]7 P. p  I+ R/ f
    {# s. ]5 G3 h8 [- m& S
        // Update client config, and build packet containing that data4 Q6 M. S4 q0 Q3 \- h' Z
        m_ClientNetConfigLock.Enter();" m( o/ K5 B. W. U2 Q
        m_ClientNetConfig.wTimeout = WORD(timeout);, M0 r1 x% ^7 O. [
        ServerConfigPacket  packet( m_ClientNetConfig );; {  u; j  B9 ]; S1 v: N' y
        m_ClientNetConfigLock.Leave();</P>* p8 E, ~' W, L- a, j
    <P>    SendConfigPacketToAll( &amp;packet );. J, h: H$ U* w  W$ [" M+ @
    }</P>0 j- t: ~+ U6 N1 j+ C8 N+ k. M
    2 s1 c: Q8 s, R2 `
    <P>
    / T8 H3 z( Z) Z! k% _//-----------------------------------------------------------------------------  D7 I+ m& M# }% M: R& s9 ^
    // Name:
    : ^  g) g" C. j& j. w// Desc:
    - _0 w% W) u& t3 K3 U//-----------------------------------------------------------------------------: q# L$ z3 B7 H  H$ g, V" W
    void CMazeServer::SetClientPackSize( DWORD size )
    & [2 {" w! x% o5 Z) @{; ]" y8 F4 }8 ~$ M, [0 ^# ]# j
        // Update client config, and build packet containing that data
    ' D6 j3 ?" R5 i- M    m_ClientNetConfigLock.Enter();6 K. N2 A$ N5 m+ I: H
        + Z- O/ Z2 {% _$ E: j0 U; W% c2 z
        m_ClientNetConfig.ubClientPackIndex++; //Increase index and verify location in array.
    ! T: u3 h7 _: U! Q4 V    if(m_ClientNetConfig.ubClientPackIndex &gt;= PACK_ARRAY_SIZE)   3 W0 z% I) X3 @6 c- J
            m_ClientNetConfig.ubClientPackIndex = 0;</P>1 X: Q3 Z- J+ W+ }4 ^7 u
    <P>    m_ClientNetConfig.wClientPackSizeArray[m_ClientNetConfig.ubClientPackIndex] = WORD(size);! I/ ?. n1 M( S+ r/ I+ M
        ServerConfigPacket packet( m_ClientNetConfig );9 V+ e2 M& b0 J$ F" @4 `% n" h8 T# X
        m_ClientNetConfigLock.Leave();</P>( E8 `4 D- F* g7 |
    <P>    SendConfigPacketToAll( &amp;packet );5 z; L( C6 L5 P: H
    }</P>% p0 l$ x" N, W- w- e; N& j% w4 y
    & h; A0 N! M+ X5 C
    <P>
    1 h3 H! {/ p- s//-----------------------------------------------------------------------------
    ( x* |$ G7 X( T9 ~  W/ {// Name: 8 d" L6 u: P/ K
    // Desc:
    . s: z! c( i" m//-----------------------------------------------------------------------------
    . J. Q; K  K6 e( r, G* y$ Avoid CMazeServer::SetServerPackSize( DWORD size )- y" E+ i3 W3 C9 O$ g' o7 a
    {9 r6 i6 ]' H( u! {. F/ i( s4 w
        // Update client config, and build packet containing that data
    9 B. e8 _6 j' q9 ^$ E    m_ClientNetConfigLock.Enter();
    / M% ]$ w2 L# H/ U; K    / z9 ^2 `: \. o7 z: G1 k; }
        m_ClientNetConfig.ubServerPackIndex++; //Increase index and verify location in array.
    4 W* _) l+ l" q4 `1 R! H    if(m_ClientNetConfig.ubServerPackIndex &gt;= PACK_ARRAY_SIZE)   
    # z; q/ Q) W# P        m_ClientNetConfig.ubServerPackIndex = 0;</P>
    6 ]2 x* w' \; ?6 Q9 F# M<P>    m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex] = WORD(size);
    $ ~* N) [( i7 a/ f+ f    ServerConfigPacket packet( m_ClientNetConfig );
    ! p% ^1 K0 E9 l( [7 x    m_ClientNetConfigLock.Leave();</P>% h3 o# u( o6 W
    <P>    SendConfigPacketToAll( &amp;packet );
    / O& p0 j% \2 `4 @! C}</P>7 N# N. I" K1 _0 _
    <P>  `5 B2 u* V+ ]! `0 M. R$ y- s
    //-----------------------------------------------------------------------------
    + a+ f% Q, n4 y2 w: T& ~) s// Name: 3 g. L1 n) B* v2 b4 H8 M
    // Desc:
    0 a& u' _/ z# s! c//-----------------------------------------------------------------------------
    $ K* x7 @3 E7 ~' yvoid CMazeServer::SetClientThreadWait( DWORD dwThreadWait )% J, m  n5 J  }6 D# c% [- J! O
    {
    ' J0 P& F" P, u. O/ A/ I/ k    // Update client config, and build packet containing that data
    $ \8 ]0 J& B; p/ ~4 M& t    m_ClientNetConfigLock.Enter();
    9 [, X# a- r. Z, ^' e/ V: S    ( Z: s% \9 E( X, B  {6 J7 i
        m_ClientNetConfig.dwThreadWait = dwThreadWait;
    5 h& \7 b: f9 C  ^( H    ServerConfigPacket packet( m_ClientNetConfig );6 W; |! H; e6 h) \( n" f# V
        m_ClientNetConfigLock.Leave();</P>
    / Z( J7 v, Q, r2 A1 X  J8 q0 c<P>    SendConfigPacketToAll( &amp;packet );
    # O3 I# b# a9 n) \}</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, 2025-8-15 00:26 , Processed in 0.583940 second(s), 56 queries .

    回顶部