QQ登录

只需要一步,快速开始

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

[分享]MazeServer源码示例

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

1万

主题

49

听众

2万

积分

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

    [LV.10]以坛为家III

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

    群组万里江山

    群组sas讨论小组

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

    群组C 语言讨论组

    群组Matlab讨论组

    跳转到指定楼层
    1#
    发表于 2005-1-31 11:52 |只看该作者 |倒序浏览
    |招呼Ta 关注Ta
    <DIV class=HtmlCode># k- g+ l4 `5 }' c- g4 o1 s
    <>// File: mazeserver.cpp0 J+ z- g! a' {$ y
    //, I8 K% y( q* G' A6 x$ X
    // Desc: see main.cpp9 x0 f# X' T+ g7 L/ p1 g
    //" G" }; w$ v4 d$ u" `; x8 [
    // Copyright (c) 1999-2001 Microsoft Corp. All rights reserved.% Z7 l: S  V! p$ N& X
    //-----------------------------------------------------------------------------
    0 d! C& v. [1 w% i0 U& K#define STRICT# _  L* T6 `+ F
    #define D3D_OVERLOADS, k" E/ N& T/ E/ x/ M' K* t
    #include &lt;windows.h&gt;
    . ]& ^7 d% {! A5 _2 Q0 ~  v5 e#include &lt;d3dx.h&gt;
    8 F0 N" A5 Y6 J2 P. x0 j/ n#include &lt;stdio.h&gt;
    1 g5 e' J, Q% c  p% H# l#include &lt;math.h&gt;
    * U0 v' \6 U/ b+ S& N" m/ r1 T#include &lt;mmsystem.h&gt;
    3 [  k) Q+ [/ j* x4 c  ~#include &lt;dplay8.h&gt;$ N; P2 q& i: F$ @+ J
    #include &lt;dpaddr.h&gt;
    ! L6 X& B( v3 A5 H4 [#include &lt;dxerr8.h&gt;
    : P, H3 y$ ~$ D/ o3 |, N4 N2 Q* _& L#include "DXUtil.h"' @" `( d" p$ I6 t+ e" G) i. r
    #include "MazeServer.h"
    * {4 ?# @4 E: r' ]& {# A#include "ackets.h"9 r; k: q" k- x  ^$ A3 e
    #include "Maze.h"
    7 B9 I% O/ U/ M#include &lt;malloc.h&gt;6 w" ]+ Q# N6 W* h
    #include &lt;tchar.h&gt;</P>
    * A) l  l0 x) d& f/ X: z9 f# C" v5 b( e. @( R+ T
    <>//-----------------------------------------------------------------------------
    " f& D; u# ~/ c// Name: ( R1 a( k/ p6 \& O: @/ y, t
    // Desc: ) q: y- y2 t5 ~0 ?4 b* W
    //-----------------------------------------------------------------------------
    3 M2 y) z0 }/ rCMazeServer::CMazeServer()
    % x: f" O& E0 z& g/ X5 W, g{
    4 @' z4 b* w1 }* ~* S( S0 _8 u1 X2 @    m_dwPlayerCount         = 0;3 a1 |4 \8 D, H8 w- j( ]
       
    & c5 M0 l1 d% C4 Q    m_wActiveThreadCount   = 0;
    8 u5 i3 ~1 {* e5 d6 j) x+ j% A( u6 T  U    m_wMaxThreadCount      = 0;8 H9 T# m: t8 k& ~
        m_fAvgThreadCount      = 0;1 S& ?/ J! j1 P1 ?: L8 i$ z
        m_fAvgThreadTime       = 0;
    ! b6 ^. x& P: ?    m_fMaxThreadTime       = 0;</P>( l9 |& F+ ]$ A  N0 t5 c5 W! [
    <>    m_dwServerReliableRate  = 15;
    0 V8 }2 p2 U' N0 q1 N$ E2 Z% ?    m_dwServerTimeout       = 150;! D9 p  H! ]/ a5 g: U+ H3 E$ U3 I
        m_dwLogLevel            = 2;& ~2 E: ]2 ^& R+ ^4 G, c6 _3 Q8 `
        m_pMaze                 = NULL;</P>* m8 e, i$ \( j* m, g* t: {+ q0 N2 z' V
    <>    m_ClientNetConfig.ubReliableRate = 15;, t& \6 {6 [. g3 G0 y
        m_ClientNetConfig.wUpdateRate    = 150;
    & n0 v9 v; p% @7 ^  v, m    m_ClientNetConfig.wTimeout       = 150;</P>
    2 e- |3 ~' ]" y<>    m_ClientNetConfig.dwThreadWait = 0;</P># h. x* h( n$ B+ ^
    <>    m_ClientNetConfig.ubClientPackIndex = 0;4 V& @* H! S5 g8 Q
        m_ClientNetConfig.ubServerPackIndex = 0;- s) h# U. n# U4 n. Z/ ?: x
        for(WORD x = 0; x &lt; PACK_ARRAY_SIZE; x++)
    ; W* |* \+ k$ _* G* y! R! V8 S    {
    4 f$ |# o0 `* A" O- l, K% l        m_ClientNetConfig.wClientPackSizeArray[x] = 0;4 \' g4 @  s! T: j" o
            m_ClientNetConfig.wServerPackSizeArray[x] = 0;' `. {! B- h, I9 i1 g' |6 q
        }
    / W" J; z0 Q0 c4 O}</P>  _+ B% x" N! X" {7 _/ m
    : w; [5 N, i9 R
    <>
    9 R1 P! ]/ @( \# A8 K//-----------------------------------------------------------------------------/ y) e, ]) e) m
    // Name:
    3 R2 a: ?8 z5 g- b$ ]// Desc: ; }9 }( x# n. J3 R' P9 ?2 f
    //-----------------------------------------------------------------------------* u( P8 V+ t$ ]! A8 `) K
    HRESULT CMazeServer::Init( BOOL bLocalLoopback, const CMaze* pMaze )
    + ]; w7 d) @/ V" k* `* }2 M. [{/ g6 `! [! y  j3 I: O* ?
        m_bLocalLoopback = bLocalLoopback;
    3 [  v, S! f! m* z+ E( M6 K0 a& W    m_pMaze = pMaze;
    ' w. ~: t$ m6 o/ A0 j$ C& g# M    if( m_pMaze == NULL )
    5 Z  v5 v) [: k# p* ?/ T        return DXTRACE_ERR( TEXT("aram"), E_FAIL );</P>
    ; ~) T# }, U4 c7 q<>    // Grab height and width of maze
    2 M0 S- ~6 M( I( y    m_dwWidth = m_pMaze-&gt;GetWidth();
    ( `3 u6 X* Y; C; x' g7 A% W3 Q    m_dwHeight = m_pMaze-&gt;GetHeight();</P>5 M  |; N- ^- ^5 y
    <>    m_ClientNetConfig.dwMazeWidth  = m_dwWidth;- `) x7 N# U& a! Y
        m_ClientNetConfig.dwMazeHeight = m_dwHeight;</P>
    1 y- ^- h# _. O1 c<>    // Validate size. Must be a power-of-2 times LOCK_GRID_SIZE. Compute the shifts.% X- h9 X5 g. O  y
        if( m_dwWidth &gt; SERVER_MAX_WIDTH || m_dwHeight &gt; SERVER_MAX_HEIGHT )
    & x2 ]$ q8 v! Z2 K2 e6 p7 h0 A        return DXTRACE_ERR( TEXT("Maze height and width need to be less than 128"), E_INVALIDARG );# H5 n' C! Z# y7 f/ {9 K
        if( (m_dwWidth % LOCK_GRID_SIZE) != 0 || (m_dwHeight % LOCK_GRID_SIZE) != 0 )6 D/ c$ r5 l8 c
            return DXTRACE_ERR( TEXT("Maze height and width need to be divisable by 16"), E_INVALIDARG );</P>
    % ^" C5 H1 p. z8 E7 d+ F  {' C) Y# Y<>    DWORD scale = m_dwWidth / LOCK_GRID_SIZE;
    6 @% S! [" C9 }; y% w1 y    m_dwMazeXShift = 0;
    8 G9 P2 O4 M, ]$ Y: M6 U    while ( (scale &gt;&gt;= 1) )
    * H/ I, N* |* {8 F4 T4 p' j, l        m_dwMazeXShift++;</P>* E' ~( ]3 U4 R: n9 l" p7 h
    <>    scale = m_dwHeight / LOCK_GRID_SIZE;  J$ N1 A$ F1 Z* t
        m_dwMazeYShift = 0;- ~) ~3 Z" S$ g! h  r+ b
        while ( (scale &gt;&gt;= 1) )
    " f" J1 P7 _, w7 P# L        m_dwMazeYShift++;</P>9 J+ ]4 I/ z6 {4 k! G+ V5 ], n
    <>    if( ((DWORD(LOCK_GRID_SIZE) &lt;&lt; m_dwMazeXShift) != m_dwWidth) ||/ }, i1 Q+ O$ k4 E5 O4 z, K& `9 _
            ((DWORD(LOCK_GRID_SIZE) &lt;&lt; m_dwMazeYShift) != m_dwHeight) )
    ; R6 Y$ t, G% ^2 z1 T; o2 A        return DXTRACE_ERR( TEXT("Maze height and width need to be power of 2"), E_INVALIDARG );</P>3 r3 s) x' ?7 u
    <>    // Initialise the player list& r1 H8 m2 T! d7 A2 F5 B
        ZeroMemory( m_PlayerDatas, sizeof(m_PlayerDatas) );
    ! H9 n0 Q* \" G- \1 D4 P    m_pFirstActivePlayerData = NULL;
    4 w9 U, T6 j6 |. H4 T    m_pFirstFreePlayerData = m_PlayerDatas;: T8 ^) d: G) n  k5 Y0 L9 Q1 |
        for( DWORD i = 1; i &lt; MAX_PLAYER_OBJECTS-1; i++ )( |) A  n' _1 s) I; P& c. H5 D8 Z
        {
    6 s% L9 E9 ^6 |8 ~2 O2 v" e        m_PlayerDatas.pNext = &amp;m_PlayerDatas[i+1];8 a7 y# ]2 \7 {3 j) I
            m_PlayerDatas.pPrevious = &amp;m_PlayerDatas[i-1];
    * |4 C1 \) ?9 N& _    }</P>
    ( p' r; r# w# Q. V<>    m_PlayerDatas[0].pNext = &amp;m_PlayerDatas[1];6 [( n4 r0 i' ^- x% T; Y( i7 V4 z
        m_PlayerDatas[MAX_PLAYER_OBJECTS-1].pPrevious = &amp;m_PlayerDatas[MAX_PLAYER_OBJECTS-2];
    3 A# L3 T5 a( T) S    m_dwActivePlayerDataCount = 0;
    & c" p  ]1 E  Y+ w4 y* B' j    m_dwPlayerDataUniqueValue = 0;</P># Y8 F  U3 X) @' x" T$ ^
    <>    // Initialise the cells
    3 E0 E5 F9 s7 O- J7 \' K& b9 F: A    ZeroMemory( m_Cells, sizeof(m_Cells) );
    / T) G1 f3 k7 V2 w: A    ZeroMemory( &amp;m_OffMapCell, sizeof(m_OffMapCell) );</P>
    2 p4 d( T0 G  J+ h! h7 a* `0 a8 t( p<>    return S_OK;
    5 Y( V1 a9 t3 K}</P>
    $ s' e# t" O* J" q6 e
      _1 i9 z8 s3 a. V1 ~9 X<>0 N' T' w, n% b  J7 l
    //-----------------------------------------------------------------------------) v7 I0 P# o% s0 t
    // Name: 4 C. Q5 E) \4 q3 F
    // Desc:
    , }" O, m8 m+ [* t  S: @/ s$ V# N//-----------------------------------------------------------------------------+ U6 j" T1 R9 B1 \0 o
    void CMazeServer::Shutdown(), D1 @) C- Z; P( I& J/ J' X
    {: g2 k# B* f$ Z  y! Y  X
    }</P>/ P! O, G) u3 g* F

    # y* n2 ^' h/ l% V; g* `<># p  F+ A$ V  N# u
    //-----------------------------------------------------------------------------
    1 A2 e/ h7 q5 T+ }. L/ B// Name: : [, x2 [& j+ l" u
    // Desc: ) q' W/ Y, W0 `+ @* Q
    //-----------------------------------------------------------------------------
    & M  l9 y0 K" q8 @2 r  c3 z" f/ y# X/ cvoid CMazeServer:ockRange( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )
    : C* `- E( z1 Y1 u{" G& M% G& ~1 v. ?: U
        m_LockGrid.LockRange( x1&gt;&gt;m_dwMazeXShift, y1&gt;&gt;m_dwMazeYShift ,
    ) V1 M! I* |) z9 W                          x2&gt;&gt;m_dwMazeXShift, y2&gt;&gt;m_dwMazeYShift );
    & a7 f( v0 K( B" F  p6 {}</P>* Q- ^0 f1 ]0 A! z# X' D# ?0 P) [
    ) k! ~0 K/ E6 ^8 H
    <>
    2 n6 X$ `0 P" f' Z" n4 v, W& [//-----------------------------------------------------------------------------9 B1 H6 h( t3 k: z
    // Name: * s/ H1 x# Z# u0 ~: ?
    // Desc: . ?+ Y5 h( m9 k, r
    //-----------------------------------------------------------------------------6 g# r0 E) ~4 R
    void CMazeServer::UnlockRange( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )% ~( L# }9 D: r
    {! i/ O7 W' O) V" y4 K5 h, u/ l
        m_LockGrid.UnlockRange( x1&gt;&gt;m_dwMazeXShift, y1&gt;&gt;m_dwMazeYShift ,
    8 `) F: e1 N2 |; H/ b6 [) p. a                            x2&gt;&gt;m_dwMazeXShift, y2&gt;&gt;m_dwMazeYShift );. M2 `1 S" ?: [
    }</P>1 u9 E2 y0 V# f, n3 p

    9 O4 m, f" g) G<>- W3 L% D' Y) e6 c# E
    //------------------------------------------------------------------------------ k0 d3 W: \/ Z! b
    // Name:
    ! f2 u& l, S% y% o$ ^// Desc:
    ' r( M2 G" m- K. x  B7 m8 H//-----------------------------------------------------------------------------
    6 r: K2 m5 b2 ]  R3 G" M1 A3 @void CMazeServer:ockCell( DWORD x, DWORD y )0 }. @2 O7 s$ e2 j: D$ c0 [
    {
    6 f5 a2 ]. I: R/ r    if( x == 0xffff )
    " J4 E/ t5 _7 E' Y        m_OffMapLock.Enter();$ U) Z; u# l: Y
        else
    ! Y0 @% `# R  v7 h, p, g" V2 U        m_LockGrid.LockCell(x&gt;&gt;m_dwMazeXShift,y&gt;&gt;m_dwMazeYShift);/ r# a* Z4 b# @: B' t5 k
    }</P>* k! W3 R- s/ M4 O- M

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

    3 q6 V8 ^4 F7 j0 M# L& r& n1 }; p    // Pack the buffer with dummy data.
    $ {: p7 g! e+ y( @' }- P$ `    if(m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex] &gt; 0)7 ]0 z. \, r9 I# }
        {
    0 j3 D' f1 k! s. I+ K0 c$ J  J2 p& q        DWORD   dwBufferSize = acksize + m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex];
    # n' A8 m" A: M/ {" H        VOID*   pTempBuffer = 0;</P>
    / r: d5 E0 F! G, E/ Z9 S<P>        pTempBuffer = malloc(dwBufferSize);$ v  B: {7 ]* G; u0 O7 i" a
            if( NULL == pTempBuffer )
    ! H, D2 l+ e: c1 [+ }+ X1 Q        {
    . p  n& c+ c7 Z. k/ P8 d/ l            //Out of memory
    / x% I6 ]) t4 {6 M            DXTRACE_ERR_NOMSGBOX( TEXT("System out of Memory!"), E_OUTOFMEMORY );
    " h7 l( g+ ~* e! p% A            free( pSvrAckPack );% Q$ A3 ~) v# v* `9 x8 ^
                return;
    ( X. V$ Y5 l4 x9 X; F        }</P>' C* n. }: ~7 I* G; J4 K
    <P>        FillMemory(pTempBuffer, dwBufferSize, 'Z');) f  f9 j) s# J# ]# q
            memcpy(pTempBuffer, pSvrAckPack, acksize);</P>& S7 {& s! O3 S# Y* L/ ]
    <P>        SendPacket( dwFrom, pTempBuffer, dwBufferSize, FALSE, m_dwServerTimeout );2 `* B) q# N. A2 ?) h
       
    2 R+ h1 q0 M# R        free(pTempBuffer);) H0 f: c; P+ c5 X' i3 V
        }   
    - E9 q! Y8 t+ L% o    else
    * |2 o, r7 z* _+ N    {7 I. t7 y0 u. D
            SendPacket( dwFrom, pSvrAckPack, acksize, FALSE, m_dwServerTimeout );
    2 ?* b0 |6 N/ ?9 [    }</P>
    6 j5 i+ o% ^: ^" d1 W, H<P>    free( pSvrAckPack );</P>
    ) K  D( z! d4 u1 ?<P>}</P>
    5 f( k5 M# p$ {. |/ Q6 [$ w; x2 b; D  K( |. _
    <P>
    6 X5 ~/ a+ j  j# r. Z& D//-----------------------------------------------------------------------------1 J; l. {& e2 T* s
    // Name:
    4 Y- Q* _) @) N- v2 C// Desc:
    7 N! q9 `: l- X" q//-----------------------------------------------------------------------------
    7 Z# h# b1 h. j/ cvoid CMazeServer::HandleClientVersionPacket( DWORD dwFrom, ClientVersionPacket* pClientVersionPack )& M; ^& F3 E/ |0 B7 t' W6 Q' b
    {
    # b$ @7 `" u0 b4 E    // Grab playerdata for this client and lock it
    / h# l7 n0 o" ~    PlayerData* pPlayerData = GetPlayerDataForID( dwFrom );
    + N+ r; U& I4 e/ n0 J/ R    if( pPlayerData == NULL )
    8 T( D# }2 H" u3 ?6 N        return;; k: E8 `3 W4 X  c
        LockPlayerData( pPlayerData );</P>' _' J: P9 b: d
    <P>    // Record the version number 2 g1 R/ x: ^% V. p5 y6 J
        pPlayerData-&gt;dwVersion = pClientVersionPack-&gt;dwVersion;</P>4 _- y' q# M% e; U# n
    <P>    if( m_bLocalLoopback )2 L5 m) ^$ W# z# k
            pPlayerData-&gt;bAllow = TRUE;
    0 D8 k2 Y' x3 R) g    else  b! B4 X% W( b' e- X
            pPlayerData-&gt;bAllow = IsClientVersionSupported( pClientVersionPack-&gt;dwVersion );</P>9 r/ H( _2 U3 H3 P- m( l# m+ k; f7 {
    <P>    if( m_dwLogLevel &gt; 0 )0 s  o6 s. X% @+ G
            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>
    ! O, w, s# }9 `; l7 R5 a- q% n<P>    if( FALSE == pPlayerData-&gt;bAllow )
    ! I# v3 t" w( ]/ f    {
    1 Z) \+ g1 x2 P$ v* b! r        if( m_dwLogLevel &gt; 0 )
    ; q  f" L! K* Y6 p* t% N            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Rejecting client"), pPlayerData-&gt;NetID );</P>
    5 E5 E* n0 x  h" g<P>        m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );  ^, W2 b! _# p  U7 k" M) M
            UnlockPlayerData( pPlayerData );
    4 o. n  i/ H$ H( C- {        return;, T: d# k/ D2 P2 b+ {2 T' n' O8 f
        }</P>& a5 N) X, G$ U1 h9 F# s+ m
    <P>    // Unlock the playerdata2 p  B" t; j9 }1 \& W+ u. o
        UnlockPlayerData( pPlayerData );</P>
    $ @+ m2 t% w+ q<P>    // Send acknowledgement to client that the client was either accepted or rejected7 Y3 D$ p0 y, W8 D: j
        ServerAckVersionPacket packet( pPlayerData-&gt;bAllow, dwFrom );
    ; I. }# c) W# P3 d+ Q- |    SendPacket( dwFrom, &amp;packet, sizeof(packet), TRUE, 0 );, I% d% k* @6 A6 Z: H
    }</P>6 x. U* h% J; ]% Q1 O9 u
    / m1 g; n0 u3 |2 }5 d/ K9 l
    <P>
    ( L- F' Y# V6 c; Z' r! m$ q//-----------------------------------------------------------------------------
    3 }; N7 c: u2 j; V// Name: & ]* D) Q* b& C8 H7 s
    // Desc:
    7 I4 i& r/ F0 P: Y1 U' |//-----------------------------------------------------------------------------: u2 s1 x" u" W; x
    BOOL CMazeServer::IsClientVersionSupported( DWORD dwClientVersion )' m8 i2 x9 }/ E' v, ^5 @
    {. ]/ l6 \. X$ u" Z! X, j3 {9 g5 |
        switch( dwClientVersion )0 E$ N/ |) o2 Q: }
        {
    + T  X3 r) O/ F' y4 @        case 107: // only v107 is supported3 M5 \6 {9 N( E1 y( p
                return TRUE;1 }2 V8 Y7 |4 J  ]1 q* H3 t* ?% Y( X
            default:3 O' x* ~8 V9 ^3 ^
                return FALSE;: U) ^# ?6 S9 a
        }
    + a6 e1 k6 W  E8 x$ W# w. f" f}</P>* I; d. k( U! w( e9 J  w  H; A2 v' b0 \* @
      r' i# U1 }, P$ k; d6 F* b* U  p. B
    <P>) C( }0 d( I, v* k4 N0 P- {* B3 l
    //-----------------------------------------------------------------------------9 P' G- X: B% L( v3 q
    // Name:
    . b2 j7 J0 G- c; E// Desc:
    ) I$ L, k: S  D+ Q/ Q6 f" _//-----------------------------------------------------------------------------0 H4 ^, v; ?( |* Z2 f3 r
    void CMazeServer::HandleUnknownPacket( DWORD dwFrom, ClientPacket* pClientPack, DWORD size )
    7 S* f" z3 @1 X( l& u' J  Y{1 D5 b# s# ~- L( \: ^
        if( m_dwLogLevel &gt; 1 ). E* p  b8 t9 ]. s& ^' S
            ConsolePrintf( SLINE_LOG, TEXT("ERROR! Unknown %d byte packet from player %0.8x"), size, dwFrom );</P>: R9 w5 ?; P: N, T+ ^
    <P>    m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );% @4 F  `7 f/ w$ c- A
    }</P>
    ! I- N- h6 A$ W8 y. L* i9 o7 c0 f# M9 c6 V/ Q$ ?0 j
    <P>
    , j# T$ I8 B! P: |+ ]//-----------------------------------------------------------------------------
    4 X) Q" \! m3 H4 a" i// Name: : P% v, D+ x. B6 ?9 g6 _" n
    // Desc:
    $ q6 {" N$ A: ?//-----------------------------------------------------------------------------0 G) C  J! ^- [# @
    DWORD   CMazeServer::IDHash( DWORD id )
    " y9 h  \; }' l{* r$ o) T3 A1 [- I" g( N7 Y
        DWORD   hash = ((id) + (id&gt;&gt;8) + (id&gt;&gt;16) + (id&gt;&gt;24)) &amp; (NUM_ID_HASH_BUCKETS-1);! Q+ v5 I/ [2 s. @* s  c
        return hash;
    % E# t; D; F  h/ U9 G; `}</P>
    - T1 {- S+ s2 x3 `' [
    & T! }/ }3 C. _/ b' m8 Y<P>
    7 R; J2 }8 N2 T; N7 S$ ~, F//-----------------------------------------------------------------------------' g/ ?9 M  y0 G+ c  K
    // Name: ) k: u' U; d) `" w6 H& X3 m  g
    // Desc: / }1 L! c0 m& B$ X7 ?) X  ^5 y
    //-----------------------------------------------------------------------------
    & T. b" y2 _9 M: S0 T" @2 jvoid CMazeServer::RemovePlayerDataID( PlayerData* pPlayerData )
    1 t) W! |' Y9 d: }2 J& A% w{: a  S7 e, k4 @" e1 f0 T+ f
        // Hash the ID to a bucket number5 G6 T3 g) ~$ i2 s! Z( d! D
        DWORD   bucket = IDHash( pPlayerData-&gt;NetID );</P>4 D- }" c, H" B8 ~. Q
    <P>    // Lock that hash bucket. ?  p1 {; ?, F4 k
        const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;7 u1 I8 S: T* z3 h/ p& b
        m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>
    9 ~7 s' g  X! W8 z* f- \<P>    // Loop though players in bucket until we find the right one
    / M$ E0 R& `! g/ M: I    PlayerData* pPt = m_pstIDHashBucket[bucket];
    / X5 {( Z; D, T4 h& x2 F    PlayerData* pPrev = NULL;
    5 A: v& C* C4 K9 C  h* e    while( pPt )( s7 R8 n! T2 \- U; Z) g8 V* Y
        {9 G9 @7 g& f. y
            if( pPt == pPlayerData )
    , F0 r, F% g# ?3 g) I8 B( v            break;, u( a7 A6 y6 m9 T- e7 e/ @" B; X
            pPrev = pPt;
    ) g9 V+ [" X1 o+ ^/ u; z        pPt = pPt-&gt;pNextInIDHashBucket;
    # o: U+ X1 h& p- M+ r    }</P>6 I9 W# \( g' ~- i0 A! k7 |
    <P>    if( pPt )/ B2 {3 L5 H- I& _1 z4 @- y- K
        {3 l6 F+ a4 o- W' v" {
            if( pPrev )) l6 ~! P3 g4 P/ `# l! S; [
                pPrev-&gt;pNextInIDHashBucket = pPt-&gt;pNextInIDHashBucket;
    9 ]; h  q' N% i' e$ H! R8 g        else; Z: Y# @" S3 P
                m_pstIDHashBucket[bucket] = pPt-&gt;pNextInIDHashBucket;" g# i4 k. H0 T! e2 D$ ?0 ~" j
            pPt-&gt;pNextInIDHashBucket = NULL;
    / q% k# r) M9 p# N- A1 f9 k0 W    }</P>4 ^: x* z/ e& L' O" ?& y, p0 t* T' `
    <P>    // Unlock the hash bucket
    ) ]  e( B0 X+ V: k* R* X' A- @    m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();
    " B( {# z! `+ V}</P>$ J. O5 k5 }/ i& D  H7 Q

    8 a: }9 |) E1 O# x4 K& Z7 H1 b<P>
      h, S9 `  @' X0 B7 E0 o) y' h- k//-----------------------------------------------------------------------------# C  S- M  k2 {& D9 w& G
    // Name: ; d# e3 B, T7 a  c, T: L6 I, Q8 \
    // Desc: $ }# `5 z5 Q5 B$ {+ m. m
    //-----------------------------------------------------------------------------
    % o) b% ]: I- V& W. t  v1 ivoid CMazeServer::SetPlayerDataForID( DWORD id, PlayerData* pPlayerData )
    - z7 {( Z# L! j# A{. m* M4 j# Q% ^
        // Make sure this player isn't added twice to the m_pstIDHashBucket[]& g& Q+ a9 l( n; g" \! y; |( l
        // otherwise there will be a circular reference
    6 X' b' E$ j' f, N    PlayerData* pSearch = GetPlayerDataForID( id );; M5 }! \( q9 I& c" `2 S0 T
        if( pSearch != NULL )
    . @  S" G, a; u- V! a        return;</P>: }! Z8 }! O! [# U2 x
    <P>    // Hash the ID to a bucket number
    4 x8 {" Q. F& K5 C0 L1 T    DWORD   bucket = IDHash( id );</P>' f) \0 _- e. Q" ~1 u" f& ^
    <P>    // Lock that hash bucket
    3 N8 {4 e3 B7 P' [8 ?* N" V    const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;$ f/ e$ H& U+ v; y/ j7 r1 P9 B$ m$ `% c2 @
        m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>
    * M6 e8 @, s/ ~! A9 G/ {* X<P>    // Add player onto hash bucket chain, u2 V' q5 V' ~3 J) ?$ J# E8 Z
        pPlayerData-&gt;pNextInIDHashBucket = m_pstIDHashBucket[bucket];
    : K/ T+ k+ F# U% |! l    m_pstIDHashBucket[bucket] = pPlayerData;</P>! {- s0 \. g3 y2 j
    <P>    // Store net id in player, a) t" V4 N1 i, f( s
        pPlayerData-&gt;NetID = id;</P>
    6 S8 v% p& m0 C. H<P>    // Unlock the hash bucket
    - x2 o" r7 n3 u/ m5 Y3 a- D' A% g    m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();3 Y; F2 K& ~- \5 R3 i' S1 e" j
    }</P>
    ( i2 v0 M8 g0 b) C3 f% Z8 D; n9 k
    % L0 \1 Z$ P, \% ?( K% a" {<P>& ^) x4 _- j. \  m/ Q9 H
    //-----------------------------------------------------------------------------
    9 F6 H4 A4 K; x// Name: 1 W: S; T! W, E9 D9 e; G; c9 Y1 s0 d: f
    // Desc:
    / U. ]% r; c0 s//-----------------------------------------------------------------------------# `2 j: F3 ]- C) f: J# I& K
    PlayerData* CMazeServer::GetPlayerDataForID( DWORD id )
    ! {2 `/ q4 b6 r  N; Z' Y* F{. Y, j' U" U3 I$ V* t0 t
        // Hash the ID to a bucket number
    1 k, M/ B/ w9 [9 j5 L    DWORD   bucket = IDHash( id );</P>  J/ P) J/ D( v% u3 }. I1 k" R
    <P>    // Lock that hash bucket5 ^2 O3 [& J  O
        const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;
    + B3 y: u- g, g" r0 v    m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>
    0 E3 [  ~: V4 v8 M; D<P>    // Loop though players in bucket until we find the right one1 I: X+ G( T# u9 Y1 E
        PlayerData* pPlayerData = m_pstIDHashBucket[bucket];
    4 _7 i; C: |" e, q# _    while ( pPlayerData )
    2 [5 k: O% n. p$ E5 o( S. T    {
    # p5 O( G. U" f, I2 ?7 L7 }! r        if( pPlayerData-&gt;NetID == id )
    8 a' e7 S* c% F: h. D# G1 |1 o5 X            break;3 Q* {( h# [+ q$ S8 E) Q0 g/ a0 H
            pPlayerData = pPlayerData-&gt;pNextInIDHashBucket;
    ! k' w+ Q3 {4 J7 j6 }# d% h    }</P>
    8 y7 J4 a: @7 }5 \2 _, M4 S<P>    // Unlock the hash bucket
    , O; q/ J* r# j6 B) b* B/ D, q    m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();</P>& s4 n) d" o3 o
    <P>    // Return the player we found (will be NULL if we couldn't find it)
    $ d# r7 M5 I; X1 S, d/ o2 f    return pPlayerData;% O( {( r% Y" u
    }</P>2 L, l% n$ z) H3 v, L

    2 I0 w5 }( F5 E2 Q* r( n<P>" |5 ^7 O4 [4 I
    //-----------------------------------------------------------------------------5 c7 C5 X4 Q9 B! o
    // Name:
    8 [. C2 r7 N: a% X# E" p' r// Desc: calls DisplayConnectionInfo for each connection in a round-robin manner
    ! n3 d+ t' z8 P. }//-----------------------------------------------------------------------------
    " ~, m& p$ l/ S- A1 bvoid CMazeServer:isplayNextConnectionInfo()! n/ {2 ?8 }' i/ E
    {: q( W% X/ L/ W: j0 _0 w' ?, ~
        if( m_pNet )
    $ q. M+ C) t6 e; _2 x8 u    {
    & S+ V7 O5 V: G+ Q        // Find the player that was displayed the longest time ago, and display it.
    - [. u! k% x- g        FLOAT fCurTime = DXUtil_Timer( TIMER_GETAPPTIME );) w* H7 J. k2 a2 ?* y1 T+ W% G
            PlayerData* pOldestPlayerData = NULL;
    2 C: A7 L, O, K4 r5 c2 o        FLOAT fOldestTime = 0.0f;</P>
    - D2 _3 i; m( N+ P<P>        m_PlayerDataListLock.Enter();</P>
    4 h# a, q2 D' Y! M4 N  K/ b, N<P>        PlayerData* pPlayerData = m_pFirstActivePlayerData;. ~4 Q+ ?: `: f, ?5 G
            while ( pPlayerData )
    + I( T% o+ J- n; ^: Z        {2 m% w0 Y) P$ ~( B7 O( ~
                if( fCurTime - pPlayerData-&gt;fLastCITime &gt; fOldestTime )
    - U; F% e! I1 Q* r            {/ F& [9 m1 F$ }  M! X# ^
                    fOldestTime  = fCurTime - pPlayerData-&gt;fLastCITime;
    3 ?" T# k8 Q4 E" C                pOldestPlayerData = pPlayerData;9 E9 p& V9 l7 b  {  M8 s, r
                }</P>
    $ }0 Y  V" h  _! a# s! u5 A<P>            pPlayerData = pPlayerData-&gt;pNext;5 ^$ E: f' I$ ^; }5 s
            }</P>" W- ~7 O* D! l3 ]/ ?6 f/ R: I5 R# }
    <P>        // Display the player with the oldest CI field, and update its CI field.
    6 \$ j9 i( Q) }& L* u. |        if( pOldestPlayerData )7 z* G+ l3 O, |
            {  z) ^% D" [3 v4 p" @6 M
                ConsolePrintf( SLINE_LOG, TEXT("Displaying connection info for next player") );! C4 d* I4 S7 D8 N' |+ q
                DisplayConnectionInfo( pOldestPlayerData-&gt;NetID );8 A# i% J% p# c! e* u0 X  H
                pOldestPlayerData-&gt;fLastCITime = fCurTime;" x5 R) s& x- b* l+ E! n
            }
    ) ]2 ~8 C! j" c. _4 S/ u        else
    & O% Q$ Z1 B- w  A- }/ _        {
      `. K/ H; ~0 r$ a3 k: S            ConsolePrintf( SLINE_LOG, TEXT("No players found") );
    0 O# l4 q  T* j; L' @  H        }</P>
    2 w2 W) s! b) x( V2 y4 d3 B<P>        m_PlayerDataListLock.Leave();
    4 i1 U% `' x/ f9 O    }4 x7 Z' R3 T/ L( J- [& c
    }</P>  U9 u. e! N% a% r/ b4 r

    ! T3 ~5 b% u( {<P>
    : W* J- N6 Q8 O6 _6 H* x# _//-----------------------------------------------------------------------------! F+ F) |: f$ _7 c: N1 N; M
    // Name: 2 q; X$ O% h3 P0 z7 r0 t- F9 J! }
    // Desc: % A4 _# _; @  s$ X* R! L
    //-----------------------------------------------------------------------------
    5 ?" ~  ]: _: H0 Uvoid CMazeServer:rintStats()2 b  o$ d/ ?( a8 ^. u2 Q) k
    {7 F/ Y6 n$ p; F
        ConsolePrintf( SLINE_LOG, TEXT("Thread count: Active=%d Avg=%.2f Max=%d"),
    ! N9 {7 J$ w  o$ U                                    m_wActiveThreadCount, m_fAvgThreadCount, m_wMaxThreadCount );9 u8 j) U9 ?# A# X1 v0 M3 j0 Q
        ConsolePrintf( SLINE_LOG, TEXT("Thread Time: Avg=%.4f Max=%.4f(s)"),
    9 I9 o. S' H7 k                                    m_fAvgThreadTime, m_fMaxThreadTime );
    9 [) A; ^, d0 t8 p    ConsolePrintf( SLINE_LOG, TEXT("Players online (not including server player): %d"), m_dwPlayerCount );
    0 b* O8 d) ^7 E5 i) j8 {6 ~% A+ c    ConsolePrintf( SLINE_LOG, TEXT("Peak player count: %d"), m_dwPeakPlayerCount );
    * f! X' ]0 E$ ?( l$ I}</P>
    ( B* w2 e, m5 ^5 d  J
    * P) m0 V* w$ [( B* p7 k<P>
    - `1 C& a& H, f//-----------------------------------------------------------------------------
    2 m. r  A; i- ]& i  w1 ~// Name:
      C! v* N7 V' X1 x; ^- G// Desc: 8 A5 d, ?1 T) m: M" X4 E
    //-----------------------------------------------------------------------------2 z: d1 `) u& }, H2 ?% H$ J/ d
    void CMazeServer:isplayConnectionInfo( DWORD dwID )8 |# V) C/ U3 z. x+ [' d6 ?
    {
    / G3 A% r1 f4 ^. y5 f    TCHAR strInfo[5000];
    " c8 m# @3 i$ I! Z/ Z) _5 k( N) E    TCHAR* strEndOfLine;
    - ~: w- r2 \- ^' Y; f. r+ }    TCHAR* strStartOfLine;</P>  b6 ~9 s1 S+ k, ?7 s1 @. o- {
    <P>    // Query the IOutboudNet for info about the connection to this user
    ( {6 |" C) `( ?  p    m_pNet-&gt;GetConnectionInfo( dwID, strInfo );</P>! ]  c: U) d5 g
    <P>    ConsolePrintf( SLINE_LOG, TEXT("Displaying connection info for %0.8x"), dwID );3 S/ @7 x! ^2 W$ F4 }0 Y
        ConsolePrintf( SLINE_LOG, TEXT("(Key: G=Guaranteed NG=Non-Guaranteed B=Bytes P=Packets)") );</P>
    ) w6 @, t6 Q0 u8 \7 f+ C<P>    // Display each line seperately3 K; j* ~7 d9 P  X3 D/ i- k( {
        strStartOfLine = strInfo;( V/ w4 M  O! T7 A6 n
        while( TRUE )
    0 I# e* ~/ i3 [2 r9 Q2 D    {
    ) ?0 u3 P$ U1 a/ I: v' _0 Q        strEndOfLine = _tcschr( strStartOfLine, '\n' );3 h2 W/ S3 W2 [5 `% o; v
            if( strEndOfLine == NULL )9 l- R, G! Q% b6 m. l1 G7 g# Y
                break;</P>7 W$ |2 F4 o/ |% u' G
    <P>        *strEndOfLine = 0;
    ; F; U, I8 |. R. Q6 F) M% U. Y        ConsolePrintf( SLINE_LOG, strStartOfLine );% n0 m' I; Q% {( g5 f) Z% [
            strStartOfLine = strEndOfLine + 1;
    . ]# T" G, D! E    }
    0 v3 f/ c* q' x. {3 U}</P>
    ' h% s+ d) {4 ]3 q
    * `2 B) t8 L3 w* W0 Q2 R<P>$ d3 o  u3 t3 P5 W  _4 I! z6 Q
    //-----------------------------------------------------------------------------# b# f! N& }2 Q
    // Name:
    8 l! l/ a2 J9 i( W' [8 g% j7 _1 q! D// Desc:
    6 L2 F( D% U" o# z+ ^8 R! @  H//-----------------------------------------------------------------------------
    8 V6 B( }- f: M. l- P- z9 m& KHRESULT CMazeServer::SendPacket( DWORD to, void* pData,   d! `* t; t* ]  v& L! K) w
                                     DWORD size, BOOL reliable, DWORD dwTimeout )0 M- n+ m$ Q, y1 x* ?
    {# E* F' I, O+ R+ X7 H$ ?& ]0 e
        // Chance of forcing any packet to be delivered reliably2 d7 i, _! Y  J. D& t& c0 s) f
        if( m_Rand.Get( 100 ) &lt; m_dwServerReliableRate ): M# `" Q; z8 q- e. k$ v" Z
            reliable = TRUE;</P>
    4 M3 z2 V0 r; A; C3 u$ w+ p<P>    return m_pNet-&gt;SendPacket( to, pData, size, reliable, dwTimeout );
    ) V: f  h% j" U& x5 K: I. t1 m}</P>$ n! K" c2 B% {( J9 |- x- L8 V

    . b2 D. o9 ^; S7 P9 Y8 W<P>
    . i0 a2 c5 V* V//-----------------------------------------------------------------------------# L/ t% E* Z+ O
    // Name: * @3 w$ a  W' q
    // Desc: # H" Q. F% o$ ^5 ~; ]3 w# _: n
    //-----------------------------------------------------------------------------5 J6 T. p# O; \8 @( f3 Y6 d0 h
    void CMazeServer::SendConfigPacketToAll( ServerConfigPacket* pPacket ); K$ C. a; b- H4 S7 A) E5 f
    {
    / P* o$ ~' p6 q' ]9 h    // If we're up and running, then send this new information to all clients
    # A6 H, R1 E7 {    if( m_pNet )
    # F0 L( M9 b% g- Y5 W# u; w6 i8 M    {: ~7 }$ X0 U. @: T3 T/ y
            //Use the AllPlayers ID9 p) k0 f" ?  C4 x  {6 F( k& n8 u
            SendPacket( DPNID_ALL_PLAYERS_GROUP, pPacket, sizeof(ServerConfigPacket), TRUE, 0 );& m& r: L! v8 N4 `- y
        }7 D  L9 `' [+ E# N$ d
    }</P>" b' g+ G. K, J

    4 r) c/ |% l2 Q# I' {$ i! s' ~( J<P>  G+ K3 z' g& X: p
    //-----------------------------------------------------------------------------' q, c2 d% |( w! ~5 q
    // Name:   d- M# G$ o4 J0 |5 u
    // Desc:
    $ V4 ]$ R& c6 W: B1 h# Y) U//-----------------------------------------------------------------------------
    # E6 J  M" d% O/ c! ?  {4 Lvoid CMazeServer::SetClientReliableRate( DWORD percent )
    3 V) e. x! D7 k- v& e{
    6 g% a$ }7 E/ o0 [/ ^* P, u    // Update client config, and build packet containing that data
    $ k& w/ E" s& z' y1 K, e    m_ClientNetConfigLock.Enter();2 G2 x9 i: U" K
        m_ClientNetConfig.ubReliableRate = BYTE(percent);
    0 h% V8 z, N; F, V5 R, i* T1 k    ServerConfigPacket packet( m_ClientNetConfig );( H. K8 d$ v) P9 t! p# q& \6 Y" j
        m_ClientNetConfigLock.Leave();</P>
    4 V, i+ Z! ^+ H  L9 y9 R6 f<P>    SendConfigPacketToAll( &amp;packet );2 w- V; v1 G* y9 `" V# H1 `7 L  s
    }</P>& E% G8 X" T# W) p& v1 i
    - D! [! Y0 R# s9 c1 ^0 A) m8 e
    <P>
    : A! u# z8 w0 N5 z# o: F//-----------------------------------------------------------------------------
    " S; {1 H; Q3 Q// Name: + i0 h; J0 _2 u& G0 q9 s
    // Desc: 8 v2 _& f8 N: s
    //-----------------------------------------------------------------------------& z0 Q, U" s+ H+ c# I1 i
    void CMazeServer::SetClientUpdateRate( DWORD rate )* r, _8 z6 ]1 T- I  s
    {/ W* J* C7 o* s+ D' P* H6 X
        // Update client config, and build packet containing that data
    / X* P' P6 o' a) p) {6 c4 z    m_ClientNetConfigLock.Enter();1 n+ i( o5 X# V9 P6 k3 k5 X
        m_ClientNetConfig.wUpdateRate = WORD(rate);- R7 D, W" l* s! K
        ServerConfigPacket  packet( m_ClientNetConfig );
    3 \6 R" j" n9 Y    m_ClientNetConfigLock.Leave();</P>4 `/ @9 L) W0 n
    <P>    SendConfigPacketToAll( &amp;packet );* K1 T  p/ Y1 w  r
    }</P>0 |$ H1 `$ y9 X
    1 }/ v. d3 A  M( A3 M% r/ Z1 B. _+ U+ C
    <P>, Y3 a( u: H( [- r
    //-----------------------------------------------------------------------------9 R' c* N7 ~6 w4 g: \
    // Name: , H! Z/ B6 K' C- a- U1 e( H) x
    // Desc:
    * M, k3 m: x/ o' G//-----------------------------------------------------------------------------8 C& Q1 ?& |- ^
    void CMazeServer::SetClientTimeout( DWORD timeout )
    . p$ Q% W/ X0 [) a{
    " s5 k; E1 ~% l1 o) S' d: z    // Update client config, and build packet containing that data+ C% C6 n: b8 [- r* u$ n4 j( m
        m_ClientNetConfigLock.Enter();- K! ^* X0 H( z  y- B  g
        m_ClientNetConfig.wTimeout = WORD(timeout);
    # r, V+ ]1 v6 l$ @5 ]# J    ServerConfigPacket  packet( m_ClientNetConfig );8 ~# @3 a* l6 U4 [0 A
        m_ClientNetConfigLock.Leave();</P>  U9 ]4 X; L3 q- l
    <P>    SendConfigPacketToAll( &amp;packet );( b2 N( g* X: Z5 D6 \
    }</P>7 }$ h3 q8 v& X3 Y" o

    9 W" k. k6 R* Z+ ~% m1 j# @<P>
    3 B: ~3 o: a/ s* I8 f) c//-----------------------------------------------------------------------------
    4 I8 B6 ]  L0 q// Name: 3 w) ]% s) I7 V) G# n: e
    // Desc:
    ) D4 p/ t# o. T//-----------------------------------------------------------------------------
    6 H7 X& n2 B; r# n, G9 ~void CMazeServer::SetClientPackSize( DWORD size )
    * ]$ L9 b4 `- O1 J{
    8 ~2 W* e' R! Z6 d# n5 `: x    // Update client config, and build packet containing that data
    + L2 j7 P8 g1 u8 H; }, o. k    m_ClientNetConfigLock.Enter();
    1 ?! E+ f) N6 l5 e' S    - d' I+ f! Y' q: L3 C2 K
        m_ClientNetConfig.ubClientPackIndex++; //Increase index and verify location in array.2 J% Q* q/ H, w- c7 ?7 _6 E
        if(m_ClientNetConfig.ubClientPackIndex &gt;= PACK_ARRAY_SIZE)   
    4 G, V+ W2 w+ l6 y        m_ClientNetConfig.ubClientPackIndex = 0;</P>
    . u) t! A) C; N<P>    m_ClientNetConfig.wClientPackSizeArray[m_ClientNetConfig.ubClientPackIndex] = WORD(size);
    ; \+ m# A5 V8 H+ }    ServerConfigPacket packet( m_ClientNetConfig );: G3 _* @6 d( \7 P/ S4 l
        m_ClientNetConfigLock.Leave();</P>/ p/ r2 T$ N! o/ Z5 T/ _) s
    <P>    SendConfigPacketToAll( &amp;packet );; m7 l( G+ T6 t9 |: x
    }</P>& E! w( w" |+ s/ ]; m5 A9 ]

    2 D' @7 e) e2 f2 `2 E  T2 s. A<P>
    6 r9 O# ]) Q9 R//-----------------------------------------------------------------------------
    2 J" n, Q$ o0 d% n9 \. E. D  v// Name:
    * e1 E# f1 o& b) b/ S" V// Desc:
    & ~# b0 C) Z3 J. f//-----------------------------------------------------------------------------, s+ n6 H/ I6 D5 R/ W
    void CMazeServer::SetServerPackSize( DWORD size )% k8 c( ^3 \7 F. o& }
    {0 @9 \0 m" N2 }) t0 A
        // Update client config, and build packet containing that data
    2 A8 O. R# X: P' J4 Q5 C) {    m_ClientNetConfigLock.Enter();! D3 H6 Y! T0 g, z& r" [; n8 l
       
    8 \, [# j  L- }, a/ {) M    m_ClientNetConfig.ubServerPackIndex++; //Increase index and verify location in array.* S/ {+ O6 R  h7 A) S1 Z
        if(m_ClientNetConfig.ubServerPackIndex &gt;= PACK_ARRAY_SIZE)   
    7 E3 M5 S% h* Z/ n6 _        m_ClientNetConfig.ubServerPackIndex = 0;</P>
    2 Q' E* i  C, i$ ?4 f( j<P>    m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex] = WORD(size);
    ! X$ n1 \% d$ `& E- t& V0 H    ServerConfigPacket packet( m_ClientNetConfig );
    - n' i1 L" L& a4 J    m_ClientNetConfigLock.Leave();</P>
    & D9 ~7 |0 d" |! y! {" \: W! ]<P>    SendConfigPacketToAll( &amp;packet );) J" D4 @- X, N1 l+ S3 V
    }</P>2 C9 n5 P, W9 a
    <P>
    9 Q# K* j& z, O' z# I% V% v0 N//-----------------------------------------------------------------------------
    , U+ D; t( ~- Q$ m// Name:
    , \2 z+ R% U& B) Q2 P: y2 E// Desc:
    ) p; g+ i) x1 ~+ @' n//-----------------------------------------------------------------------------
    " Y* J% G+ s0 \: Q  t: hvoid CMazeServer::SetClientThreadWait( DWORD dwThreadWait )
    & [( u/ |' q7 h& O, j! c{0 _# G, t( Q9 }+ V
        // Update client config, and build packet containing that data7 A& b4 d5 z0 \
        m_ClientNetConfigLock.Enter();
    9 y" L  X0 x" x/ F    : q& |$ b/ A3 u: M
        m_ClientNetConfig.dwThreadWait = dwThreadWait;
    " L: T& y5 x4 c    ServerConfigPacket packet( m_ClientNetConfig );  i' O; m) j- y
        m_ClientNetConfigLock.Leave();</P>
    7 O  |! F; |8 f<P>    SendConfigPacketToAll( &amp;packet );: d4 y, f9 m, E: i$ ~+ J2 S  h
    }</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-8-9 00:42 , Processed in 0.384797 second(s), 53 queries .

    回顶部