QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 4243|回复: 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>
    % ]1 w  n' t9 ]8 z<>// File: mazeserver.cpp
    * M' S8 s& b# O3 |  T7 \' ]! S- N9 A3 ?//
    " x6 A9 Z2 H. x( v- n. ?// Desc: see main.cpp0 N) i. s3 V1 o5 V# ~; A& {* J
    //
    9 q; G$ g( W5 w! X$ k  S// Copyright (c) 1999-2001 Microsoft Corp. All rights reserved." y$ W2 L  S6 z" l4 N& W' y
    //-----------------------------------------------------------------------------, d$ ^) F% R/ O3 O- w6 U
    #define STRICT& w1 W' ~) p/ y4 V4 y- N8 }
    #define D3D_OVERLOADS
    5 g! H- U9 K6 d. `6 c& ]#include &lt;windows.h&gt;. ?' z0 b& }+ v% `- I
    #include &lt;d3dx.h&gt;
    7 W0 d3 l1 t( [3 v& e/ g#include &lt;stdio.h&gt;$ D, a. H# U1 F
    #include &lt;math.h&gt;& |7 n/ C( W8 @" y* |# q
    #include &lt;mmsystem.h&gt;1 u: d  Q) j5 f7 E& \. G8 O  b0 J
    #include &lt;dplay8.h&gt;/ c3 S5 R# ~; @; [  g2 h) u8 E% F6 L
    #include &lt;dpaddr.h&gt;
    , n9 `& o8 ]9 ?6 k& {: z8 w#include &lt;dxerr8.h&gt;, c- g. H- a+ j7 `" l2 e
    #include "DXUtil.h"
    ( }8 J# b0 D$ _8 C#include "MazeServer.h"
    ; }: Y% s0 r2 o- p/ P" G#include "ackets.h"
    / j# F# d% e9 l" w' O9 }. H#include "Maze.h"
    ( L+ {: F$ H* W3 W, a#include &lt;malloc.h&gt;2 \9 P  D" b. I, g7 [9 K6 |
    #include &lt;tchar.h&gt;</P>8 M$ G4 g( [5 {- h* i: v2 w7 W1 x

      v9 U0 G! A) A& H<>//-----------------------------------------------------------------------------) I( P9 o! x6 N' g5 L7 A
    // Name: ' w3 [! j1 B" o9 m: i! N
    // Desc: # p: l& |1 r7 ~& H
    //-----------------------------------------------------------------------------
    2 y/ y% ?) L1 cCMazeServer::CMazeServer()
      [; V4 B* ?, q( d& e9 m" U{8 y* |( Q: j8 B& @2 |2 G% n
        m_dwPlayerCount         = 0;
    ; I/ J8 Q; z9 \+ ^! W   
    , U6 w. H" x+ W* N/ d    m_wActiveThreadCount   = 0;! ^. x/ a: L# O8 w
        m_wMaxThreadCount      = 0;
    4 Z. t% p6 ?' n    m_fAvgThreadCount      = 0;) F! F, P0 M; T  U5 z' l+ B; W
        m_fAvgThreadTime       = 0;
      k  i& y/ H, c( J    m_fMaxThreadTime       = 0;</P>
    9 ~% b1 i2 P$ X<>    m_dwServerReliableRate  = 15;7 Q7 e0 \8 f& Q& r( P
        m_dwServerTimeout       = 150;
    0 r- _, X% ~7 b7 Y    m_dwLogLevel            = 2;2 G- ?  B+ x: P' k8 @
        m_pMaze                 = NULL;</P># p# L6 N$ b. @, X! b
    <>    m_ClientNetConfig.ubReliableRate = 15;8 Q& E6 W/ z, a
        m_ClientNetConfig.wUpdateRate    = 150;4 d9 R/ o6 J; a8 t. |5 c2 S
        m_ClientNetConfig.wTimeout       = 150;</P>& P' w3 }/ P+ k6 @$ ^$ K
    <>    m_ClientNetConfig.dwThreadWait = 0;</P>
    ( d8 m( F9 K0 g" \! \# P0 ~1 I<>    m_ClientNetConfig.ubClientPackIndex = 0;8 J3 f' W# Z! {2 m$ u
        m_ClientNetConfig.ubServerPackIndex = 0;8 Z0 O" ^' Z! s; }
        for(WORD x = 0; x &lt; PACK_ARRAY_SIZE; x++)
    $ o( \/ H. F8 h( \' H" B1 v    {
    ; d5 Y1 O4 s1 r8 K/ Q+ o" n+ z6 B9 H        m_ClientNetConfig.wClientPackSizeArray[x] = 0;
    : [; Y. l" K; d1 d  F        m_ClientNetConfig.wServerPackSizeArray[x] = 0;! b, ^$ U" ^6 z$ j1 P9 ?
        }
    - K* \5 P" \9 k8 O( O4 K, C}</P>
    : e/ v3 G# F; j( K; m1 b1 y6 U( J. {) y. A
    <>0 e: [: s1 ]$ f) W* V
    //-----------------------------------------------------------------------------5 O) |9 a8 i& y; `3 W/ e8 p# F, J
    // Name: . G+ r  C3 f: `# Z
    // Desc:
    : s- j- ]2 h4 w! t8 Q//-----------------------------------------------------------------------------
    " i8 r& o1 @+ W) @  z, _* QHRESULT CMazeServer::Init( BOOL bLocalLoopback, const CMaze* pMaze )$ U( c2 |% J: V7 z9 o
    {
    . [9 i" U% x& x) p  S" G6 H3 V5 v5 _    m_bLocalLoopback = bLocalLoopback;4 p4 O4 z3 F+ _/ R+ ?) Q
        m_pMaze = pMaze;: E8 O1 t* [7 k# r8 G2 {( ?
        if( m_pMaze == NULL )2 S+ \! Y9 ]  |0 ^
            return DXTRACE_ERR( TEXT("aram"), E_FAIL );</P>: f( {  }+ E" B2 Q
    <>    // Grab height and width of maze
    1 u& L4 w% w  Y7 e0 d' T    m_dwWidth = m_pMaze-&gt;GetWidth();
    / z/ J9 E' z) ?4 H1 p' a    m_dwHeight = m_pMaze-&gt;GetHeight();</P>
    : x, w- e- z! Y, s! U2 Q( h  N# z<>    m_ClientNetConfig.dwMazeWidth  = m_dwWidth;
    ) @, l) S5 x( b1 Y% e# O    m_ClientNetConfig.dwMazeHeight = m_dwHeight;</P>
    " N) u% Q6 f# N% c<>    // Validate size. Must be a power-of-2 times LOCK_GRID_SIZE. Compute the shifts.
    8 A% d8 K; T2 a6 q  }) o    if( m_dwWidth &gt; SERVER_MAX_WIDTH || m_dwHeight &gt; SERVER_MAX_HEIGHT ), N7 N$ W9 z$ L% K  _
            return DXTRACE_ERR( TEXT("Maze height and width need to be less than 128"), E_INVALIDARG );
    6 d0 u7 B, N+ v  T. n) `    if( (m_dwWidth % LOCK_GRID_SIZE) != 0 || (m_dwHeight % LOCK_GRID_SIZE) != 0 )# u# w9 p: k1 F: p9 a! p' [9 h
            return DXTRACE_ERR( TEXT("Maze height and width need to be divisable by 16"), E_INVALIDARG );</P>
    ( m5 f3 Z$ `3 J" y<>    DWORD scale = m_dwWidth / LOCK_GRID_SIZE;% U3 G( \& t' G2 G6 e# S/ G; Y/ x8 `7 Z" O
        m_dwMazeXShift = 0;3 E* s% I1 e% i" F# e' U; g6 _( M
        while ( (scale &gt;&gt;= 1) )
    ; R$ @, H) E7 ^1 ]        m_dwMazeXShift++;</P>/ b0 @: I! q7 ?$ |9 K6 q/ h. _
    <>    scale = m_dwHeight / LOCK_GRID_SIZE;
      L; ?- A, ^$ s8 U1 H/ ^    m_dwMazeYShift = 0;
    $ o) C, {+ K1 R* n    while ( (scale &gt;&gt;= 1) ). [% @0 a6 y9 i; R' {
            m_dwMazeYShift++;</P>* q& ]! M) Q3 O8 Q$ a
    <>    if( ((DWORD(LOCK_GRID_SIZE) &lt;&lt; m_dwMazeXShift) != m_dwWidth) ||
    " r* H% p* u7 `* n7 p        ((DWORD(LOCK_GRID_SIZE) &lt;&lt; m_dwMazeYShift) != m_dwHeight) )
    . L8 k* |. i1 v! i4 C1 D& ]        return DXTRACE_ERR( TEXT("Maze height and width need to be power of 2"), E_INVALIDARG );</P>
    - E! T7 |5 \( X; r- o! G<>    // Initialise the player list
      A7 [, [' ^0 t8 \7 b    ZeroMemory( m_PlayerDatas, sizeof(m_PlayerDatas) );
    & h' S) k. u/ L: t; z% x1 N    m_pFirstActivePlayerData = NULL;# o; \9 C2 p- u" X
        m_pFirstFreePlayerData = m_PlayerDatas;' x& u" ]) U8 X0 {2 A
        for( DWORD i = 1; i &lt; MAX_PLAYER_OBJECTS-1; i++ )* o1 Y, u) Y& X7 n
        {6 v1 T4 ~% x  \* k9 T; [. S/ s
            m_PlayerDatas.pNext = &amp;m_PlayerDatas[i+1];; T- K0 A) G2 y
            m_PlayerDatas.pPrevious = &amp;m_PlayerDatas[i-1];
    5 P* A8 ?6 |( }    }</P>
    * A( K% j. Y* {$ G7 B4 x<>    m_PlayerDatas[0].pNext = &amp;m_PlayerDatas[1];
    ! ^( ~$ B* Q9 C' A# k    m_PlayerDatas[MAX_PLAYER_OBJECTS-1].pPrevious = &amp;m_PlayerDatas[MAX_PLAYER_OBJECTS-2];+ I4 \! N7 {) N7 d) X
        m_dwActivePlayerDataCount = 0;4 F% X0 |  @- _( x, ^- D: o
        m_dwPlayerDataUniqueValue = 0;</P>% Y- N7 m) D0 o" O1 A5 ]2 c
    <>    // Initialise the cells
    & o$ ^% O4 n3 M0 x: g7 f    ZeroMemory( m_Cells, sizeof(m_Cells) );9 ]- z4 i# A" C
        ZeroMemory( &amp;m_OffMapCell, sizeof(m_OffMapCell) );</P>: i2 C. U6 H$ Q4 s5 k2 t% S
    <>    return S_OK;/ K; o* x# V. j, J' P* }+ y
    }</P>
      t0 a1 M8 x9 P$ M6 I( R2 Z6 o* H, o! ?7 s
    <>% u+ J& O- i/ g7 F
    //-----------------------------------------------------------------------------
    5 I& U3 q" J1 D1 F! N// Name: % k  M8 H% X9 q9 f4 t/ \
    // Desc:   w: S9 L/ `1 n5 j
    //-----------------------------------------------------------------------------* Z, E: H: S/ A% m, D
    void CMazeServer::Shutdown()" S" V# u% n7 i
    {
    * h% @& O% N8 I2 E% d}</P>
    * i. |. Z& M$ M, n* r% j. N; L% i
    <>8 D4 l2 L; A0 ^; e2 E% l
    //-----------------------------------------------------------------------------4 `" \! l+ d4 o0 u; q! s0 m" P
    // Name: 5 {# V! ^  e+ b9 W+ L
    // Desc: 6 d" ^+ w/ N! P$ s3 I
    //-----------------------------------------------------------------------------* ?/ F3 e& \) V
    void CMazeServer:ockRange( DWORD x1, DWORD y1, DWORD x2, DWORD y2 ); O4 b) }$ U! C$ I" g! O
    {
    ; r$ \4 E# Y) j' x7 [! m' a2 W    m_LockGrid.LockRange( x1&gt;&gt;m_dwMazeXShift, y1&gt;&gt;m_dwMazeYShift ,- G0 j& N4 p$ j) ]& E0 Q
                              x2&gt;&gt;m_dwMazeXShift, y2&gt;&gt;m_dwMazeYShift );
    ' P% l2 E# J  Q3 N/ M}</P>% [5 Q) g4 ~1 r
    2 u4 p8 Y/ }0 R* D2 A' |8 Z6 Z
    <>, |2 X9 E; O9 r( {0 S
    //-----------------------------------------------------------------------------
    8 x0 V& _0 v& K6 v// Name:
      u/ v+ b' v: D% }/ M6 c// Desc: + w9 ?, s) B$ s- l( B
    //-----------------------------------------------------------------------------
    % M' x" ~2 `9 O4 |# B  u. ovoid CMazeServer::UnlockRange( DWORD x1, DWORD y1, DWORD x2, DWORD y2 ), I& ~& Y/ _8 t, W9 E2 e
    {- I0 v- W0 \$ S7 Z
        m_LockGrid.UnlockRange( x1&gt;&gt;m_dwMazeXShift, y1&gt;&gt;m_dwMazeYShift ,, V, n6 n; A+ o
                                x2&gt;&gt;m_dwMazeXShift, y2&gt;&gt;m_dwMazeYShift );, B) T7 _9 q4 [2 m
    }</P>
    $ G. t  P; I* G: x3 }6 K. ?. A5 H
    4 ^/ V7 h, ~: @; \9 j<>
    5 K; I4 _( `9 s//-----------------------------------------------------------------------------, V4 I# K) x. T. f5 e
    // Name:
    , c5 J9 D8 j1 K// Desc: , u6 j/ T7 l1 ^& ~1 j9 q0 X- L
    //-----------------------------------------------------------------------------7 o# C" |4 v2 R# j) H2 I
    void CMazeServer:ockCell( DWORD x, DWORD y ); ?6 \) Z4 i8 _' B4 T& `  Q$ j
    {, }* S' J1 p# d$ {( f+ }6 M5 J
        if( x == 0xffff )
    6 l: d3 I1 w7 d        m_OffMapLock.Enter();9 h: K9 K+ G" @2 }5 y3 m
        else- r* Z4 Z* b' m: s& i3 A6 V3 e
            m_LockGrid.LockCell(x&gt;&gt;m_dwMazeXShift,y&gt;&gt;m_dwMazeYShift);$ F3 b: i/ c: D, J
    }</P>7 P- J, [) \6 U% `

    ' p0 g* r8 e5 I  I" Y<>( }/ y4 {" L  e  D8 g
    //------------------------------------------------------------------------------ r! S; w: ?3 V5 w! M
    // Name:   k! P( @1 e. o1 R0 O6 y
    // Desc:
      }8 h) ?' {! r( |: K$ |# i$ `//-----------------------------------------------------------------------------+ V. X  R) n' r8 z' Z/ N
    void CMazeServer::UnlockCell( DWORD x, DWORD y )
    8 U  b/ }- n' d. y- R) S) W{+ \7 S8 m' i) \+ O9 D
        if( x == 0xffff )4 `# X  `3 n  U* @" o% p
            m_OffMapLock.Leave();) ]% g2 F* _3 U- P
        else3 ^' Y0 u# t, y' v! X, I
            m_LockGrid.UnlockCell(x&gt;&gt;m_dwMazeXShift,y&gt;&gt;m_dwMazeYShift);
    0 s+ P- g2 ~- [}</P>! |$ `, D) \5 j: U
    * L, [' y6 O4 _/ H3 r5 V
    <>4 K4 ?+ d3 ~! y% m! H- L, k
    //-----------------------------------------------------------------------------/ E( [7 H4 u) D3 \/ p9 P- y
    // Name: 3 p/ G: O: G5 m; y  c
    // Desc: 6 \/ b5 w$ Q& g/ a6 k
    //-----------------------------------------------------------------------------
    6 T: P8 n1 |/ ~void CMazeServer:ockCellPair( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )) N2 L. [4 B/ a/ |% v* s
    {
    6 S, b4 f: x3 Q4 z+ m    if( x1 == x2 &amp;&amp; y1 == y2 )
    5 A9 m0 V% O: v2 M5 [0 ]7 p) Z6 o    {; z0 ]  X# J7 U" `, L8 Q
            if( x1 != 0xffff &amp;&amp; y2 != 0xffff )
    " m& Q' \. W$ t6 @; Z+ T            LockCell( x1, y1 );& C7 l8 x" }- g% |7 C& O( K
            else
    . g) S& G' Y! \3 z3 {            m_OffMapLock.Enter();</P>9 {8 O0 G6 l/ B- t' ^
    <>        return;2 z* j4 H( n3 |( W3 O8 V
        }</P>1 J; w% H# [% ?
    <>    DWORD x1shift = x1&gt;&gt;m_dwMazeXShift;
    + V3 j& s! }/ ]9 ^: x    DWORD x2shift = x2&gt;&gt;m_dwMazeXShift;; d- u5 [  {3 C8 M$ v4 P  D3 P2 q1 H
        DWORD y1shift = y1&gt;&gt;m_dwMazeYShift;
    : W9 {  [7 X; T    DWORD y2shift = y2&gt;&gt;m_dwMazeYShift;</P>5 a' H$ u# s* p/ W7 F, s8 w
    <>    if( x1 == 0xffff )
    . n$ Z3 ?, B. ?0 x' |    {
    9 u. F" M1 P$ |" k8 g        m_OffMapLock.Enter();
    % x7 z) E' a, d- c0 I. c) n        m_LockGrid.LockCell(x2shift,y2shift);7 S' O# x( S* w2 v& E& e
        }+ ~8 X( i4 ^* J
        else if( x2 == 0xffff )1 ?2 K1 ]. G2 g
        {
    4 `0 `5 ~, v' B. z% x        m_OffMapLock.Enter();
    & c0 g  A+ q) y2 z        m_LockGrid.LockCell(x1shift,y1shift);& R- h6 c- H7 G" D7 X4 U8 R5 J  i
        }0 E+ y/ O6 u" N9 y9 Z* F6 X6 ]+ `
        else $ L/ F# a' h" [
        {* ?2 K4 y1 a2 x
            m_LockGrid.LockCellPair(x1shift,y1shift,x2shift,y2shift);
    % U. @. w7 C3 I    }( `8 s; M, W5 v5 ?
    }</P>  U2 l! a4 `% u- Z) J+ W! ], r- _
    % `: G) u/ B9 n5 u) m) C' j1 m
    <>6 J9 Y) P# X2 S' a+ p. |& `8 B8 l
    //-----------------------------------------------------------------------------! O  @& p' x7 Y
    // Name: & N1 r0 J! V5 |: k+ q" J
    // Desc:
    , I, D8 B+ ~; }9 u1 a//-----------------------------------------------------------------------------3 k0 {" F; A  ^3 z/ x
    void CMazeServer::UnlockCellPair( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )
    ' k) z$ T6 ^, ~* H+ |6 S% }{! S) U' I$ G) \! u% u$ R
        if( x1 == x2 &amp;&amp; y1 == y2 )" j& X3 Z. i( N+ D( {* ^& J
        {0 ~& h' H5 I; E2 r4 b
            if( x1 != 0xffff &amp;&amp; y2 != 0xffff )
    " h$ I/ P6 }7 `! C; B  `$ R/ Q& u            UnlockCell( x1, y1 );/ ?$ g2 l: Q6 x6 I# G
            else
    8 ]/ _7 g& v# d; j/ G& s/ H3 q            m_OffMapLock.Leave();</P>, a9 c/ z, x% Q/ i. q
    <>        return;
    7 E9 b6 |! O# ?( f    }</P>5 P& t5 B/ l2 V" ~/ \0 A3 n9 ]
    <P>    DWORD x1shift = x1&gt;&gt;m_dwMazeXShift;
    5 z( C3 `6 o* s8 E6 @, w    DWORD x2shift = x2&gt;&gt;m_dwMazeXShift;
    * H/ d+ B0 s7 d/ ]    DWORD y1shift = y1&gt;&gt;m_dwMazeYShift;
    8 n; s7 R5 w6 o2 {    DWORD y2shift = y2&gt;&gt;m_dwMazeYShift;</P>% C/ S# s1 T! |8 |- [- `
    <P>    if( x1 == 0xffff )/ W# R3 t$ \/ \5 {# R
        {) p' T7 v2 I, P; Z0 f3 j1 o( K2 p
            m_LockGrid.UnlockCell(x2shift,y2shift);9 A8 E1 ]- E4 q( m" k& \
            m_OffMapLock.Leave();
    ( I% s3 s* `% P    }0 }: a' b$ O  c4 }4 s
        else if( x2 == 0xffff )" K8 v: P: g* _4 P) g- Z4 i9 p0 z
        {
    9 ~- _) w2 W! q        m_LockGrid.UnlockCell(x1shift,y1shift);" K. K9 j, t( @. K* S- W
            m_OffMapLock.Leave();
    ; q  Q& t8 P1 l( t5 J" m& v$ t    }( @. Q, Y" [; c1 z
        else
    , {3 W4 N1 p5 T, u    {5 p2 ~/ N& y9 D2 j
            m_LockGrid.UnlockCellPair(x1shift,y1shift,x2shift,y2shift);" {4 t3 @9 i: ^# H; C% Z, ]
        }
    ; @# Y) D) Y8 P}</P>5 R6 L# T, o+ }/ H, @2 c% d) ]

    ! B: |# x" b0 p/ G<P>
    * k9 v/ z/ r3 ~- y//-----------------------------------------------------------------------------
    6 |- Z4 o$ G" _) i+ K$ y* K  O7 ~% t// Name:
    4 a3 e) c! ?0 P2 L; a6 s0 \5 `; ?( i// Desc:
    % N: i5 K  {- G//-----------------------------------------------------------------------------
    1 g" X/ A" b* i- P; }0 u5 ovoid CMazeServer::OnAddConnection( DWORD id )# D$ }( U) }; r
    {
      k% |+ U# M# o: p3 e    m_AddRemoveLock.Enter();</P>6 D+ P6 n0 _) @& p0 {  @
    <P>    // Increment our count of players( n+ }8 o/ J) U7 z1 L
        m_dwPlayerCount++;
    9 C; c& }0 h  ^5 d    if( m_dwLogLevel &gt; 0 )
    * Z  H7 I( F7 ?1 c5 Y& n1 S# R    {
    " Q; C! n" U0 ?        ConsolePrintf( SLINE_LOG, TEXT("Adding player DPNID %0.8x"), id );$ Q! @; E4 x+ s8 R% W% T
            ConsolePrintf( SLINE_LOG, TEXT("Players connected = %d"), m_dwPlayerCount );
    1 U1 a; s' C# s    }</P>
    2 v1 I0 ~+ F; C0 [, c, j<P>    if( m_dwPlayerCount &gt; m_dwPeakPlayerCount )
    0 R, t. f4 q0 J! x        m_dwPeakPlayerCount = m_dwPlayerCount;</P>
    2 ^6 C4 a6 G' d# t# J: z- ]<P>    // Create a player for this client
    & @3 f- C5 W/ U1 C3 ~! D    PlayerData* pPlayerData = CreatePlayerData();
    ; H0 z; G) R9 \. [' Y' s% T) D/ T2 j    if( pPlayerData == NULL )
    + P" K% z, C- S9 {2 }4 {0 k    {
    1 a" O. g1 R3 a0 E: Y, z8 I0 T        ConsolePrintf( SLINE_LOG, TEXT("ERROR! Unable to create new PlayerData for client!") );
    ; R9 L. N( s$ [% j- ^! P        DXTRACE_ERR( TEXT("CreatePlayerData"), E_FAIL );
    $ X. V) N8 P! G8 T        m_AddRemoveLock.Leave();( M# U( L% A% R) F' ~5 [
            return;( b3 s( v1 ~* ?& N  }6 W0 c: Y
        }</P>  M1 P( x" N1 T/ a8 K+ W4 C1 V+ J( ^
    <P>    // Store that pointer as local player data4 q) e4 S% E( v: r7 S
        SetPlayerDataForID( id, pPlayerData );</P>
    0 V. |, t9 q0 p- P! Y, Q' r8 v% i<P>    // Grab net config into to send to client
    ; |& c# H1 h% m6 v0 e) I    m_ClientNetConfigLock.Enter();1 s( E. o* u0 U9 J7 \' _1 f
        ServerConfigPacket packet( m_ClientNetConfig );
    0 m2 C# [3 b% ^5 u) H' {    m_ClientNetConfigLock.Leave();</P>
    ( K. Q6 _$ w8 v# A: I9 W$ `. N4 }<P>    // Send it
    % |& x5 N& {, s& p6 w+ n& |0 j% j    SendPacket( id, &amp;packet, sizeof(packet), TRUE, 0 );</P>1 @: v. f+ u5 R9 a; ~3 `* i8 v
    <P>    m_AddRemoveLock.Leave();
    + G) m- R* [1 K# d/ X9 r}</P>" E* f) f, ?% ]- I( o
    2 q' c2 Q' h- k( Q
    <P>% L" T+ A4 z( I+ K/ m, L
    //-----------------------------------------------------------------------------
    - V  P/ X- N' j5 r* t( L0 V// Name:
    $ c7 m) I" y$ ?// Desc:
    # T. `. W8 e1 ^: i, s: V9 R% g//-----------------------------------------------------------------------------: U  N9 C! r2 }" q1 `1 J0 K
    void CMazeServer::OnRemoveConnection( DWORD id ), M' o6 r. l- j: h" n, z
    {
    7 e3 [! O3 e8 T    m_AddRemoveLock.Enter();</P>" ~& {. q& d" T6 d4 n6 O( p
    <P>    // Decrement count of players7 V1 |9 m1 ?9 y( q3 |
        m_dwPlayerCount--;</P>
    $ b6 C1 e! w, Q  W* B9 |# t/ }<P>    if( m_dwLogLevel &gt; 0 )- V' `  ]% u) l0 @3 e4 i! a
        {* j2 m* l! `5 n/ ?! Q
            ConsolePrintf( SLINE_LOG, TEXT("Removing player DPNID %0.8x"), id );" A8 T$ }# \5 X  ^+ \
            ConsolePrintf( SLINE_LOG, TEXT("Players connected = %d"), m_dwPlayerCount );
    6 {. ^9 S  Q; m: x4 z0 g2 J    }</P>
    % Z2 S5 A7 R8 K1 g$ B  W<P>    // Find playerdata for this client$ J0 b; V- _6 m9 Q1 Z
        PlayerData* pPlayerData = GetPlayerDataForID( id );. y1 B/ m' L! @. }+ d* B
        if( pPlayerData != NULL )
    . o. M5 l3 s3 V( Q3 ~    {% \2 Y; D$ @2 l  h- W, P4 p% E9 e
            // Destroy it
    " ?0 Z1 M8 q$ T        RemovePlayerDataID( pPlayerData );$ h4 J2 ]. q, w9 s: E( }
            DestroyPlayerData( pPlayerData );6 O( b# [, ~2 n: r& C. {5 {
        }</P>( M( ?+ j2 m3 E8 l3 F
    <P>    m_AddRemoveLock.Leave();6 V1 s/ y+ j2 c) I1 M9 `  j
    }</P>. O" m# j' X1 s: |# P

    7 u2 a" u* |! L<P>+ x2 e8 f1 A! K! M
    //-----------------------------------------------------------------------------$ U- R0 Z1 f  c. }9 W0 P
    // Name:
    6 V3 t, H9 v; R' @& V$ ?; Q9 p) h// Desc: + Y) }' m9 N/ B5 ]' E( ?; [" F
    //-----------------------------------------------------------------------------
    3 F, K$ Z! K8 IHRESULT CMazeServer::OnPacket( DWORD dwFrom, void* pData, DWORD size )* t% u7 y+ }% |4 ~- {
    {
    " I$ l" l$ Z0 a    BOOL fFoundSize = FALSE;</P>
    / Z% N, S1 y& m* U( h: M0 z. j<P>    // Increment the number of thread we have in this process." C) X. Z/ m+ y% Q( R- z+ ~
        m_csThreadCountLock.Enter();</P>
    * ?* S! t1 H. ^. C7 D<P>    //Get the start time of when we entered the message handler.8 t: S9 y  k2 U+ Y
        FLOAT   fStartTime = DXUtil_Timer( TIMER_GETAPPTIME );</P>5 `5 n0 f  ^7 A% M6 E+ f1 `0 d
    <P>    m_wActiveThreadCount++;
    % U8 t2 h7 G7 T3 s* J+ b    if(m_wActiveThreadCount &gt; m_wMaxThreadCount). o/ o! [7 m! n3 _; s
            m_wMaxThreadCount = m_wActiveThreadCount;" i# e: ]5 X/ ~
        ( ~& c/ e( O3 K
        // Calculate and average.
    ; u- X2 m: }" k# e+ u& t" y    FLOAT fdiff = m_wActiveThreadCount - m_fAvgThreadCount;
    + E" s- y9 m3 P+ x: Y3 Y    m_fAvgThreadCount += fdiff/32;0 G! d. v) z3 E  \8 \
       
    3 q- X( N( ]: t0 }1 v    m_csThreadCountLock.Leave();</P>2 b5 ~4 U6 M' z
    <P>
    % b. W# x& a- Z! S9 Q. E    ClientPacket* pClientPack = (ClientPacket*)pData;4 h/ U; W! z. {2 E# H
        switch( pClientPack-&gt;wType )/ D) X0 K* O' k! }; o4 `& K
        {
      O, f- e0 U1 x& I( e, ^& X4 S        case PACKETTYPE_CLIENT_POS:6 w: ~- t# z* d/ g$ Y
                
    , y& u/ q9 Y! O9 v            // Check to see if the packet has a valid size. Including 7 b1 S7 r: Q& T7 M
                // the custom pack size.4 J' j& S5 S+ C! ~/ M
                if( size &lt; sizeof(ClientPosPacket))+ Y1 |% G3 K( S" C- ^
                    fFoundSize = FALSE;
    1 G( Q/ L7 s' W0 H% O9 w0 [            else if( ! IsValidPackSize(size - sizeof(ClientPosPacket))), p; l( x3 g# d; Q. Q
                    fFoundSize = FALSE;
    " A7 V  l- e  d            else( h( q6 {8 K) t8 D3 g+ ?$ E
                    fFoundSize = TRUE;</P>
    # {  ~* y# T. E, {<P>            // If valid sized packet, handle the position.
    + W8 \, t" C1 I" a- F- z* [! k6 j            if(fFoundSize)6 t" ]$ J8 y  G
                    HandleClientPosPacket( dwFrom, (ClientPosPacket*)pClientPack );# ^; Z* Y- D( h3 B' ~7 ]0 [' g) R
                else
      O: z( S/ {4 X! q& L& {9 i1 j                m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );</P>
    - ^+ V- X: g1 |8 k6 U3 c! r- g& q<P>            break;</P>
    : V8 a- k6 Z3 L<P>        case PACKETTYPE_CLIENT_VERSION:) |) S- t# y$ J/ Z" ]
                if( size == sizeof(ClientVersionPacket) )
    4 i0 f5 Q" Z6 a7 [" _                HandleClientVersionPacket( dwFrom, (ClientVersionPacket*)pClientPack );
    4 t6 \) X0 ]8 O            else
    % Z. ~8 Z; s2 G( `8 D                m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );
    7 w5 }0 m7 Q4 H; a. d% M            break;</P>
    " Y" P) i% y5 W. ]1 s9 k! u: J<P>        case PACKETTYPE_SERVER_CONFIG:</P>
    $ |- v8 z$ t3 C3 {6 o<P>            // Server config packet sent to all users (including server). Just ignore and continue.</P>* {1 o5 g' B1 l+ z# _
    <P>            break;
    ! ^1 J: o* E2 B. T0 J' ?6 O        default:
    $ k" z# R% B. o9 }5 t) k* }            HandleUnknownPacket( dwFrom, pClientPack, size );/ v' _+ w1 ]$ A+ P
                break;
    ( a4 f% J+ y: l+ s    }</P>
    3 C. x5 S7 b2 k+ k1 [<P>    //If the user wants to hold the thread, Sleep for given amount of time.
    1 S+ A( r1 p" Z7 W7 p5 D    if ( m_dwServerThreadWait &gt; 0 )" f  o. G( I5 o3 T
        {
    & a4 r, O# |8 `6 m% q5 B1 e        Sleep( m_dwServerThreadWait );
    1 m  z+ |0 m& [- n% B    }# F0 T$ ~0 V' \
        : z$ q. N/ R2 G* e
        // Retrieve thread data for this process.; I. C* p7 D" C2 n, ~. d
        m_csThreadCountLock.Enter();</P>2 \% z5 i$ m4 T$ V; {5 ?5 P
    <P>    m_wActiveThreadCount--;</P>
    ; I: ?( `8 f2 ]/ K( ?<P>    FLOAT fDiffTime = (DXUtil_Timer( TIMER_GETAPPTIME ) - fStartTime) - m_fAvgThreadTime;
      s2 T3 |# x2 |* e; n$ C    m_fAvgThreadTime += fDiffTime/32;</P>; v& }" W# S) ^! d# B, J/ \) i
    <P>    //Get the Max time in the thread.
    1 o! X+ l. U3 k6 E0 b+ T  C( H    if ( fDiffTime &gt; m_fMaxThreadTime )
    8 O2 R- I6 G( Z- `    {
    9 \- p5 B  I6 U2 ~5 m5 @        m_fMaxThreadTime = fDiffTime;. ?) j! {/ T! {& b8 Z- w+ A
        }</P>9 T2 t& z! X$ Q( a& `* Q! t2 H
    <P>    m_csThreadCountLock.Leave();</P>( ]- |7 c: Z% j$ Q- ?  [3 [
    <P>    return S_OK;
    9 ^5 o& x+ F" W8 r2 \7 m8 D8 S}</P>$ `9 H- n4 r+ f; j5 T) Y

      E1 D4 }# S# `6 D<P>//-----------------------------------------------------------------------------( a, K5 k1 ^' g8 ?1 K) O
    // Name: 9 V$ v8 ]& e6 g$ _! g2 b
    // Desc: % P0 p7 |- C; R2 E) g
    //-----------------------------------------------------------------------------; d! \1 K% e* Y/ T
    BOOL CMazeServer::IsValidPackSize( DWORD dwSize )" J8 p( H' g: Z1 K8 a) c' }
    {
    % Z5 i# p  \) E9 |" p: m/ M- ^    BOOL fFoundSize = FALSE;
    6 \$ R$ D& @6 G# N! R* J    BYTE ubPackLocation = m_ClientNetConfig.ubClientPackIndex;
    ) z0 I5 V3 c- P   
    ; L3 V$ f7 n8 B) w# R    // Check through the array of valid pack sizes.
    7 X; {9 Z# d$ V" K    if(dwSize != m_ClientNetConfig.wClientPackSizeArray[ubPackLocation])3 t) K3 I! ?3 g) y8 G
        {
    3 |/ j1 ?: n4 N$ ^( T# Y9 v* ~        for( --ubPackLocation; ubPackLocation != m_ClientNetConfig.ubClientPackIndex; ubPackLocation--)
    % ^! U0 V6 |6 h+ H1 d( i/ q        {6 M. \8 \6 m* M% H
                if(dwSize == m_ClientNetConfig.wClientPackSizeArray[ubPackLocation])" D5 {' ?% k( u% a4 J# l& U5 u
                {' i- g  p5 R/ y# {
                    // Found valid size in the array.
    4 K; Y$ J0 r4 s5 M( v                fFoundSize = TRUE;. O8 R' W6 I/ W: U. Q& [3 T
                    break;% L- d0 A1 r" P* w  k
                }
    + M% _1 q1 p( m7 l6 |7 @) @' W. c, E  c            if(ubPackLocation &gt;= PACK_ARRAY_SIZE)  ubPackLocation = PACK_ARRAY_SIZE;  //Wrap the array.
    ! n  B% x: H# q3 q, V) F2 b        }
    $ V4 _0 Z" m, K8 m* h    }2 E' ]7 k% t' _, o; Q7 Z
        else, ~7 v& W3 j, u) `
        {
    2 ^# ~4 j& t, L6 A: C        fFoundSize = TRUE;5 H# G1 B" T) ]# L/ v
        }</P>! `5 @& @. j, W. X' d+ a
    <P>    return fFoundSize;2 Q* |' I( Z+ E0 Z1 g, E( r9 B, L" \% O
    }</P>
    7 o/ l' G# k1 C; F/ d* M<P>& ~4 h& v; |  e8 Y1 @+ n
    //-----------------------------------------------------------------------------0 _# _3 D6 G' f; x, x  p
    // Name:   E8 _# K) G1 Z- x
    // Desc:
    0 h5 K0 A1 |4 a8 N5 ^: p& U  C//-----------------------------------------------------------------------------
    6 v5 d5 Q( H! j: H2 q8 Ivoid CMazeServer::OnSessionLost( DWORD dwReason )1 h4 ]" K* K  l* d/ p# W6 s
    {3 ^8 J5 b9 Q  }$ ]# s
        ConsolePrintf( SLINE_LOG, TEXT("ERROR! Session was lost") );
    1 o, \( j5 M9 l2 E8 u1 Z" D  Q2 W}</P>9 |$ u8 Z/ k' H4 ^0 A, f: D

    6 [4 w: G; J* |+ L* z7 s" r<P>6 Z+ T1 N' U% F- E& o4 {
    //-----------------------------------------------------------------------------0 u+ f. l6 k7 U6 ?) n
    // Name:
    / y. ?) t2 I; L( \% p& k// Desc:
    ! i7 D, F/ P3 R8 l% a& Z; o//-----------------------------------------------------------------------------, @) D; y  d  P: f* F5 o
    PlayerData* CMazeServer::CreatePlayerData()
      a& x) k% w+ h5 p{
    8 N$ |: i5 d' R+ j    m_PlayerDataListLock.Enter();</P>( r4 N) K9 d$ H& U, ^( A
    <P>    // Grab first free player in the list
    % K5 z" Q6 f% Z' B- B; |' _+ c    PlayerData* pPlayerData = m_pFirstFreePlayerData;</P>" _. S8 F9 H) ]) a
    <P>    if( pPlayerData )$ ?* J% Y0 R, k4 F: ~. u
        {
    + u& e( A( K, b        LockPlayerData( pPlayerData );</P>
    - s2 @7 `; w+ m) H5 A$ [$ v<P>        // Got one, so remove it from the free list' F( q6 {3 Q. P
            if( pPlayerData-&gt;pPrevious )1 G: u9 q- S7 [  A- M3 p
                pPlayerData-&gt;pPrevious-&gt;pNext = pPlayerData-&gt;pNext;3 [( K7 j1 d( f
            if( pPlayerData-&gt;pNext )5 r' W& T# v( w
                pPlayerData-&gt;pNext-&gt;pPrevious = pPlayerData-&gt;pPrevious;9 L! c( W- U# L' r
            m_pFirstFreePlayerData = pPlayerData-&gt;pNext;</P>
    9 g4 E( g  a, G8 q6 _<P>        // Add it to the active list. n! V5 n& I# Q" Y( J' c
            if( m_pFirstActivePlayerData )2 \0 ]7 [3 r' g/ g' Z. w
                m_pFirstActivePlayerData-&gt;pPrevious = pPlayerData;" c- B: A% ~2 y9 `+ ?/ j1 ~
            pPlayerData-&gt;pNext = m_pFirstActivePlayerData;
      ^/ U; q" |* W1 m9 {        pPlayerData-&gt;pPrevious = NULL;- B- C1 }( u5 I; r) L: k! H# f% f" O
            m_pFirstActivePlayerData = pPlayerData;</P>! ^& S$ x$ |2 P1 ]1 ^
    <P>        // Update count of players, V  s* _! N8 x& ~9 b, k6 X4 }
            m_dwActivePlayerDataCount++;</P>/ P& I0 u' {6 @: L& M
    <P>        // Generate the ID for this player5 @2 \  d; s  J7 Z
            m_dwPlayerDataUniqueValue++;5 B" k; n0 M( n
            pPlayerData-&gt;dwID = (DWORD) ((pPlayerData-m_PlayerDatas)|(m_dwPlayerDataUniqueValue&lt;&lt;PLAYER_OBJECT_SLOT_BITS));</P>! I! I% j8 l+ t  u# m9 ]6 s& [
    <P>        pPlayerData-&gt;pNextInIDHashBucket = NULL;
    & p8 ^: b1 c& c. x4 c8 A% _        pPlayerData-&gt;NetID = 0;
    ) @0 l3 \# S* K5 J' y! E. h        pPlayerData-&gt;dwNumNearbyPlayers = 0;</P>
    8 i8 q. k7 z8 m4 o- N- z<P>        // Insert into the "off-map" cell% ]) q6 b+ m+ H% H# ~. V9 A
            pPlayerData-&gt;fPosX = pPlayerData-&gt;fPosY = -1;8 \  l# M  c! k* o1 \+ d6 ?2 H
            pPlayerData-&gt;wCellX = pPlayerData-&gt;wCellY = 0xffff;1 ~' l* F: J# i- {9 z3 K( F6 T. v
            m_OffMapLock.Enter();
    + S* n! C' k' \3 W# M$ c        pPlayerData-&gt;pNextInCell = m_OffMapCell.pFirstPlayerData;
    ; e3 i0 _# u* m# C& j! q        m_OffMapCell.pFirstPlayerData = pPlayerData;* n' W% a1 X6 ^+ p! `) Z
            m_OffMapLock.Leave();</P>
    / X" m2 |' m" V& y. O$ V<P>        // Mark as active) ]) ?( C+ m7 S2 f
            pPlayerData-&gt;bActive = TRUE;</P>, z. ~! q( e. ]$ `$ l1 l: a
    <P>        UnlockPlayerData( pPlayerData );* m# R1 G6 c0 X9 X8 v
        }</P>6 W0 h+ R) ^/ V7 q, o
    <P>    m_PlayerDataListLock.Leave();</P>: @; U6 v0 T9 N! Y
    <P>    return pPlayerData;
    + T. W8 G0 X9 P}</P>  ?& \) P8 k. A6 u4 s  e$ `
    2 @& V% f$ y, ?, S
    <P>* I" ^8 ]+ y: a
    //-----------------------------------------------------------------------------& N' g4 `5 T$ v1 U) |3 p" w
    // Name:
    , W3 [* {8 r+ s5 m// Desc:
    5 |$ B- S( d1 u" o8 u//-----------------------------------------------------------------------------
    2 |' c! I1 B! j" \void CMazeServer:estroyPlayerData( PlayerData* pPlayerData )
    $ T& t5 O5 @* b  e" l{
    # y& {* z1 F. j, u( Z    m_PlayerDataListLock.Enter();" _' K+ U3 `" c) |! U. J1 V: m  C
        LockPlayerData( pPlayerData );</P>  d! x% k4 c' P
    <P>    // Remove the player from its cell
    ; [! C7 |/ P% T. Q3 J* b! @$ Z    RemovePlayerDataFromCell( pPlayerData );</P>
    9 Z3 u5 {8 x+ U0 T, `2 ^<P>    // Mark as inactive) |" Y: k  d6 f# \
        pPlayerData-&gt;bActive = FALSE;</P>
    ' w1 y: I  [4 c- Q<P>    // Remove player from active list
    , e5 O& |. ~* V1 C* e7 c    if( pPlayerData-&gt;pPrevious ); c, `) g2 ]$ k6 h4 A9 C
            pPlayerData-&gt;pPrevious-&gt;pNext = pPlayerData-&gt;pNext;- J* J& B4 I6 \8 ]" `+ O
        if( pPlayerData-&gt;pNext )
      k& l5 L# u0 w. g' d0 `7 K        pPlayerData-&gt;pNext-&gt;pPrevious = pPlayerData-&gt;pPrevious;</P>
    ( q2 ]# t* k- {; `+ t8 q<P>    if( m_pFirstActivePlayerData == pPlayerData )
      L$ `5 S+ V# c+ L2 Q# W4 Q% v        m_pFirstActivePlayerData = pPlayerData-&gt;pNext;</P>' k1 K4 a9 h  I" B; ?$ q) F
    <P>    // Add it to the free list9 l8 y9 y2 e; F5 d9 @, E
        if( m_pFirstFreePlayerData )
    * ?# a6 |. {9 G' Z9 @        m_pFirstFreePlayerData-&gt;pPrevious = pPlayerData;, k* W2 q6 B% g) v: O# [
        pPlayerData-&gt;pNext = m_pFirstFreePlayerData;
    2 c# E" T7 v! O! w- P7 p% m    pPlayerData-&gt;pPrevious = NULL;
    9 h2 R. D0 j5 A% I; p    m_pFirstFreePlayerData = pPlayerData;</P>
    ( x- m: a3 c/ ?: N! m<P>    // Update count of players& R# I% V- ^$ p/ }
        m_dwActivePlayerDataCount--;</P>
    , Z8 \/ q* s+ e3 b. Q( z<P>    UnlockPlayerData( pPlayerData );- Y4 r2 S% x3 U
        m_PlayerDataListLock.Leave();* Y; G% g+ i7 C, ^1 @. s
    }</P>" B5 A" h. ?& m& z2 F- q! W

    7 `) g0 ?7 _7 d<P># \$ b( Y* h. K) y5 _# ?, ^
    //-----------------------------------------------------------------------------+ J- {3 X) c$ T, H  L% o1 L: a
    // Name: ' l7 p' g, c& ^8 Z
    // Desc:
    : N! O: A. }/ e//-----------------------------------------------------------------------------
    ' E4 z* A0 B9 f# R# Ovoid CMazeServer::RemovePlayerDataFromCell( PlayerData* pPlayerData )( D; g: v, m5 J; z
    {
    4 y- X7 V/ h6 b: O1 ^. E0 r1 B    // Lock the player
    2 `- A3 k: U& c7 j    LockPlayerData( pPlayerData );</P>, x  P! V* o6 u7 f. n
    <P>    // Lock the cell the player is in
    0 @! a* `5 \9 `/ v" y9 V    ServerCell* pCell;
    " i$ ]# @0 P9 u5 x0 V: `    if( pPlayerData-&gt;wCellX == 0xffff )
    4 Y9 I5 `$ p8 ~1 k: Z4 m% c! j    {  H3 b2 A8 M6 e, z2 P8 t
            m_OffMapLock.Enter();7 q) f4 m% O3 T2 B# v6 ?. L
            pCell = &amp;m_OffMapCell;
    / @$ J% j  r, u8 c    }
    ' y) u0 a1 h  t. P% T    else
    ' j/ L' Y1 X$ x    {% e! D' @9 h  Q) V
            LockCell( pPlayerData-&gt;wCellX, pPlayerData-&gt;wCellY );' U; {' q( l; i
            pCell = &amp;m_Cells[pPlayerData-&gt;wCellY][pPlayerData-&gt;wCellX];
    5 `6 D; ~) ~7 E; }    }</P>0 H6 N! N, w& f
    <P>    // Remove it from the cell% k: n# V5 X' t" u  t5 F
        PlayerData* pPt = pCell-&gt;pFirstPlayerData;
    7 X+ v2 E0 K$ D    PlayerData* pPrev = NULL;
      `' ^/ S; |: z7 A% D    while ( pPt )3 j- n  K$ U/ W: H
        {! n3 k4 f) A0 F8 z
            if( pPt == pPlayerData ). v4 h% w! U' @2 j# R) l
            {
    # p6 x2 A+ J$ T9 q            if( pPrev )
    : p6 w6 Z2 A, h4 z; P                pPrev-&gt;pNextInCell = pPlayerData-&gt;pNextInCell;
    7 Y0 L6 ?& k7 K$ R& ?+ J; u# v            else
    - b+ r# |- r/ Z! I                pCell-&gt;pFirstPlayerData = pPlayerData-&gt;pNextInCell;</P>& w- T! q1 B4 s5 `
    <P>            pPlayerData-&gt;pNextInCell = NULL;
    4 ~3 Z' c2 n* l5 K            break;& B3 u: K. o- [/ E& R; m
            }/ e1 ^- ]; m+ O8 l8 W  y
            pPrev = pPt;$ G' u$ o5 R. {, D" F; b
            pPt = pPt-&gt;pNextInCell;3 `& e* {! h9 U! \. e# y, \& \
        }</P>
    6 q1 e3 F1 f! @9 H2 W' b. p9 a<P>    // Unlock the cell  W5 [% w3 P  O: \
        if( pPlayerData-&gt;wCellX == 0xffff )
    2 P1 n  A  q( M/ d! |7 h( y' _% j        m_OffMapLock.Leave();- H  _; G0 C/ G3 Q
        else9 \0 ?+ H* j) e
            UnlockCell( pPlayerData-&gt;wCellX, pPlayerData-&gt;wCellY );</P>" N3 E" S8 z" |
    <P>    // Unlock the player
    4 i  Y& ~7 Y  b- J& _% e    UnlockPlayerData( pPlayerData );/ o# U& j6 j0 e' G* Y7 F
    }</P>$ ?: t/ z5 K) J6 _

    ; n7 w. V8 f. s8 z<P>8 O. Q) |$ N* j+ b  Y; x! Z6 W
    //-----------------------------------------------------------------------------
    ; o) \4 C( k! ~3 U+ i// Name: ( `( ?6 c, Q) M/ B% z7 Y- l
    // Desc: . I" r* }9 b; s, C& t  i
    //-----------------------------------------------------------------------------* n4 B- I9 J! ?! M& Q+ W
    void CMazeServer::UnsafeRemovePlayerDataFromCell( PlayerData* pPlayerData )
    0 F+ a' N3 r; _7 F( i6 e5 U+ ^/ K{
    $ |5 Z) u' C- A3 B. Q5 a$ N9 j) b    ServerCell* pCell = GetCell( pPlayerData );
    , g8 u4 U9 U6 ?$ v    PlayerData* pPt  = pCell-&gt;pFirstPlayerData;2 v9 }) x( W- G4 l) b0 ~3 k0 E/ f0 v
        PlayerData* pPrev = NULL;( A, r! o" ]5 g$ b2 f
        while ( pPt )
    ! `  [8 J1 k7 G, W9 s8 B$ h8 x    {3 A% ?* g: A2 D
            if( pPt == pPlayerData )
    & P0 G2 t; }& F3 z0 a" X, r& ^% T        {
    & m( Z% Q8 J8 @" i6 C/ {            if( pPrev )* {! r8 f1 {4 Q: P3 Q) M' t
                    pPrev-&gt;pNextInCell = pPlayerData-&gt;pNextInCell;
    3 r5 D( ?- W7 K. H+ S5 f            else
    % B# F9 M7 Q) {0 r& D8 ~0 I( d                pCell-&gt;pFirstPlayerData = pPlayerData-&gt;pNextInCell;& C0 J7 T' Z) a. k
                pPlayerData-&gt;pNextInCell = NULL;, Q+ r& ~8 j1 b" y4 ~9 P; v" o0 ]
                break;/ a6 B$ N: Z/ {& j: J. k
            }* N' i+ K: e* v' d, `$ `
            pPrev = pPt;
    9 F6 }9 _  M* q8 B% j) R        pPt = pPt-&gt;pNextInCell;
    - S/ L0 U* S9 @8 @. i    }5 G! g# O/ d' Q& d$ Z  `3 Q
    }</P>
    ) s/ l! v6 M5 u: C2 x. p, [+ |4 c/ i$ B4 s
    <P>% Z5 Y! z3 d* A, J% Q& G
    //-----------------------------------------------------------------------------4 r/ ~( f  ^" E9 M% w4 }+ A
    // Name:
    % K7 q; r& Z* k% L8 K// Desc:
    3 W, ]4 z$ q5 j& W. X! Y//-----------------------------------------------------------------------------1 x- m0 h$ G& T+ w$ e3 T
    void CMazeServer::UnsafeAddPlayerDataToCell( PlayerData* pPlayerData )( O/ G; J" k0 W& w4 i1 |- H
    {
    ' H) F; g) W2 T" _7 O    ServerCell* pCell   = GetCell( pPlayerData );
    9 `! U! k4 @* n( E    pPlayerData-&gt;pNextInCell = pCell-&gt;pFirstPlayerData;$ l' O' G2 ~/ |* L; |' W
        pCell-&gt;pFirstPlayerData = pPlayerData;7 x1 C! w$ k! Q# U
    }</P>" `/ v+ ?7 a0 M- N

    # Q. }: `& |# x* H, E' i6 I, i<P>
    6 l, y- G& z$ B/ F& m& l//-----------------------------------------------------------------------------& _' s& l3 P- g! W
    // Name: ' H# g5 t  M" U8 O  r
    // Desc:
    3 E2 \7 N, B, L! z5 r& t//-----------------------------------------------------------------------------
    5 j3 s/ P- K8 Q  {void CMazeServer::HandleClientPosPacket( DWORD dwFrom, ClientPosPacket* pClientPosPack )7 E$ p% W2 o) v2 ?/ e* M+ _- J
    {
    6 S, w$ ~% l: W9 j0 A6 H/ L    // Grab player for this client and lock it4 Z) Q& v* G6 S1 n' j3 V
        PlayerData* pFromPlayer = GetPlayerDataForID( dwFrom );0 b+ @+ H( a6 N8 _
        if( pFromPlayer == NULL )
    ( {7 {# V* Q( C' _+ R: u8 b    {
    2 |6 I0 ]) I) H) i- X) p        if( m_dwLogLevel &gt; 1 )
    9 ~* w4 v) r5 m2 f            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Could not find data structure for this player"), pFromPlayer-&gt;NetID );4 S' A1 v1 N- V" F
            return;9 T0 {( S, C; ~1 u& u+ W- m
        }</P>
    4 q5 I$ W" g" o  W<P>    LockPlayerData( pFromPlayer );</P>
    & j+ N5 O2 O6 ?7 P: }( _<P>    if( FALSE == pFromPlayer-&gt;bAllow )
    4 M( m0 D$ E3 W- @. Z6 T    {
    / r( Y( g$ u* t# H3 Q! W7 a: Z        if( m_dwLogLevel &gt; 0 )  @+ r5 C; C1 I2 S
                ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Got position packet from bad client.  Rejecting client"), pFromPlayer-&gt;NetID );</P>
    - i0 e2 \$ k5 G& {4 e! f  i<P>        m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );
    4 H( K6 G" ]: _/ L# e        UnlockPlayerData( pFromPlayer );
    ! P- u$ @6 L, p1 F( I2 I+ z3 Y! u+ o        return;5 n/ G! E+ V% H6 h" @
        }</P>
    % B& r" [" E" D* m0 l/ @# G<P>    // Compute the cell the player should be in now
    $ C4 L4 T, X% r9 K7 h. T& G0 G! @    DWORD newcellx = int(pClientPosPack-&gt;fX);, R1 H9 I% l* d" o( j
        DWORD newcelly = int(pClientPosPack-&gt;fY);% F: n) N$ x1 E
        DWORD oldcellx = pFromPlayer-&gt;wCellX;; S' ]. \8 p. R) F+ o5 [
        DWORD oldcelly = pFromPlayer-&gt;wCellY;</P>
    ! G+ G; e. E+ ]  y1 C: u( A0 b<P>    // Have we moved cell?/ z# ]' k$ \5 u( w2 b" ^
        if( newcellx != oldcellx || newcelly != oldcelly )# J: O+ t' Q. O3 ]- b
        {! [1 u  ~. Q* ~8 \6 ]: \8 t
            // Yes, so lock the pair of cells in question! d7 e6 p& ]& Q8 ^$ E) P
            LockCellPair( oldcellx, oldcelly, newcellx, newcelly );</P>9 O  j; M5 B. d
    <P>        // Remove from old cell and add to new cell
    + ?# U( j5 B2 B( \  g% o( ]        UnsafeRemovePlayerDataFromCell( pFromPlayer );
    $ e& H& P/ f$ o1 E. |        pFromPlayer-&gt;wCellX = WORD(newcellx); pFromPlayer-&gt;wCellY = WORD(newcelly);
    * h; V  N3 \$ G# m8 k        UnsafeAddPlayerDataToCell( pFromPlayer );</P>0 @0 T+ t) f" g
    <P>        // Unlock cells8 D7 [4 y. v5 Y7 V) u8 A2 O* z- Z5 \$ L) h
            UnlockCellPair( oldcellx, oldcelly, newcellx, newcelly );! }& j) p! u3 K# q* O: O
        }</P>
      ]0 [8 y* f0 O1 X9 }/ d<P>    // Update player position
    ) `& t, L' B' a& Q5 h3 ], n    pFromPlayer-&gt;fPosX      = pClientPosPack-&gt;fX;
    * C4 W7 f! X7 j% ~( a8 E: ]# }' Z    pFromPlayer-&gt;fPosY      = pClientPosPack-&gt;fY;* X3 t& E1 I9 i9 G4 d
        pFromPlayer-&gt;aCameraYaw = pClientPosPack-&gt;aCameraYaw;</P>
    ; S5 k5 ]! g+ f' ?& r# B<P>    // Allocate space to build the reply packet, and fill in header 8 X2 n% `/ o- f' U! W3 U
        DWORD dwAllocSize;3 V$ v& A0 l- s9 [# N4 D
        ServerAckPacket* pSvrAckPack = NULL;</P>
    9 I$ |$ E# _$ p8 \6 o<P>    // Begin by allocating a buffer sized according to4 {5 E4 H: ^- X4 F  v7 @
        // the current number of nearby players + 4.  This will give ( P. ^+ p: K! M' g% J+ W
        // a little room for more players to come 'near' without resize
    & O; X; H! r, H" k9 W    // the buffer.
    * c6 g% I4 d! \0 W( v; }3 g* |' Z; ~    DWORD dwMaxPlayerStatePackets = pFromPlayer-&gt;dwNumNearbyPlayers + 4;</P>
    % V5 j9 Y1 `5 C* a& L<P>    dwAllocSize = sizeof(ServerAckPacket) + dwMaxPlayerStatePackets*sizeof(PlayerStatePacket);
    ( L3 G+ `) g4 j6 x& w& u8 X    pSvrAckPack = (ServerAckPacket*) realloc( pSvrAckPack, dwAllocSize );. k& ~' Q% a( Z' \1 w4 M3 x
        if( NULL == pSvrAckPack )" M) P* b; `- ^) A. p3 z
        {
    & z* z! ~  Y2 P        // Out of mem.  Cleanup and return, i( f2 k% f8 t
            UnlockPlayerData( pFromPlayer );7 x* |$ Y8 u6 s" {( T" a3 r) G' v$ _
            return;      
    . Z# f% W+ g+ Z5 c# t    }8 `4 A  ~/ V) w2 @" S
        ZeroMemory( pSvrAckPack, dwAllocSize );</P>, K0 p; h: d' D5 X9 U
    <P>    *pSvrAckPack = ServerAckPacket(m_dwPlayerCount);
    & y/ ~) d0 i/ E3 u: \  a1 I    pSvrAckPack-&gt;wPlayerStatePacketCount = 0;
    ; |8 C* T1 W* ^& m" q2 T9 o8 ~8 y0 B    PlayerStatePacket* pChunk = (PlayerStatePacket*)(pSvrAckPack+1);</P>
    , I8 _6 `4 v% K<P>    // Compute range of cells we're going to scan for players to send
    * s  C0 n, |" K1 T' d    DWORD minx = (newcellx &gt; 7) ? (newcellx - 7) : 0;, s1 s2 `9 W3 c8 l$ T* a+ s  C
        DWORD miny = (newcelly &gt; 7) ? (newcelly - 7) : 0;
    % {6 F: D% n9 T4 ?( @    DWORD maxx = (newcellx+7 &gt;= m_dwWidth) ? m_dwWidth-1 : newcellx+7;
    ! `- y2 G& c8 ], p1 Y    DWORD maxy = (newcelly+7 &gt;= m_dwHeight) ? m_dwHeight-1 : newcelly+7;</P>
    $ ^8 X1 c5 ?. D# v$ |<P>    // Lock that range of cells
      ~2 R) u# P' E: v( u* l    LockRange( minx, miny, maxx, maxy );</P>: X% e$ \1 R8 F# ?
    <P>    // Scan through the cells, tagging player data onto the end of: m8 A7 E: k6 Q4 V
        // our pSvrAckPacket until we run out of room! `7 Y: S3 z; z; u' c
        for( DWORD y = miny; y &lt;= maxy; y++ )
    ( ?; L' {; M1 E/ {* r    {
    : }* z" ]1 `6 t; }3 f4 e        for( DWORD x = minx; x &lt;= maxx; x++ )
    & E8 G! S$ t0 {/ R        {
      n& s: h. i/ Z: W! |% c# I            PlayerData* pCurPlayerData = m_Cells[y][x].pFirstPlayerData;
    , {; F( d4 h; ^; j+ o8 f            while ( pCurPlayerData )
    . D+ l1 h; q: Z+ t4 K# U$ S9 h' P            {
      u& L% {5 a5 p) W+ c* `                if( pCurPlayerData != pFromPlayer )
    / o  k4 o4 ]; B7 c: r                {
    * {) S( [* {" {" H' p7 u% Y" r                    if( pSvrAckPack-&gt;wPlayerStatePacketCount &gt;= dwMaxPlayerStatePackets )
    ; p8 Y8 T2 ?- E' M+ H- O! g                    {* T6 q% D7 e- s/ v$ q9 I. k
                            // Make sure pChunk is where we think it is7 Y( s7 O/ ?! w' Y' v
                            assert( (BYTE*) pChunk == (BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket)) );</P>
    6 O' s7 T. b, ]% T6 o& E$ J2 `3 ^<P>                        // There are more than just 4 new nearby players, so resize the
    * `- m: V+ ~2 Z' u4 P, y3 D                        // buffer pSvrAckPack to allow 16 more PlayerStatePacket's.
    5 H! N6 ~8 f7 q9 c7 Z$ r7 J6 ?. m0 y                        dwMaxPlayerStatePackets += 16;
    ! c3 V5 Q" R4 t+ y  Z9 j                        dwAllocSize = sizeof(ServerAckPacket) + dwMaxPlayerStatePackets*sizeof(PlayerStatePacket);; P% t( N9 B8 y- K5 d# |/ s
                            ServerAckPacket* pNewSvrAckPack = NULL;
    - o! E0 w1 D3 V& z# M5 {                        pNewSvrAckPack = (ServerAckPacket*) realloc( pSvrAckPack, dwAllocSize );0 J) S; ?7 j. \: z" q
                            if( NULL == pNewSvrAckPack )
    / v$ H1 |8 \, t0 ~1 I/ {                        {
    : P0 R5 u0 S; Z. N7 ^9 b9 l                            // Out of mem.  Cleanup and return1 g( v8 o4 y5 G) u, x5 e- w
                                free( pSvrAckPack );
    3 z" j+ A5 n' O% Z                            UnlockRange( minx, miny, maxx, maxy );" \& P/ V; w0 {
                                UnlockPlayerData( pFromPlayer );
    ( R* m! F0 V: ]                            return;       6 W( f# Q3 x1 }' g
                            }</P>5 v( X9 R7 ~  \: @& S3 L- _
    <P>                        pSvrAckPack = pNewSvrAckPack;+ a# d+ C8 P* s9 n  Q
                            pChunk = (PlayerStatePacket*) ((BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket) ) );</P>
    # Z; N$ E# H) Z9 n8 a7 M<P>                        // Make sure pChunk is still where its supposed to be
    " z  z- |  u! w& M) Q: [$ I0 k                        assert( (BYTE*) pChunk == (BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket)) );2 ]& Y7 D* }: @# ~2 X5 a: Z) z
                        }</P>: `3 S8 [$ A8 D9 m1 D( O
    <P>                    pChunk-&gt;dwID       = pCurPlayerData-&gt;dwID;0 I& |. e5 Z  c, n) K) {' [8 B  ?
                        pChunk-&gt;fX         = pCurPlayerData-&gt;fPosX;3 L% [- o* i# N7 D- |
                        pChunk-&gt;fY         = pCurPlayerData-&gt;fPosY;
    6 G; v# Z  Z4 B3 a+ @                    pChunk-&gt;aCameraYaw = pCurPlayerData-&gt;aCameraYaw;: \, ~3 }$ P- c9 m5 i1 Q( Q
                        pChunk++;! L! N3 j1 }2 q; v& v; G8 e0 q
                        pSvrAckPack-&gt;wPlayerStatePacketCount++;
    . S: C! u  d) J( ]: }1 A; l6 H                }
    1 J: N) E) f1 X; ~& `                pCurPlayerData = pCurPlayerData-&gt;pNextInCell;
    ; I4 t- m$ H6 D/ S# \2 s( z8 ?; s( m' }            }: a2 Y( m6 V( e  A: P; X% h" ?1 {
            }; |) o+ e8 S) |
        }</P>
    , A# O# e* i, c- }3 T) @% P* }( R<P>    // Update the dwNumNearbyPlayers for this player/ G- ]- ^6 ], X
        pFromPlayer-&gt;dwNumNearbyPlayers = pSvrAckPack-&gt;wPlayerStatePacketCount;</P>6 `" X. F- c( }+ ?  T2 t8 o
    <P>    // Unlock range of cells
    8 d" j: e3 B+ D    UnlockRange( minx, miny, maxx, maxy );</P>
    8 I4 \2 b4 F( C) M<P>    if( m_dwLogLevel &gt; 2 )
    % O+ ^- T9 H# f5 g    {
    ' J1 w. L6 P: f1 t" ?; h) Y) ^        ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Position is (%0.2f,%0.2f)"), pFromPlayer-&gt;NetID, pFromPlayer-&gt;fPosX, pFromPlayer-&gt;fPosY );$ P' y' I  i! k+ ^( d# {: n# u) ^
        }: {3 R4 _7 r; _$ c& @0 [' C# }$ k+ ]
        else if( m_dwLogLevel == 2 )
    . Z" \. f6 Z, b4 [2 N8 n4 D    {/ a% {! Q# H5 k7 x/ T
            FLOAT fTime = DXUtil_Timer( TIMER_GETAPPTIME );
    ; r3 c* Q1 N/ }. y1 i, o        if( fTime - pFromPlayer-&gt;fLastDisplayTime &gt; 60.0f )
    0 K# y4 i# G. v% n* u2 h" Z' o  e        {! ^* p4 f; K9 T" q( k0 X  }* C
                ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Position is (%0.2f,%0.2f)"), pFromPlayer-&gt;NetID, pFromPlayer-&gt;fPosX, pFromPlayer-&gt;fPosY );
    4 u+ [( M5 T$ F) e! Z7 R' X1 E            pFromPlayer-&gt;fLastDisplayTime = fTime;4 Q$ T  n( j0 p7 V* ^1 ^- L5 D
            }) p& F$ S  l7 M0 B0 p
        }</P>/ T: L7 Z4 h8 z  ?
    <P>    // Unlock the playerdata+ W* F4 t6 k; ^1 ?
        UnlockPlayerData( pFromPlayer );</P>  o( Z) A' T; _
    <P>    // Send acknowledgement back to client, including list of nearby players
    3 h" |& z7 R) F    DWORD acksize = sizeof(ServerAckPacket) + (pSvrAckPack-&gt;wPlayerStatePacketCount * sizeof(PlayerStatePacket));
      a" d) C$ B1 H% M: `% g 8 o; V2 w1 L# e& F& `' X
        // Pack the buffer with dummy data.
    7 s. X% @- D' ^9 b$ n    if(m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex] &gt; 0)+ L# i7 |$ W5 F) O2 D& y
        {
    - l) |% [+ u' T4 Z- w7 @* N        DWORD   dwBufferSize = acksize + m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex];
    ! J! g# V- R% @4 J/ S        VOID*   pTempBuffer = 0;</P>! f& S, u3 f/ J9 W
    <P>        pTempBuffer = malloc(dwBufferSize);5 }5 X8 Q& H: @( K* c
            if( NULL == pTempBuffer )* E! L* X& ]( S6 A' Q: }8 t6 R
            {& p( [' e/ Z3 Z& k# D0 `3 Y; L
                //Out of memory
    1 t5 h* M6 @/ E* K5 J/ }            DXTRACE_ERR_NOMSGBOX( TEXT("System out of Memory!"), E_OUTOFMEMORY );0 y  b% M) Q1 r0 Q# s2 B0 r- X4 f+ L
                free( pSvrAckPack );
    ! d2 C+ l6 h2 e9 a$ K, y  M            return;3 S; n: C" R7 g( K( d5 j
            }</P>
    - N' O& x$ ^$ ~) `4 g0 H/ U$ s0 c6 d<P>        FillMemory(pTempBuffer, dwBufferSize, 'Z');! }& g* X% B& S
            memcpy(pTempBuffer, pSvrAckPack, acksize);</P>8 W0 k. t- R9 @' q
    <P>        SendPacket( dwFrom, pTempBuffer, dwBufferSize, FALSE, m_dwServerTimeout );; H$ s: m) q3 w
        & D/ V: f  n0 P; }  r* x
            free(pTempBuffer);- h1 z' `; w& K: M4 ~4 ^; ?
        }   
    + G/ x; ]' Q4 T* p/ l2 M7 F    else
    ) f- l; X; \1 q3 I, C2 ~7 k    {. F, J; \1 w/ l& c+ E
            SendPacket( dwFrom, pSvrAckPack, acksize, FALSE, m_dwServerTimeout );
    9 z/ `' z8 B, ~( _    }</P>6 _; Z+ T% F/ z% \! a! W
    <P>    free( pSvrAckPack );</P># W6 f6 g/ D5 H, n
    <P>}</P>; e+ a0 M: k/ h, C; |- j+ ~
    ; }( y+ |) ^' \* u9 d4 i$ u
    <P>
    2 T+ s( ^8 p9 \- U//-----------------------------------------------------------------------------6 h$ D* j1 I6 j* _  W
    // Name: : W% W3 }2 W$ z: V
    // Desc: 2 ~  x1 i+ _7 ~+ w* ?) l- K) Y% z
    //-----------------------------------------------------------------------------( U) O6 _  k6 k' i4 y
    void CMazeServer::HandleClientVersionPacket( DWORD dwFrom, ClientVersionPacket* pClientVersionPack )( X" x' s/ `6 ^4 [( P  P0 E+ O
    {
    5 U! c, [7 k2 L& O: I. q6 H  N6 {& Y    // Grab playerdata for this client and lock it5 ]4 E. k8 t; l6 W3 q& v2 c
        PlayerData* pPlayerData = GetPlayerDataForID( dwFrom );$ ?, `/ A8 U; [' H9 U! X. b! X$ ^$ U# a. A# O
        if( pPlayerData == NULL ); G& ~, {  D& {. l! c& H
            return;
    9 Z8 d. F( a: s8 j: h    LockPlayerData( pPlayerData );</P>
    $ R* [; {- B( z9 }* o<P>    // Record the version number
    7 w) K# f7 D2 h1 _# [7 a' O5 P; R    pPlayerData-&gt;dwVersion = pClientVersionPack-&gt;dwVersion;</P>0 O/ X! P: O: T
    <P>    if( m_bLocalLoopback )
    " {: B. ~0 w% h5 I& I( p        pPlayerData-&gt;bAllow = TRUE;
    + Q. ], _* t. U% J# N( }    else
    0 N# Z( a8 |- V. P7 l0 S8 V3 l' g        pPlayerData-&gt;bAllow = IsClientVersionSupported( pClientVersionPack-&gt;dwVersion );</P>: I; O% E6 D' o: I( q) j
    <P>    if( m_dwLogLevel &gt; 0 )
    * n) g5 |3 o; V5 _3 _: L        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>
    / B4 o; e4 _/ `+ s5 t<P>    if( FALSE == pPlayerData-&gt;bAllow ), [; v: |1 b! {/ q2 N9 a
        {& E( E: n" `; g
            if( m_dwLogLevel &gt; 0 )
    6 Q) |" }% T7 Z( x; S# b  n8 t            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Rejecting client"), pPlayerData-&gt;NetID );</P>
    8 q. }. W8 y$ @5 k  L" }. z5 f<P>        m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );
    - O; v+ ^# J7 Z        UnlockPlayerData( pPlayerData );" x6 K; l. o' v
            return;# E% M" }# v. t9 D% H( ~9 Q/ {
        }</P>' @5 @0 g" q. P
    <P>    // Unlock the playerdata
    / `( H& G4 M, b    UnlockPlayerData( pPlayerData );</P>. p: C. b0 C* I
    <P>    // Send acknowledgement to client that the client was either accepted or rejected9 p9 m& ^' Y+ b/ ]$ q
        ServerAckVersionPacket packet( pPlayerData-&gt;bAllow, dwFrom );
    ( F" n1 s3 {- X9 g# u    SendPacket( dwFrom, &amp;packet, sizeof(packet), TRUE, 0 );' [. E% a. _* ?: B
    }</P>+ F/ Z: O: Y: q% t# A! k. a; ?5 f

    6 O# \  r4 ^. P2 M/ J<P>* \& D; N) e( K# S, T/ S
    //-----------------------------------------------------------------------------7 c) l; X' ~& h8 _5 e$ l7 \
    // Name: % S3 j* D0 U! j. ]* i7 W+ W% n
    // Desc: ) c, E2 A7 Q6 }% {8 _$ D0 v
    //-----------------------------------------------------------------------------2 g, ]5 r( [' C1 Y/ `( K9 B6 W- x
    BOOL CMazeServer::IsClientVersionSupported( DWORD dwClientVersion )
      q# k7 I( M  @% W* b& a& Z{9 F- u' o# u/ ]+ ~
        switch( dwClientVersion )
    $ U+ q$ k1 l$ {. Y$ `: }3 B: C* C    {* i5 n- v" c' S: {6 ?( e
            case 107: // only v107 is supported
    2 Z( |/ I4 m1 S8 s" c* [            return TRUE;
    - J+ ?- N: D  f& D$ Z8 [8 O9 ?        default:
    ) ]( v3 M$ ]/ O1 d$ t. x1 r3 n% W            return FALSE;: T9 y* r/ P( @% s3 P
        }
    * M! s8 `' J5 U. m; A}</P>3 R) x( K  {& c$ E" I* o( s, u/ W7 r

    4 T/ T: V$ K# p" X8 T8 }<P>
    7 f5 A% S: ^+ G8 L% b! x# O9 i//-----------------------------------------------------------------------------# l& e3 T; K. q9 H) X; [
    // Name: # B# L* [) y/ M+ j0 [: v) S
    // Desc: 1 ^0 D. N5 l7 v9 H! w
    //-----------------------------------------------------------------------------
    7 O7 C: c" L9 \! [1 \3 [- q; n4 Evoid CMazeServer::HandleUnknownPacket( DWORD dwFrom, ClientPacket* pClientPack, DWORD size )8 H3 c& p: |1 r0 ^7 ]' p( u" Q
    {$ q! g# m, k( D( s& K+ T+ Q
        if( m_dwLogLevel &gt; 1 )
    7 p! _& h$ V8 }6 j9 T) b        ConsolePrintf( SLINE_LOG, TEXT("ERROR! Unknown %d byte packet from player %0.8x"), size, dwFrom );</P>
    2 C7 k( Q( T1 G$ l$ [<P>    m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );
    $ S3 j" I8 s- W" u}</P>
    & \6 o2 v8 }0 L& {8 G9 N  o1 `, s( B  t8 l( I' s
    <P>
    ; G  F9 O. d1 r; c! i//-----------------------------------------------------------------------------
    ! F$ \" P+ \9 Q! \1 T// Name: # h  _3 z% h: Y0 B$ ^2 N; f0 }+ E
    // Desc:
    % u: k5 V/ Z: c4 ]6 `//-----------------------------------------------------------------------------7 p4 J3 C9 \7 X( y# D
    DWORD   CMazeServer::IDHash( DWORD id )
    8 i6 S! Z1 V8 I{
    5 Y% |7 Y( o: h& d    DWORD   hash = ((id) + (id&gt;&gt;8) + (id&gt;&gt;16) + (id&gt;&gt;24)) &amp; (NUM_ID_HASH_BUCKETS-1);
    ) e" n: d/ n4 f" ~    return hash;
    ! y' `) }$ ~4 a9 {# i4 i}</P>
    / l) B3 t# b- s! \' D; H+ h. {# D/ T  [% r$ w/ {
    <P>  g) ?. D& J3 {5 u
    //-----------------------------------------------------------------------------
    ; ~! l6 D/ @5 [) c2 D7 }// Name: . }& F9 O* }4 F6 A
    // Desc:
    # ], }" l* J' O- Y, \2 @0 n% H//-----------------------------------------------------------------------------9 W% ]' v0 c/ S+ S4 V2 _
    void CMazeServer::RemovePlayerDataID( PlayerData* pPlayerData )- Z, B$ B4 V% ^2 e, p1 x
    {
    3 r1 O" y' J5 ~# F& B    // Hash the ID to a bucket number1 l( f- c1 v0 O0 f) a! i, k1 y6 D
        DWORD   bucket = IDHash( pPlayerData-&gt;NetID );</P>
    5 a( B& o1 h$ d2 u% L# C<P>    // Lock that hash bucket( e% n: D+ J* E/ h
        const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;1 G+ q% y0 s/ p: u' r
        m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>
    % J8 t. [' |+ U! w( u; R<P>    // Loop though players in bucket until we find the right one# A7 u( n: s. t' M, ]+ T9 X
        PlayerData* pPt = m_pstIDHashBucket[bucket];1 N2 L7 n0 O( E2 l+ r
        PlayerData* pPrev = NULL;* u9 E& j1 X, B# e2 R
        while( pPt )8 E1 n. L5 f" t9 ?
        {, A5 Q2 x% X- }7 y7 D1 F9 W$ y
            if( pPt == pPlayerData )
    : A9 X9 Y0 z/ r# q* ~4 l7 A( v            break;3 M* G& O* K0 W/ _
            pPrev = pPt;
    & F- \0 O, F/ E/ K9 Z4 W8 R        pPt = pPt-&gt;pNextInIDHashBucket;
    2 ~2 W& Z9 }. Z4 ?" D* B- l    }</P>% k; }4 g# O, C' K8 o. _+ B" r
    <P>    if( pPt )
    / t. H( Y$ [) L% c; _" a! ]& K3 f, p    {) U- P! Z' g: Y. `7 P
            if( pPrev )
    5 F* v) k/ P$ Y            pPrev-&gt;pNextInIDHashBucket = pPt-&gt;pNextInIDHashBucket;
    " ~) @5 P0 h. G" x2 N) n6 V, l        else- r: W  Z( @3 ?& F9 p% ~- U, k% q4 }
                m_pstIDHashBucket[bucket] = pPt-&gt;pNextInIDHashBucket;
    9 T- k4 X& B2 m! Z" n+ }8 t        pPt-&gt;pNextInIDHashBucket = NULL;) j/ |% }2 e4 O# T: \# o/ I4 m
        }</P>1 ]- e: [# F8 E0 T  Y. L
    <P>    // Unlock the hash bucket
    $ B3 H3 j8 ]5 e( `    m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();
    4 o1 |" A/ z3 q  r7 n% A}</P>
      ?- \% A# A" G$ V
    ! o5 Z+ W: q4 ^<P>7 V- D5 w6 t' q  Y
    //-----------------------------------------------------------------------------
    . U' [5 i  S+ E7 N( e: U: n// Name: / T) e. _2 f; m3 z& O- i
    // Desc: 0 E9 K1 ~4 q& B' c
    //-----------------------------------------------------------------------------
    3 a$ v+ L. A; w4 Svoid CMazeServer::SetPlayerDataForID( DWORD id, PlayerData* pPlayerData )% v$ ^# G4 s' V. u# B2 `
    {
    # G% S9 b( P" C+ g6 p9 e/ B    // Make sure this player isn't added twice to the m_pstIDHashBucket[]9 M% g+ G( r9 s
        // otherwise there will be a circular reference
    & N: t6 l1 \" u7 J" V0 S: A' @    PlayerData* pSearch = GetPlayerDataForID( id );
    ) }! F: C: k# ~8 H; s) i  U    if( pSearch != NULL )  q+ t6 F: F6 f  P( j
            return;</P>" ~7 k3 g; h. n# O! r/ C
    <P>    // Hash the ID to a bucket number
    0 W/ o: W# m  U    DWORD   bucket = IDHash( id );</P>
    1 ~8 T8 V/ G' K3 Q( i1 n<P>    // Lock that hash bucket
    ' y  k' t  K% |    const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;- m" _. p% Y) e
        m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>
    7 f7 l. D9 s/ s5 J<P>    // Add player onto hash bucket chain/ ^2 p& o5 M, S' K  p- @
        pPlayerData-&gt;pNextInIDHashBucket = m_pstIDHashBucket[bucket];' ^3 q( v; o- Z7 R5 x
        m_pstIDHashBucket[bucket] = pPlayerData;</P>% @0 R$ L0 i% {6 ~2 G
    <P>    // Store net id in player- p$ }& {0 B1 u; [' s% Y
        pPlayerData-&gt;NetID = id;</P>+ g2 z' d* b7 W$ I% K5 r
    <P>    // Unlock the hash bucket
    / y* q  F$ s! l9 v: `3 X  B0 o    m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();
    & [5 m* B# @* O: C" L! E}</P>
    % g- y+ T5 O" T* {9 X$ ]6 f0 }0 K! ]( c
    <P>/ G/ d! C& x9 t7 B8 Y% e! [
    //-----------------------------------------------------------------------------1 w/ n- s# ~  R* R' b
    // Name:
    . f, c# d# {3 R8 Y, Z* ^// Desc: ( C) m) x/ N& w$ h! _
    //-----------------------------------------------------------------------------( G$ O$ ?* u) K
    PlayerData* CMazeServer::GetPlayerDataForID( DWORD id )
    * m; {3 w$ D9 E4 k! a# t/ e. E{4 {& A/ i% s& N3 g# Z! S
        // Hash the ID to a bucket number
    3 o: u( O3 n2 h    DWORD   bucket = IDHash( id );</P>$ p: I( _+ Z4 l4 D
    <P>    // Lock that hash bucket
      J, U& W* S/ }+ ^3 B    const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;" P1 ~' R1 I; V, O& s% @0 i9 |
        m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>7 q* e# C) _% O6 [6 g" u
    <P>    // Loop though players in bucket until we find the right one( Q$ x* i& N2 }# B& X- [5 @
        PlayerData* pPlayerData = m_pstIDHashBucket[bucket];3 i4 I) L) P! x  x6 [8 Y7 f% D- P( F
        while ( pPlayerData )% S  ?* w5 D7 S4 a) ^6 A+ {7 h( a
        {+ b9 R( k8 t! f5 y9 T
            if( pPlayerData-&gt;NetID == id )
    : k8 t# X* O) w9 Q) c  M            break;, Z# o: J+ ]3 C9 G9 z) D' g- h, }
            pPlayerData = pPlayerData-&gt;pNextInIDHashBucket;' P2 l# [" \9 i' g' |. q
        }</P>
    % K$ D: C) k: z2 y0 o$ }' ~<P>    // Unlock the hash bucket/ Y9 w) o9 q6 H- A
        m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();</P>
    , \$ O* F+ N4 \' F5 G% k0 Y$ @  S<P>    // Return the player we found (will be NULL if we couldn't find it)
    7 }9 [7 v) }+ J6 N* ]( U& X    return pPlayerData;
    2 i: i' A8 N+ l6 j! w0 G: G}</P>
    $ g4 @) n8 K! k6 Y; k( s8 a% B
    - _/ {; k% J. w( m<P>
    0 r' M* t. G  B# E. V; x//-----------------------------------------------------------------------------) Y2 @( c  \% d( n; E& c+ G  ~  m. t
    // Name:
    1 ]" v! w+ v) e8 e* r// Desc: calls DisplayConnectionInfo for each connection in a round-robin manner# s5 Y8 L5 u% Z1 ?4 x
    //-----------------------------------------------------------------------------2 G! j; l& ]& {9 b( ]1 b% C+ E
    void CMazeServer:isplayNextConnectionInfo()5 r0 X; @2 k* J
    {
    $ T: w+ a! w/ G0 w' S3 `5 c    if( m_pNet )
    6 Q5 z# o$ X/ M; O2 h; S8 o% D    {2 t! K7 Y" t7 D. J* `
            // Find the player that was displayed the longest time ago, and display it.0 e& o$ L/ ?5 S1 c
            FLOAT fCurTime = DXUtil_Timer( TIMER_GETAPPTIME );  `+ m9 B+ o0 F2 i$ t- s
            PlayerData* pOldestPlayerData = NULL;8 E9 U$ q2 r6 [
            FLOAT fOldestTime = 0.0f;</P>
    # P; B* T3 t! |% @; W5 N<P>        m_PlayerDataListLock.Enter();</P>3 z9 g. i* ?! X+ F
    <P>        PlayerData* pPlayerData = m_pFirstActivePlayerData;
    $ ~0 I: ~) I. N' }. Z) K        while ( pPlayerData )
    * v7 p) Z% T& K3 S2 q* P2 O        {
    9 I, |4 s: ^0 A+ d$ Q! C            if( fCurTime - pPlayerData-&gt;fLastCITime &gt; fOldestTime )( t5 s4 f; ~9 ~; ]" q, H- ?
                {  B7 i& q8 N1 t" M! {
                    fOldestTime  = fCurTime - pPlayerData-&gt;fLastCITime;
      w) Q5 m; [) {                pOldestPlayerData = pPlayerData;
    # E/ ^( `, j% ?/ v# C            }</P>; s  ^" o4 f3 h
    <P>            pPlayerData = pPlayerData-&gt;pNext;
    ! H/ M" F& U+ h) u" T        }</P>
    % h2 U/ G: L8 A, v; w9 c5 H<P>        // Display the player with the oldest CI field, and update its CI field.$ s- Y5 j) L& b. ^8 G
            if( pOldestPlayerData )
    ! s2 ?# N/ a/ ~: I; f        {
    , d+ @; {1 ]4 w. n: R; C5 H9 i            ConsolePrintf( SLINE_LOG, TEXT("Displaying connection info for next player") );6 D& `/ `- p5 \) [, ?' M
                DisplayConnectionInfo( pOldestPlayerData-&gt;NetID );
    3 m7 `' u/ n% j( T& X. Y1 c0 ]3 b            pOldestPlayerData-&gt;fLastCITime = fCurTime;
    % C. E' Q" Q( j- o- k2 u& W        }
    : Y$ P! z% E2 C0 ~. S  v# ?' Y, V9 n        else
    6 n) W8 U& [# `4 b+ ]        {" b' R% [" b0 {; I4 j$ ^  B
                ConsolePrintf( SLINE_LOG, TEXT("No players found") );
    7 P3 g: e  u" ]0 O/ Y! B. }        }</P>
    & Z" R1 d; q4 C<P>        m_PlayerDataListLock.Leave();4 D6 l9 e  `: ^! ~
        }
    ) a" e0 \+ |  m" e9 \* F8 B}</P>
    ; O# A; {$ b2 k7 j! I# y0 K! C2 J$ Q9 ]+ k" c4 O# O9 ~
    <P>
    ) V2 p5 I( p6 I; k4 |! M4 O//-----------------------------------------------------------------------------
    ! R7 T( G, m5 k$ r6 ]// Name: 5 ^/ a+ E" j4 I+ h
    // Desc:
    . g# b. e# y* b1 L9 O+ h//-----------------------------------------------------------------------------
    ; V4 j+ K- j% _$ ovoid CMazeServer:rintStats(); x' s/ ~' a- ^8 k
    {( Z8 L* |: b$ \0 `" Q7 F; x0 V
        ConsolePrintf( SLINE_LOG, TEXT("Thread count: Active=%d Avg=%.2f Max=%d"), & z# H* C" M# V
                                        m_wActiveThreadCount, m_fAvgThreadCount, m_wMaxThreadCount );! V: [: Y7 Q3 O# w- W$ ~6 H
        ConsolePrintf( SLINE_LOG, TEXT("Thread Time: Avg=%.4f Max=%.4f(s)"),
    2 d2 B- g) p: V( _                                    m_fAvgThreadTime, m_fMaxThreadTime );; o' M- F- m+ u6 I$ ]
        ConsolePrintf( SLINE_LOG, TEXT("Players online (not including server player): %d"), m_dwPlayerCount );2 U, V1 i5 K; l( l8 `6 l1 T
        ConsolePrintf( SLINE_LOG, TEXT("Peak player count: %d"), m_dwPeakPlayerCount );
    ; |8 t/ [3 R# Y9 O) J( u  S* i3 z}</P>
    9 ^0 t2 _( J7 v3 j; ~0 `4 q! k' a: P) H. J& @% I* b
    <P>
    0 `, t" ?: I0 y+ B0 `9 q//-----------------------------------------------------------------------------. g' g3 U; _! p
    // Name: : q# Z5 A8 W: g8 x6 p
    // Desc:
    . i2 y+ J! M8 ~% I//-----------------------------------------------------------------------------
    ' j& c- {2 m8 Rvoid CMazeServer:isplayConnectionInfo( DWORD dwID ), C. l9 C# |7 y0 ^3 t: h, K8 J% ~
    {
    5 e3 {+ B' N& k0 m0 _" x    TCHAR strInfo[5000];
    * b; ~0 e  g7 e1 @    TCHAR* strEndOfLine;
    5 v. F; j1 D* O; H% n    TCHAR* strStartOfLine;</P>7 Q/ Z. O% k5 Q4 b- w1 a
    <P>    // Query the IOutboudNet for info about the connection to this user. w) `' y2 i; K6 ^3 ?5 N% v- S
        m_pNet-&gt;GetConnectionInfo( dwID, strInfo );</P>$ ^) Q# _) J' D4 T$ ]
    <P>    ConsolePrintf( SLINE_LOG, TEXT("Displaying connection info for %0.8x"), dwID );
    $ l% q) E. L" n2 ^: A% M4 g    ConsolePrintf( SLINE_LOG, TEXT("(Key: G=Guaranteed NG=Non-Guaranteed B=Bytes P=Packets)") );</P>
    + M& i2 R4 u7 x# p8 }8 \+ M<P>    // Display each line seperately
    ' M4 q: C- C' j    strStartOfLine = strInfo;8 e; J$ S/ g7 ^# K
        while( TRUE )
    + }3 e- I/ A; m: L+ o' D% `7 K' I    {8 `- f2 Y7 R! R+ @/ `# r
            strEndOfLine = _tcschr( strStartOfLine, '\n' );
    / d5 E# u$ r- g* D' ]' @7 t0 E        if( strEndOfLine == NULL )
    : t6 c8 ?  K4 W            break;</P>
    0 O1 Z" P6 @  o' k- ~9 z<P>        *strEndOfLine = 0;
    + @& Y9 F5 c  P9 v        ConsolePrintf( SLINE_LOG, strStartOfLine );
    % @/ `( L2 C0 ]7 w/ ^        strStartOfLine = strEndOfLine + 1;* G! r$ T$ `) p6 M+ d7 o# q
        }6 C  B) i9 M4 m" G/ k" ?& d/ i6 L1 W
    }</P>
    ) v3 K% }, e8 @1 l, F+ u! @" q* _* `. \
    <P>
    ! P) Y) x  S6 m7 N! x$ \. D//-----------------------------------------------------------------------------% r$ x; v% t& U$ E; T6 v' t* S
    // Name: - c: `; e' \1 B  ?' `' h
    // Desc: ) ^0 D1 o5 A& _+ w$ T) M; n
    //-----------------------------------------------------------------------------+ a, F: W+ ~" ?& Q: e: T) y8 _
    HRESULT CMazeServer::SendPacket( DWORD to, void* pData, + Q4 ^3 Q$ c1 V6 U- S% Z& n
                                     DWORD size, BOOL reliable, DWORD dwTimeout )# H0 m' M. ?, x# m& a4 q
    {& c: u! ?' U  F* j& t# h0 j2 J2 M
        // Chance of forcing any packet to be delivered reliably
    ( n* b9 y, A4 k& O    if( m_Rand.Get( 100 ) &lt; m_dwServerReliableRate )6 C& H3 l9 A. j  p6 p& c9 h
            reliable = TRUE;</P>$ H& F6 c8 m- t4 D6 m
    <P>    return m_pNet-&gt;SendPacket( to, pData, size, reliable, dwTimeout );
    3 M, G0 d6 V" Y$ X6 C}</P>
    1 s. _- K/ [# L$ q& N% }% U: J! B. [, I  |
    <P>" k' m$ U  ~6 o( k2 x) b
    //-----------------------------------------------------------------------------5 \( R" U) Z6 q6 ~8 e9 L- R, h
    // Name: 0 w+ G0 t  Z9 R
    // Desc: % N5 w1 O( ~0 @) j. S
    //-----------------------------------------------------------------------------
    7 j4 H& d* f0 _  F+ u2 Nvoid CMazeServer::SendConfigPacketToAll( ServerConfigPacket* pPacket ). U, o& k8 O% {, s5 [
    {
    4 k/ A% \5 q# L7 ]9 V4 y; i7 w    // If we're up and running, then send this new information to all clients# R# g$ `, V! Q% z: l7 }
        if( m_pNet )2 a9 M/ D8 J0 p2 c( ]% b& ]2 H& k6 j
        {& V+ S; n& y$ q$ R
            //Use the AllPlayers ID! D1 t1 S: Q) f& ?) D* Y  K8 T
            SendPacket( DPNID_ALL_PLAYERS_GROUP, pPacket, sizeof(ServerConfigPacket), TRUE, 0 );
    ( [% G( q# N% L9 c$ p+ j4 g    }
    6 j1 m" A/ x/ k7 b/ u}</P>
    " G' p, r/ {6 o7 @( q  o; I: i" f6 w- _/ y  v+ D
    <P>
    - V) ~, t+ p  E2 R$ z//-----------------------------------------------------------------------------
    " o) M, U8 i, s. @4 J// Name: * j+ _, b7 U+ T+ m* S
    // Desc:
    " P- G' k8 E. K% H; p- K//-----------------------------------------------------------------------------
    0 l% d, ^- ^7 k7 }7 n  Ivoid CMazeServer::SetClientReliableRate( DWORD percent )
    , H' o( ?" z# [0 {+ [- q{
    4 P% l' r: i3 k# U$ ^% U    // Update client config, and build packet containing that data
      a( E. |& t. q* A7 X1 c; Q; w* c% q$ d    m_ClientNetConfigLock.Enter();) w& }3 d/ ^- g, |5 z, [3 t
        m_ClientNetConfig.ubReliableRate = BYTE(percent);6 e. d( l: H6 u1 G
        ServerConfigPacket packet( m_ClientNetConfig );
    # y0 _4 @+ `9 b1 X- s1 M    m_ClientNetConfigLock.Leave();</P>2 I9 b$ _8 a( }( c$ r
    <P>    SendConfigPacketToAll( &amp;packet );
    % y3 u! h# L' z$ X}</P>" E4 \/ L/ c4 }: F# B! m; `0 X5 ^
    : K4 s8 S1 `0 k/ J8 f. q2 F! j
    <P>% `  s1 B, o. F$ G9 Q5 b
    //-----------------------------------------------------------------------------
    7 k6 V9 S, B+ Y' R- L9 u// Name:
    7 a- P$ P. D" g( L' K" r// Desc: ' n* c* F, y; c: S$ d
    //-----------------------------------------------------------------------------0 z$ }6 O( w% x, @1 H& ?* m
    void CMazeServer::SetClientUpdateRate( DWORD rate )5 H0 y' `- ~' s5 a+ m* Q$ d- Y
    {: F/ C1 K  {( t1 G' ]6 K
        // Update client config, and build packet containing that data
    1 m  q; u4 u: z% t    m_ClientNetConfigLock.Enter();
    ; u/ y2 w. p' v6 {+ ]/ t    m_ClientNetConfig.wUpdateRate = WORD(rate);
    0 i3 }1 y7 _$ a, J/ |    ServerConfigPacket  packet( m_ClientNetConfig );
    % e! V& w7 b' Y: V& v( p4 l    m_ClientNetConfigLock.Leave();</P>
    % h" [" G" P3 ~8 K( {/ T<P>    SendConfigPacketToAll( &amp;packet );
    # m) w8 @& d! M1 e9 N}</P>
    ( I& W: A6 ~! G2 s; c" r2 J
    # T1 q& J: f3 U( `# E<P>! W; z7 A0 f5 m) w& z
    //-----------------------------------------------------------------------------
    $ V* ?2 ]# L5 p: k0 G. e0 v7 f// Name:
    * O0 s6 r. H# C9 x8 c# l- a// Desc: / s, N4 _" ~" c( A' R( n7 q3 F1 z
    //-----------------------------------------------------------------------------
    6 d" U0 Y4 H- S( D  f5 y. y# X4 Dvoid CMazeServer::SetClientTimeout( DWORD timeout )' s$ y2 r& b% U9 j: C( {3 r; J) o% t
    {
    5 a1 L% W# |; y* l    // Update client config, and build packet containing that data# V! ]7 b; j% p
        m_ClientNetConfigLock.Enter();# E2 ]. ?0 e0 R3 \5 C: Z% h, h9 X! D
        m_ClientNetConfig.wTimeout = WORD(timeout);
    . r% [" \5 {) w    ServerConfigPacket  packet( m_ClientNetConfig );- R6 w4 x4 Z* N; r" \; ~5 e
        m_ClientNetConfigLock.Leave();</P>
    . s# _, K# L! g9 |<P>    SendConfigPacketToAll( &amp;packet );
    & t. q0 I% }' {$ D& f/ @* f$ {4 O: R}</P>
    ) _3 ?9 z2 l( q4 B8 y
    ( [: n! k4 @, b3 K6 l% s3 V1 ?<P>
    # `; P- L  @  j) T2 }: Z3 A//-----------------------------------------------------------------------------
    3 z1 e( J/ E1 i4 ?// Name: 3 f1 i' b' r* O- X
    // Desc:
    4 I4 ~  h5 L8 a//-----------------------------------------------------------------------------2 P. a& v/ {% A5 d
    void CMazeServer::SetClientPackSize( DWORD size ), [7 ^5 q/ d9 v( K
    {9 P" T  a; O! p1 k4 j* r9 o3 R8 a
        // Update client config, and build packet containing that data
    : J0 {  H# ~- \, m0 s    m_ClientNetConfigLock.Enter();
    ) }  ~; x! @! P8 W) z* F   
    . n0 n  P4 p; i& F; ]    m_ClientNetConfig.ubClientPackIndex++; //Increase index and verify location in array.1 C$ E( y0 @8 a6 j8 E" i
        if(m_ClientNetConfig.ubClientPackIndex &gt;= PACK_ARRAY_SIZE)   
    $ S# X; k) k! z/ m        m_ClientNetConfig.ubClientPackIndex = 0;</P>
    $ c, Z; e7 B; x5 C" _1 z: C<P>    m_ClientNetConfig.wClientPackSizeArray[m_ClientNetConfig.ubClientPackIndex] = WORD(size);- j3 o8 S. @6 W# ^& b2 j
        ServerConfigPacket packet( m_ClientNetConfig );% G: v5 s3 e5 z
        m_ClientNetConfigLock.Leave();</P>
    ' I  {/ n9 x; L+ \$ w9 x<P>    SendConfigPacketToAll( &amp;packet );& r. |+ m* N& A. J
    }</P>
    * L! a# z' ]9 @5 E5 i: i" ?( c$ ^3 h# h
    <P>
    3 A, j) d$ H6 X. K; [7 Y7 s5 X* k4 {//-----------------------------------------------------------------------------
    * E5 U2 n9 D4 F: T4 k" b- ^// Name: 7 n9 M, o! s( `) E: l! a
    // Desc:
      \; D- l/ n% D( I" r+ ?//-----------------------------------------------------------------------------
    ' }  v7 G; J0 ^: t3 ~3 Bvoid CMazeServer::SetServerPackSize( DWORD size )
    - n6 r9 ?7 c' A8 a) U0 N{
    , b9 j5 I6 O! C* ^. V    // Update client config, and build packet containing that data: ^' T$ J- O" u1 J% w
        m_ClientNetConfigLock.Enter();
    2 {+ G7 I5 c: R; u4 H   
    8 X9 B# o# A8 K9 z& ^    m_ClientNetConfig.ubServerPackIndex++; //Increase index and verify location in array.) G& Y8 A- v5 g0 Q# r7 J! u" q5 h
        if(m_ClientNetConfig.ubServerPackIndex &gt;= PACK_ARRAY_SIZE)   
    & d( G( J7 v' m6 u1 d/ |        m_ClientNetConfig.ubServerPackIndex = 0;</P>
    6 Z$ w' X2 ]  L* R( w& @# O) i& c<P>    m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex] = WORD(size);
    ; k& [( }9 D. A) |# f1 c4 `) L    ServerConfigPacket packet( m_ClientNetConfig );; Z& \" s) f1 r* L+ G* a
        m_ClientNetConfigLock.Leave();</P>0 K  T, G) h% T) T
    <P>    SendConfigPacketToAll( &amp;packet );
    0 E% _! c& F7 Z. `}</P>
    + T4 {2 a  j! L; U; T<P>  B8 b( s' @! L0 M  l$ h
    //-----------------------------------------------------------------------------
    2 u8 b% }" ?6 ?2 ]9 `// Name:   X, n' @$ o) Y9 j7 u) H
    // Desc:
      U1 H; g. g3 g% S7 T  h, N' s. q//-----------------------------------------------------------------------------) y  g& a/ v' z  |+ F9 N: V
    void CMazeServer::SetClientThreadWait( DWORD dwThreadWait )+ n  u' u0 Q: U) D
    {
    ; I( J/ s2 b: D3 U" O    // Update client config, and build packet containing that data1 I+ G' u) q$ {* j1 x% f) `
        m_ClientNetConfigLock.Enter();. D' U2 N4 f! F* ?& Y/ j
        3 k$ Q+ o% r) F5 Y* X
        m_ClientNetConfig.dwThreadWait = dwThreadWait;: ?' t3 e+ |, i
        ServerConfigPacket packet( m_ClientNetConfig );- v  ^" e# @  x5 Z9 n3 d$ B# ^
        m_ClientNetConfigLock.Leave();</P>. E* [' T3 x7 }9 W
    <P>    SendConfigPacketToAll( &amp;packet );
    " R' f- K/ f- b. v}</P></DIV>
    zan
    转播转播0 分享淘帖0 分享分享0 收藏收藏0 支持支持0 反对反对0 微信微信
    您需要登录后才可以回帖 登录 | 注册地址

    qq
    收缩
    • 电话咨询

    • 04714969085
    fastpost

    关于我们| 联系我们| 诚征英才| 对外合作| 产品服务| QQ

    手机版|Archiver| |繁體中文 手机客户端  

    蒙公网安备 15010502000194号

    Powered by Discuz! X2.5   © 2001-2013 数学建模网-数学中国 ( 蒙ICP备14002410号-3 蒙BBS备-0002号 )     论坛法律顾问:王兆丰

    GMT+8, 2026-10-8 07:27 , Processed in 0.690597 second(s), 51 queries .

    回顶部