QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 4168|回复: 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>
    6 i3 G: p4 j* ], i- |+ _<>// File: mazeserver.cpp. w" r) g( j0 l( {9 z) m; p2 |
    //* u) \. {( K( u3 ~/ n- I! b
    // Desc: see main.cpp, W2 A' p, ~6 P. Q* g& h) K/ B! d
    //
    . S3 Q/ B# I7 l! g9 O2 T+ f( P7 v// Copyright (c) 1999-2001 Microsoft Corp. All rights reserved.
    . K& @- q( Q! m4 v$ s( g! d: V# U//-----------------------------------------------------------------------------
    : k) G, h0 M2 h#define STRICT, S* }& a, a, b: R' o# {$ Y
    #define D3D_OVERLOADS
    * Q! E) z- {- Z: ?7 L& r#include &lt;windows.h&gt;
    $ i% x) P8 B3 q1 I, a2 f#include &lt;d3dx.h&gt;4 v3 P* Q( S/ E% ?" K* Q6 l
    #include &lt;stdio.h&gt;
    6 U! T# {: I8 u" @#include &lt;math.h&gt;
    8 r: \1 L/ \. \! e% e9 v( W: j' z0 J#include &lt;mmsystem.h&gt;
    ; i0 u; r0 B- v: F/ N#include &lt;dplay8.h&gt;: H* y/ h2 q) u1 I4 _& \
    #include &lt;dpaddr.h&gt;" E4 c  |; o/ v! e4 v! s3 y
    #include &lt;dxerr8.h&gt;
    5 }" y% _) {  S& M7 o#include "DXUtil.h"
    1 h! Q3 o( a+ `% y: L/ I) Z1 \, k#include "MazeServer.h"
    ) x( L  r# _2 Y1 K2 J% `+ b#include "ackets.h"
    5 Z! ?4 {$ K8 U4 Q#include "Maze.h"
    8 ?% n3 C; ^+ D9 I* g#include &lt;malloc.h&gt;
    - `% b$ p7 A- D1 C#include &lt;tchar.h&gt;</P>
    + m2 h# N  W. U7 Y( x
    . i& Z- o# j$ g6 v6 |* C<>//-----------------------------------------------------------------------------# ]1 O/ E3 E: J7 r, Q
    // Name: $ ?$ h& m" F* M" q
    // Desc:
    1 ^( g3 }; D* o//-----------------------------------------------------------------------------) Q: t! n, _0 E9 i; J8 d5 a. g- e  D) H
    CMazeServer::CMazeServer()
      t' P2 o; ]. C* O; ~5 a$ r{! _0 w3 v" d$ z7 }+ C$ h
        m_dwPlayerCount         = 0;
    $ Q9 |2 B; S2 S/ X   
    - P! u4 X. t9 k/ i# v' R* a    m_wActiveThreadCount   = 0;- C  T+ |) `9 U! t
        m_wMaxThreadCount      = 0;" m  T/ R: U' R
        m_fAvgThreadCount      = 0;9 A" a; d* x8 R6 [' C  f
        m_fAvgThreadTime       = 0;' ~/ }( }9 q% X* a! Q; N
        m_fMaxThreadTime       = 0;</P>
    2 U; Q, Q+ i3 ~# Q7 a" g4 W<>    m_dwServerReliableRate  = 15;
    0 M# j4 v/ c8 D    m_dwServerTimeout       = 150;1 R# Y5 i$ L) O
        m_dwLogLevel            = 2;/ |; P" T9 O& F, m7 e/ u* p- k
        m_pMaze                 = NULL;</P>
    & m& D) N: W0 |<>    m_ClientNetConfig.ubReliableRate = 15;: t0 d# b+ O, B
        m_ClientNetConfig.wUpdateRate    = 150;" h* k# d+ x% F7 R" X" a3 z
        m_ClientNetConfig.wTimeout       = 150;</P>
    - q  o$ f0 ^8 }( c, {# T% w<>    m_ClientNetConfig.dwThreadWait = 0;</P>
    1 S6 c) T9 W5 H# T# O<>    m_ClientNetConfig.ubClientPackIndex = 0;7 ?( J8 t4 _2 C: G4 f1 T
        m_ClientNetConfig.ubServerPackIndex = 0;
    , m2 @/ B, s) q) O! M& D    for(WORD x = 0; x &lt; PACK_ARRAY_SIZE; x++)
    ! z" m7 Y- D3 j: x6 X- }    {( b8 r' T2 j, _: R0 q6 c4 O
            m_ClientNetConfig.wClientPackSizeArray[x] = 0;$ z; J# B& r- q- }: `6 p
            m_ClientNetConfig.wServerPackSizeArray[x] = 0;
    " \  u: B0 D* ]; W) F3 S    }
    3 Q, U4 p1 h' {9 [# \8 j+ a: ]* [# @}</P>( I3 m3 {  s: N$ ~+ R, X/ m
    $ i- B3 z) h0 B' T- I8 [5 E
    <>
    $ Q! {/ z: J5 k9 K/ _* p& a" ~5 S//-----------------------------------------------------------------------------
    2 c  U4 b% g- Q0 P' }8 {// Name: # W1 m, W' d1 e$ c0 u( D" o
    // Desc: / N" r1 j; r4 W$ }! a$ D
    //-----------------------------------------------------------------------------
    , P0 ^6 \* E: A( s/ z1 N9 l6 ]HRESULT CMazeServer::Init( BOOL bLocalLoopback, const CMaze* pMaze )
    2 f  a* r% A$ J4 k* B' [: i{
    / f. X0 ?6 B/ m% w+ @    m_bLocalLoopback = bLocalLoopback;9 ^5 o  w4 y7 a0 H5 `# _8 A2 Q
        m_pMaze = pMaze;
    3 X- C: s* l6 P$ b" A    if( m_pMaze == NULL )
    4 q" Q; o0 t7 E3 X- u' @7 ~6 H, s        return DXTRACE_ERR( TEXT("aram"), E_FAIL );</P>
    1 S" \* u# ?1 C5 [<>    // Grab height and width of maze+ C+ D# H4 K% f
        m_dwWidth = m_pMaze-&gt;GetWidth();9 r8 }% C) E3 g- ]$ S
        m_dwHeight = m_pMaze-&gt;GetHeight();</P>
    # H1 {3 {6 W6 {" W<>    m_ClientNetConfig.dwMazeWidth  = m_dwWidth;
    8 t' [2 W9 ^9 e* ~    m_ClientNetConfig.dwMazeHeight = m_dwHeight;</P>! X. w3 e( F: [$ Z5 S7 l$ Y5 ~
    <>    // Validate size. Must be a power-of-2 times LOCK_GRID_SIZE. Compute the shifts.2 h) j2 a$ i2 ~, |2 l
        if( m_dwWidth &gt; SERVER_MAX_WIDTH || m_dwHeight &gt; SERVER_MAX_HEIGHT )
    # x+ Y3 k8 F2 B: T4 R5 |' V( t5 p$ {        return DXTRACE_ERR( TEXT("Maze height and width need to be less than 128"), E_INVALIDARG );
    ) ?3 m2 r. Z( r) {    if( (m_dwWidth % LOCK_GRID_SIZE) != 0 || (m_dwHeight % LOCK_GRID_SIZE) != 0 ). F/ H% K5 b" G$ i9 U
            return DXTRACE_ERR( TEXT("Maze height and width need to be divisable by 16"), E_INVALIDARG );</P>) w+ }1 Z7 L8 X( ~" h
    <>    DWORD scale = m_dwWidth / LOCK_GRID_SIZE;
    # P. j* P. E, L5 s  C    m_dwMazeXShift = 0;
    $ {. X4 ?8 ~6 K, @0 X    while ( (scale &gt;&gt;= 1) )) ~1 f' [4 W/ G& V- m5 M
            m_dwMazeXShift++;</P>
    9 H& q; o+ k5 w& b4 d; s& }0 j<>    scale = m_dwHeight / LOCK_GRID_SIZE;
    2 y, H& x) r! p    m_dwMazeYShift = 0;# Y  |# ^. o9 I8 h
        while ( (scale &gt;&gt;= 1) )
    % N2 l/ P" u: d8 |( M9 \        m_dwMazeYShift++;</P>
    7 s: B# h' W2 j, X, W<>    if( ((DWORD(LOCK_GRID_SIZE) &lt;&lt; m_dwMazeXShift) != m_dwWidth) ||$ y# `3 W/ q4 |& ~
            ((DWORD(LOCK_GRID_SIZE) &lt;&lt; m_dwMazeYShift) != m_dwHeight) )* [! o3 A9 R5 t+ e* f
            return DXTRACE_ERR( TEXT("Maze height and width need to be power of 2"), E_INVALIDARG );</P>
    4 m/ Y5 O. i( N$ J0 m<>    // Initialise the player list
    # ?9 g  V7 U3 ]0 }    ZeroMemory( m_PlayerDatas, sizeof(m_PlayerDatas) );
      h) Q7 b: M% U" [    m_pFirstActivePlayerData = NULL;6 S' S1 X& r5 J, w4 E
        m_pFirstFreePlayerData = m_PlayerDatas;: S. I  N4 l) G: X' B% f' X
        for( DWORD i = 1; i &lt; MAX_PLAYER_OBJECTS-1; i++ )! b4 a5 t2 n# V
        {) G+ h& y6 p* p) b2 U* g* a, ^
            m_PlayerDatas.pNext = &amp;m_PlayerDatas[i+1];
    ( ^  b; @2 t! E' x- e5 C        m_PlayerDatas.pPrevious = &amp;m_PlayerDatas[i-1];5 I' t2 l& m. m" n
        }</P>( T* ^  ^$ M+ a7 C! {
    <>    m_PlayerDatas[0].pNext = &amp;m_PlayerDatas[1];
    ! Q7 D) s+ L, E$ u) E$ D  Q' X    m_PlayerDatas[MAX_PLAYER_OBJECTS-1].pPrevious = &amp;m_PlayerDatas[MAX_PLAYER_OBJECTS-2];
    6 z% f8 W) T, W1 D% r" }    m_dwActivePlayerDataCount = 0;
    & v: W% d/ H# |. {7 w9 o; {    m_dwPlayerDataUniqueValue = 0;</P>7 w: L) p3 ?3 s
    <>    // Initialise the cells9 [6 O2 T2 L  U  j
        ZeroMemory( m_Cells, sizeof(m_Cells) );9 a* z2 q4 `8 d, K- u8 R
        ZeroMemory( &amp;m_OffMapCell, sizeof(m_OffMapCell) );</P>
    * v, V" ?, F: o) a- {- ^! K) @: H; ^<>    return S_OK;
    0 Z+ \5 ]7 F) o" r5 o" |+ R}</P>
    & l$ e! K, Z: h, w0 r2 }8 q4 x5 C: o1 E( U3 ^2 m
    <>
    6 y4 M% L9 O# G% U! Z0 m//-----------------------------------------------------------------------------
    3 j. y: {) q6 @  R7 g$ o// Name: 8 B7 v5 v' b/ }" S
    // Desc:
    % W$ E' ]# R6 m" x& u//-----------------------------------------------------------------------------
    % G; h" g+ @$ qvoid CMazeServer::Shutdown()
    7 J& d; @0 C; R( B. W4 ^{  b( S0 R1 T# o9 d9 Z1 V, t
    }</P>
    + S0 Q! c1 E2 u/ k- i8 g0 w
    " i% E4 \+ J6 q' _3 {/ B<>
    ) s  R! d  \9 H, h; T! X+ O* z//-----------------------------------------------------------------------------
    " _& b6 W9 O, G+ @9 Z// Name: # n2 q7 m. S2 O+ h  i# C
    // Desc:
    / W5 v6 b/ S% t+ `5 m//-----------------------------------------------------------------------------( Q' E' j; u: r
    void CMazeServer:ockRange( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )
    0 J6 ~" _: W4 P6 V{$ \: j5 b6 ?4 @- }; T9 U
        m_LockGrid.LockRange( x1&gt;&gt;m_dwMazeXShift, y1&gt;&gt;m_dwMazeYShift ,
    / e3 T# @& y' M8 D; v2 N+ a# o6 b/ K                          x2&gt;&gt;m_dwMazeXShift, y2&gt;&gt;m_dwMazeYShift );6 s+ j( f9 `8 f3 R+ t0 Z! K6 B; i
    }</P>
    0 j* P. p3 D" Y0 B9 ?
    2 e. w& x6 L' ?1 h% W: K/ G- l<>
    & f. w+ e' J  ]$ S( [4 s2 I8 j//-----------------------------------------------------------------------------
    1 j' O; o$ a" J3 S3 d1 J$ b. V// Name:
    ; y5 _. S3 w6 A2 I2 g4 V$ D// Desc: : F$ O& b! ]8 o; R( Q! Z
    //-----------------------------------------------------------------------------
    5 d" C# t0 \/ Gvoid CMazeServer::UnlockRange( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )% n* Z) Q9 I4 Q
    {$ W$ z) t1 g9 i/ b! {
        m_LockGrid.UnlockRange( x1&gt;&gt;m_dwMazeXShift, y1&gt;&gt;m_dwMazeYShift ,
    ; ^# E5 h* q& A                            x2&gt;&gt;m_dwMazeXShift, y2&gt;&gt;m_dwMazeYShift );
    0 U6 J" }( Z# L) H}</P>
    , ^8 ^% S, H1 x3 t+ T4 ?6 K/ H# b- x: Z+ G4 i2 x
    <>
    + V7 L: U' ]' L! p1 ?) F//-----------------------------------------------------------------------------
    0 W4 {7 q/ X! `% ?2 t( w1 M// Name:
    ( n' ]. B! @" v9 x6 @0 k// Desc:
    + O; j# [& [% X' ?1 _//-----------------------------------------------------------------------------( ?+ u4 i" A- `* h* q9 W, w
    void CMazeServer:ockCell( DWORD x, DWORD y )
    ; W3 @9 {" h( ?# C{) n- X, P2 k# M2 k, l
        if( x == 0xffff )# h7 f; n9 f- V8 M: _
            m_OffMapLock.Enter();' L2 }7 u0 D  \7 L- t
        else8 c4 Y9 y; s: P/ S; ~
            m_LockGrid.LockCell(x&gt;&gt;m_dwMazeXShift,y&gt;&gt;m_dwMazeYShift);
    ' W! L+ u! J8 ]. t8 `4 x}</P>
    ; j! y/ S  C# o6 S$ \9 K
    ; s6 e9 Q( l: @. C3 x' w  ^<>5 Z! s- D! ]4 ?
    //-----------------------------------------------------------------------------* a/ O9 m% c" w2 y- {
    // Name: ; U7 C! h) \6 _9 ~1 i# @. W
    // Desc:
    3 j+ W! Y& O% ]) D$ @//-----------------------------------------------------------------------------5 v+ p% |4 A* W; x1 Y, E
    void CMazeServer::UnlockCell( DWORD x, DWORD y )3 c& T. A/ _$ t0 w+ O/ r, u" c/ c
    {
    1 a# ^. N5 Z& w0 b: m( k    if( x == 0xffff )9 N9 U9 B/ b% k5 q+ x, q) H
            m_OffMapLock.Leave();$ A% B5 t  L: F6 U( w
        else
    , m0 n( \# g% [        m_LockGrid.UnlockCell(x&gt;&gt;m_dwMazeXShift,y&gt;&gt;m_dwMazeYShift);9 w; }! j" O0 ?% B% H# u7 o5 T- [1 D
    }</P>
    4 q% R( J# O( [% C( E
    " a. L; P% b6 C: n/ h<>
    1 i! p! X) U+ d: S" o' a: H6 }//-----------------------------------------------------------------------------
    ( s+ v0 n+ w% G, B// Name: 6 ^% \2 Z  I4 E% ~: H! k, p' d' H% l
    // Desc:
    " U9 C* B7 y: ~% d  X$ D) @! P//-----------------------------------------------------------------------------3 o* Z& Y+ T3 G. z1 F8 e: W$ A
    void CMazeServer:ockCellPair( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )& J7 r2 Z1 {- _- w9 ?/ j5 a
    {
    2 n! w, ]' J! y! {# f/ C    if( x1 == x2 &amp;&amp; y1 == y2 )) g! ~9 l$ _& V
        {
    . U+ l  y4 y! G        if( x1 != 0xffff &amp;&amp; y2 != 0xffff )$ S! |1 [4 g3 L3 }( l$ }  |0 a. z
                LockCell( x1, y1 );, |# L2 Z( e8 E. l
            else
    . f$ ^: i! x' X* T: ?            m_OffMapLock.Enter();</P>
    + \2 O) ^$ R2 _! p4 r# G% t<>        return;' c# V/ @2 n$ \2 i
        }</P>- |  |" Y2 V) U4 u$ s. E
    <>    DWORD x1shift = x1&gt;&gt;m_dwMazeXShift;, |% J/ V* |7 R, d
        DWORD x2shift = x2&gt;&gt;m_dwMazeXShift;9 T- h# I& q2 d3 ]
        DWORD y1shift = y1&gt;&gt;m_dwMazeYShift;
      y/ Z% O+ ?% C, s9 t" U# \/ ~/ h0 a% G    DWORD y2shift = y2&gt;&gt;m_dwMazeYShift;</P>& c, z0 `9 J- R1 a  u; y
    <>    if( x1 == 0xffff )$ F* n2 N' I4 S! F3 P& c5 [
        {- @' ]3 `, k+ K0 v/ H
            m_OffMapLock.Enter();: b# g0 o: c/ o; x8 X
            m_LockGrid.LockCell(x2shift,y2shift);  a, }4 J& G) C0 F
        }
    . v4 f8 D' O* J    else if( x2 == 0xffff ); ]5 l, F( `( p5 p1 O
        {
    % N9 b$ @/ X' v( }$ \+ b! @& `        m_OffMapLock.Enter();
    7 S: @; b! t7 A9 k% i        m_LockGrid.LockCell(x1shift,y1shift);
    " f, s2 D5 X% n3 N3 Y! i8 _* s0 F    }, [. ^" I7 |* N7 z3 m: ~9 i3 \5 {
        else
    ) P! U' b# J+ S& t! e' C, T; K1 f    {
    . x- M* l9 E- U: |+ P  X; s        m_LockGrid.LockCellPair(x1shift,y1shift,x2shift,y2shift);
    * i( Q6 J' d2 B3 w" n+ y! k    }
    ; G% S0 J. x$ x5 @' f}</P>
    ' D1 D2 U. i' \0 z  n7 b$ Q7 {' p0 Q- X: u5 [4 s+ S3 `" G) l
    <>
    , c5 F* L$ o  t! n2 L. n6 t, M//-----------------------------------------------------------------------------
    + \, P, i- q" w, u3 m: W: N// Name:
    / T4 J1 v: W* x3 O- q4 v% F. |: l9 P// Desc: ; D- ^1 Z+ O) ^* G* `
    //-----------------------------------------------------------------------------
    . X( N" n/ N; ]0 ]+ avoid CMazeServer::UnlockCellPair( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )
    # o+ R5 {2 T9 T- r. J{
    5 i% |  n: b! W2 C1 G9 ]    if( x1 == x2 &amp;&amp; y1 == y2 )
    1 n% v6 i: j7 O. \7 j4 L0 a    {" e3 }3 O8 s5 J2 B
            if( x1 != 0xffff &amp;&amp; y2 != 0xffff )% A$ Z' b3 ]+ ~3 ?
                UnlockCell( x1, y1 );
    ( D. ~+ ^1 r" ~( V; ^$ S# D        else" T1 F# A- ^7 ^' _/ j
                m_OffMapLock.Leave();</P>
    % f" G, ~: N) _0 W<>        return;
    : t! z; b, f5 @1 |1 _9 }/ z    }</P># z7 X' M0 Y8 K( ^6 s
    <P>    DWORD x1shift = x1&gt;&gt;m_dwMazeXShift;
    # S1 H, {) M5 M    DWORD x2shift = x2&gt;&gt;m_dwMazeXShift;
    * K3 K+ s: w7 f6 ?: H6 ^% Z    DWORD y1shift = y1&gt;&gt;m_dwMazeYShift;
    ; B  `: Q: g- D" a# k6 G- D' s    DWORD y2shift = y2&gt;&gt;m_dwMazeYShift;</P>6 a6 o, d& {8 R: n6 W" b! G
    <P>    if( x1 == 0xffff ), u" R6 X" t( Y6 p6 {
        {7 _+ G7 X: O& w
            m_LockGrid.UnlockCell(x2shift,y2shift);
    % @- H$ k6 ^' \7 F2 F% [        m_OffMapLock.Leave();
    # p& ~. F, f' {0 W9 W+ x7 M    }
    ! }9 A0 o5 M  a! B, Y7 [4 _% g' i    else if( x2 == 0xffff )1 T) `/ A& u' B
        {9 x9 y+ ^9 Z1 ^# B
            m_LockGrid.UnlockCell(x1shift,y1shift);
    / q' ]% O9 P$ ]7 J  E8 I4 Y        m_OffMapLock.Leave();/ l7 a- d( n% f. z9 A% C# }
        }( I% K! L$ y# Q- r
        else ; f! o$ c* o6 A7 Z
        {
    : n1 \- C6 W+ L: ]- s7 F        m_LockGrid.UnlockCellPair(x1shift,y1shift,x2shift,y2shift);
    3 u* b  y5 K, W6 p$ w0 u    }
    , f% x* \' Y' H- Z5 s, m, P}</P>% C- f. }3 k) ^9 e

    1 t0 J9 m' \: T% w, f<P>
    2 @9 P2 |3 k1 x6 L4 b6 P2 S: w+ \//-----------------------------------------------------------------------------
    - Q1 T/ m' _1 w& {0 B; t7 Y- g// Name:
    $ k, B" Q: z3 a$ }8 S// Desc:
    0 F% C6 w! [7 D8 W//-----------------------------------------------------------------------------/ e. G, v; e2 z( I& _8 p: P
    void CMazeServer::OnAddConnection( DWORD id )
    1 d. U+ a3 M0 a+ W/ T5 \, b; k5 F{
    . P3 S6 R! J( w% P, K: G1 W; k    m_AddRemoveLock.Enter();</P>$ w* B/ X; t6 \: p
    <P>    // Increment our count of players' [$ v1 g" V  S% D. l, P7 j
        m_dwPlayerCount++;
      s$ W/ F- S; o/ ~% O    if( m_dwLogLevel &gt; 0 )6 N3 ?( p$ j0 V3 ^
        {" K! U$ W( l5 q& u# L: I0 ~
            ConsolePrintf( SLINE_LOG, TEXT("Adding player DPNID %0.8x"), id );
    ! U/ C- |" @5 R, j        ConsolePrintf( SLINE_LOG, TEXT("Players connected = %d"), m_dwPlayerCount );, x; G" e: d0 V) c+ a2 D  Z
        }</P>
    : E1 [, S! u2 Q9 E, }9 `* v<P>    if( m_dwPlayerCount &gt; m_dwPeakPlayerCount )
    * I$ r/ i; r) o- H4 c        m_dwPeakPlayerCount = m_dwPlayerCount;</P>
    # K% F! c* w# d( t0 }; w& {<P>    // Create a player for this client! a# q0 D. G* [( {+ u9 q
        PlayerData* pPlayerData = CreatePlayerData();+ q7 J8 L: A; b5 w# |; j
        if( pPlayerData == NULL )
    / a2 {: \) z& T6 S    {
    3 k& v5 N& N$ J4 ^7 v2 V) t1 T% [+ R9 C        ConsolePrintf( SLINE_LOG, TEXT("ERROR! Unable to create new PlayerData for client!") );
    , m6 g# ^' b5 R# G        DXTRACE_ERR( TEXT("CreatePlayerData"), E_FAIL );9 l/ T1 f: n2 o6 L' E9 D
            m_AddRemoveLock.Leave();& v" q( t' P; f) w: z+ k* t6 [
            return;. x+ T- i/ {0 Y5 L( S8 B
        }</P>: w; V6 F3 a( e8 U  [
    <P>    // Store that pointer as local player data
    * }/ l1 v) B; K- q- I    SetPlayerDataForID( id, pPlayerData );</P>
    1 ~6 a4 E6 t9 q/ j<P>    // Grab net config into to send to client
    ' L8 @4 q% y1 E  H3 v9 p6 _    m_ClientNetConfigLock.Enter();
    . B$ g3 L* X2 O6 M9 b    ServerConfigPacket packet( m_ClientNetConfig );
    / h* s0 i  {  y; q1 k    m_ClientNetConfigLock.Leave();</P>
    7 E0 [9 L( k4 b, ]$ ~$ D<P>    // Send it: \! S1 b% q0 V- m
        SendPacket( id, &amp;packet, sizeof(packet), TRUE, 0 );</P>; x/ k7 l; f. ?
    <P>    m_AddRemoveLock.Leave();: L5 P4 \' _8 t( M
    }</P>
    * l  w- p: V( E7 V! C  V& p, V
    3 a. t, L8 X$ Y  b# e<P>
    ! I& {3 P" ]3 [: ^//-----------------------------------------------------------------------------
    # h2 A7 Z/ c8 F// Name: - I3 o+ X7 D5 c3 P0 r! w
    // Desc: ) j: D% `5 u$ H5 L  ]3 @( k& e! ]- M
    //------------------------------------------------------------------------------ }' Q% q9 c2 S- O0 {- T9 Z
    void CMazeServer::OnRemoveConnection( DWORD id )
    - m# U% P. c3 a8 Y0 ]{
    ; T2 V5 W  L. B/ c6 X0 G1 m    m_AddRemoveLock.Enter();</P>
    ; k9 L: \- M* }<P>    // Decrement count of players/ h- r4 ]( N* t$ J
        m_dwPlayerCount--;</P>
    4 y* J/ @' B+ T  e# |# H: b! B<P>    if( m_dwLogLevel &gt; 0 )
      r3 E9 {: p7 z9 ~  i) Y: J. N* c    {
    . e& y$ P8 b5 G  P" i        ConsolePrintf( SLINE_LOG, TEXT("Removing player DPNID %0.8x"), id );0 Y4 L0 n; A5 v( L
            ConsolePrintf( SLINE_LOG, TEXT("Players connected = %d"), m_dwPlayerCount );
    0 D& m1 ]2 Q1 L    }</P>
    2 j/ v. F) X5 G( S<P>    // Find playerdata for this client
    - V% t: a0 i% |, p: P    PlayerData* pPlayerData = GetPlayerDataForID( id );9 j5 a" Z" ^9 U2 A1 ?+ i$ T, O$ f
        if( pPlayerData != NULL )  ]3 m8 X7 f% p2 Q' `( }* L9 f
        {) q4 k7 A4 J% ~
            // Destroy it
    0 M$ a% w, f2 D" z% w0 s# |* u        RemovePlayerDataID( pPlayerData );
    ! H# ^" B1 E3 ?        DestroyPlayerData( pPlayerData );* q7 R# ?3 w2 Z1 @; d
        }</P>( L' r3 `: x, t& N' T9 h
    <P>    m_AddRemoveLock.Leave();
    / n1 v* ^4 _7 }; c}</P>
    " O; i/ }1 S9 ^$ B/ `# S/ }4 @3 H8 `; y. @4 |. B3 X
    <P>
    $ ]) w+ `: _( I% Z5 G: c//-----------------------------------------------------------------------------5 K. E  @: G5 |! }3 B
    // Name: / N2 X9 c6 W% |! d# z" j
    // Desc:
    2 W0 o, C. P9 ]( Z& T) G& y//-----------------------------------------------------------------------------  j3 c2 T8 W4 @  V1 g6 B! B' O
    HRESULT CMazeServer::OnPacket( DWORD dwFrom, void* pData, DWORD size )
      }) z+ E7 [* M% e4 C$ c. H& E{3 J! b; ^4 W+ G6 V
        BOOL fFoundSize = FALSE;</P># ]5 c1 a) h* T1 T6 q) w6 V
    <P>    // Increment the number of thread we have in this process.
    * T1 U: }$ p6 p5 [    m_csThreadCountLock.Enter();</P>% T3 e  i) ~, w' n0 k8 o
    <P>    //Get the start time of when we entered the message handler.) F" S$ i# B6 v4 A. e
        FLOAT   fStartTime = DXUtil_Timer( TIMER_GETAPPTIME );</P>% h+ C& J9 b; W% b: n/ ?- d, h: C) U) T
    <P>    m_wActiveThreadCount++;0 e! D# I" C; ^4 K9 d& C8 @/ [: U
        if(m_wActiveThreadCount &gt; m_wMaxThreadCount)
    1 ~- i2 E) t6 `        m_wMaxThreadCount = m_wActiveThreadCount;6 a7 V( H( r) l' L  f
       
    ' j% {+ I; R- I' O0 j3 B" G    // Calculate and average.
      L8 r7 q( m8 a* w6 |    FLOAT fdiff = m_wActiveThreadCount - m_fAvgThreadCount;
    ' u! K/ T7 B1 n; v    m_fAvgThreadCount += fdiff/32;
    ) Y/ h" ~( X9 s& c5 N; w; x9 Q6 k   
    3 [. [; q2 @7 j    m_csThreadCountLock.Leave();</P>
    . _, H' M9 z" T, H+ |<P>
    7 ]) J9 Z  X0 r) z    ClientPacket* pClientPack = (ClientPacket*)pData;
    % l0 U6 u# M: ~6 r    switch( pClientPack-&gt;wType )  G( P$ w7 t+ V
        {" Q, I0 r1 o& F4 F; H* ?
            case PACKETTYPE_CLIENT_POS:
    ' \7 x8 R' E) E4 x. t8 k, {# n. U            
    # u' M8 }. }+ E4 k            // Check to see if the packet has a valid size. Including 4 R* k% L- C% h* o4 X( y; E
                // the custom pack size.8 {/ N0 r# y7 f( ]5 F$ _- I
                if( size &lt; sizeof(ClientPosPacket))$ r$ J# J) L8 j3 \' m: ^2 p
                    fFoundSize = FALSE;9 K9 ^+ @5 `; {  _; s5 U" G
                else if( ! IsValidPackSize(size - sizeof(ClientPosPacket)))6 C2 ~: D, ?# V% H2 V
                    fFoundSize = FALSE;9 t- ?7 F0 k( f  V/ b  z' v
                else
    # Z$ |. @. b6 c) ?0 F                fFoundSize = TRUE;</P>9 j1 e+ K# m: X" q+ g* T
    <P>            // If valid sized packet, handle the position.* n; G+ D" k  @: B* `
                if(fFoundSize)( u9 x! F! m) X8 d4 `/ b
                    HandleClientPosPacket( dwFrom, (ClientPosPacket*)pClientPack );; G  m8 ]& W" H, f' N$ z/ k* V5 [
                else
    1 n5 l* H0 S; i                m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );</P>
    1 ]7 l; Y& n3 {" v3 ]) t<P>            break;</P>( _8 ?! K3 z9 N$ r  ^
    <P>        case PACKETTYPE_CLIENT_VERSION:7 S6 i7 E: i( R( C
                if( size == sizeof(ClientVersionPacket) )' p6 C. C& G# y$ v
                    HandleClientVersionPacket( dwFrom, (ClientVersionPacket*)pClientPack );$ k" u! I6 P# b
                else
    $ F. @+ r  {$ i; V. V" `                m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );6 R5 Z# J7 J0 [5 v/ Z) x) t8 q
                break;</P>
    $ y. g4 T/ d- h& L3 g0 c  k  U<P>        case PACKETTYPE_SERVER_CONFIG:</P>
    0 }2 U7 I* w$ k1 |0 f<P>            // Server config packet sent to all users (including server). Just ignore and continue.</P>
    , v  K# q4 v( c3 q: |, l0 S# Y<P>            break;6 \2 |1 y! ^% f: `2 y" c
            default:
    9 b* ]. X6 P; W5 }0 ]; X/ W1 P3 f            HandleUnknownPacket( dwFrom, pClientPack, size );, z8 ^- y9 w' Q+ ]9 Y$ h5 q' S
                break;8 K9 O& Y4 `, N* g3 k2 l- M; L
        }</P>' @9 }) e; K0 ]' f) k8 [' i. F
    <P>    //If the user wants to hold the thread, Sleep for given amount of time.+ P7 {8 Z8 w! [3 V5 N/ [+ b3 d
        if ( m_dwServerThreadWait &gt; 0 )
    9 u' X% D9 i+ f: h- F0 W9 ^2 J    {
      m+ P! |1 |" G" D( @        Sleep( m_dwServerThreadWait );& k% ^  X" z( i- r3 ]
        }
    # }& S. L& Q; Y+ ?' l# V   
    9 a! c( J# ?  f$ h( ?4 v, D6 X    // Retrieve thread data for this process.
    ( e  b5 k0 o$ N$ t% l8 l) @    m_csThreadCountLock.Enter();</P>+ N  D  }; ^) B1 H$ D4 P% }
    <P>    m_wActiveThreadCount--;</P>
    1 S, `6 P; ~. U( O7 G5 |+ B  u<P>    FLOAT fDiffTime = (DXUtil_Timer( TIMER_GETAPPTIME ) - fStartTime) - m_fAvgThreadTime;. c2 T  U4 k" I) |/ u  ]1 }# D5 F
        m_fAvgThreadTime += fDiffTime/32;</P>
    : X! H2 k8 Y* v& h3 w, v<P>    //Get the Max time in the thread.& n1 r( W/ k* v/ z8 h. N6 Y7 z; G
        if ( fDiffTime &gt; m_fMaxThreadTime )
    # h2 H$ o/ @7 S    {
    - H( H8 X( G0 P5 B; Y, i        m_fMaxThreadTime = fDiffTime;
    ' G! p7 o3 O/ }$ T# c    }</P>
    - m9 `, d9 G% o/ H7 Y<P>    m_csThreadCountLock.Leave();</P>2 g: f3 T: z4 b- \
    <P>    return S_OK;7 X8 n/ x% p* ~+ p+ Q. J$ E$ Z
    }</P>
    * U" `2 I$ L! f5 n4 V9 W4 P- \) y( _' i
    <P>//-----------------------------------------------------------------------------# E& D. e3 I( f' Q7 @# A) N
    // Name:
    7 I, s2 s0 ]) x- o// Desc: % r7 Z+ x- t5 I5 U& c
    //-----------------------------------------------------------------------------
    % I1 Y8 ]2 S& I- T! kBOOL CMazeServer::IsValidPackSize( DWORD dwSize )
    6 Q. N- {# W9 e/ v{0 I; v* C* T4 [# {6 H  T* P
        BOOL fFoundSize = FALSE;
    - V/ J- G! m8 z$ \% l. a    BYTE ubPackLocation = m_ClientNetConfig.ubClientPackIndex;& e; `+ \9 V' N) V0 k
        % `' g# q- T- k& b9 R5 O
        // Check through the array of valid pack sizes.
    2 \8 C) ]! s  _- G% X5 y( v. f6 |    if(dwSize != m_ClientNetConfig.wClientPackSizeArray[ubPackLocation])8 L# j" e5 w5 G. q( L# j7 e
        {
    + ]# ^# ~) P' p1 M2 I        for( --ubPackLocation; ubPackLocation != m_ClientNetConfig.ubClientPackIndex; ubPackLocation--)
    % i* @4 u/ P' h0 `3 C0 \4 J7 ?% Z        {. a3 s3 p2 a! _  W
                if(dwSize == m_ClientNetConfig.wClientPackSizeArray[ubPackLocation])8 |% i; P. i. G2 I5 @7 i* V
                {6 q! F9 R  O: H
                    // Found valid size in the array.! V9 a1 T9 b3 L+ A/ n
                    fFoundSize = TRUE;
      U# C. X- H9 N* N                break;; f, ?$ n# n$ r) x
                }  @7 |7 G0 o$ {0 y9 x. G2 f4 R
                if(ubPackLocation &gt;= PACK_ARRAY_SIZE)  ubPackLocation = PACK_ARRAY_SIZE;  //Wrap the array.9 O9 G2 A" _8 ~1 @( o& ~& {
            }
    : t# l* x- P( X9 S' A) N( v* F4 B    }2 R" m8 E5 [, A0 h; J( h
        else) ?- q4 \( ^" a6 W" v
        {
    3 u* i7 ?. D7 g' r        fFoundSize = TRUE;* c" M) P7 S; P/ M: a
        }</P>' i* Q/ h- T, A+ y
    <P>    return fFoundSize;: u2 w: u; {) w6 ^- w# ]3 I" O4 g
    }</P>  i- F7 @4 t3 _! o4 @6 Y
    <P>' g! O8 n0 ^0 Z" x( {. `) D
    //-----------------------------------------------------------------------------
    ) l' z  ?- `* p9 d// Name: 4 K+ z: u2 I4 ^3 f  [- }
    // Desc:
    + s% s9 \( ]1 W) G+ Y9 G//-----------------------------------------------------------------------------6 z) o2 f/ P, A0 C  B# T6 K. C
    void CMazeServer::OnSessionLost( DWORD dwReason )
    4 u9 Q* |8 D( j{
    5 {& V) Q: b4 X( |2 H    ConsolePrintf( SLINE_LOG, TEXT("ERROR! Session was lost") );5 S) t% e$ U. z! y5 U1 h0 F5 k5 K' H
    }</P>% r; X- s3 p4 T  C

    3 D5 X( B$ r1 T- R4 X1 G! c<P>1 x9 k% Q* v# I% s
    //-----------------------------------------------------------------------------4 n, `6 K/ r" k; N3 f6 I
    // Name: 6 j0 b) T- f1 J7 G$ t
    // Desc:
    & R( `% v- E3 r" O. A) u, b+ E//-----------------------------------------------------------------------------  M8 a8 J2 O0 g$ U4 i
    PlayerData* CMazeServer::CreatePlayerData(), E, x' q, B  v' T: M
    {
    1 `# P: E, F, t2 D& w; R    m_PlayerDataListLock.Enter();</P>
    & W1 D, U1 o  i9 t+ c<P>    // Grab first free player in the list
    % {7 S3 n  e  j1 X) f  L5 y    PlayerData* pPlayerData = m_pFirstFreePlayerData;</P>
    " n: q8 Q2 ?6 C6 Z<P>    if( pPlayerData )
    2 z; Q" ]1 }) {0 A8 e5 U6 m" V    {
    ' V9 K" }' m- f. r3 {        LockPlayerData( pPlayerData );</P>1 [& k9 r7 ]+ h6 q! c. o, q
    <P>        // Got one, so remove it from the free list) D/ I1 [1 w8 e$ Z) D) u9 Q# B% e
            if( pPlayerData-&gt;pPrevious )
    $ Z7 R0 ]9 \: I5 E  O            pPlayerData-&gt;pPrevious-&gt;pNext = pPlayerData-&gt;pNext;( A- {* }% \+ O, e" z
            if( pPlayerData-&gt;pNext )
    * H( H' K$ e2 E! t            pPlayerData-&gt;pNext-&gt;pPrevious = pPlayerData-&gt;pPrevious;
    5 A# _/ ^" K/ a# f. D: P$ r9 P        m_pFirstFreePlayerData = pPlayerData-&gt;pNext;</P>
    " X1 K, k! B, ?. d3 W5 {9 X<P>        // Add it to the active list5 q9 z7 r! @4 q3 X6 j1 O
            if( m_pFirstActivePlayerData )( J1 s7 e' C+ f5 c; `2 Z
                m_pFirstActivePlayerData-&gt;pPrevious = pPlayerData;, C% [4 b6 w1 ?- j0 y1 U. N! S
            pPlayerData-&gt;pNext = m_pFirstActivePlayerData;
    3 |+ d0 t  P+ y8 O1 i! x        pPlayerData-&gt;pPrevious = NULL;
    & A% C, |( ]! |, V4 H% \2 d) ]( _        m_pFirstActivePlayerData = pPlayerData;</P>
    % U4 S6 P& V( G" ?, N3 H3 G5 y7 o<P>        // Update count of players
    , P( _0 J) ]! B        m_dwActivePlayerDataCount++;</P>, b+ b% W$ S9 M: M/ A0 f: o
    <P>        // Generate the ID for this player
    1 V+ s8 H! k/ h        m_dwPlayerDataUniqueValue++;4 i$ A8 T" U4 R) X: D
            pPlayerData-&gt;dwID = (DWORD) ((pPlayerData-m_PlayerDatas)|(m_dwPlayerDataUniqueValue&lt;&lt;PLAYER_OBJECT_SLOT_BITS));</P>
    0 ^* E0 h( n7 S  m. O1 G+ k<P>        pPlayerData-&gt;pNextInIDHashBucket = NULL;
    8 S8 U% w+ L$ `3 s        pPlayerData-&gt;NetID = 0;+ S: a& C% h: A) P% j" Q
            pPlayerData-&gt;dwNumNearbyPlayers = 0;</P>. A% M1 _2 L2 {
    <P>        // Insert into the "off-map" cell% S( M' X/ z7 B4 Q/ m: g5 B# [- w
            pPlayerData-&gt;fPosX = pPlayerData-&gt;fPosY = -1;
    ; r1 O. f4 z5 h* B        pPlayerData-&gt;wCellX = pPlayerData-&gt;wCellY = 0xffff;
    * X+ ~5 C. G9 e$ h        m_OffMapLock.Enter();5 n* Z. ?- l" m- U* k6 w' R
            pPlayerData-&gt;pNextInCell = m_OffMapCell.pFirstPlayerData;
    : j9 w5 j7 [7 n$ O& V+ C        m_OffMapCell.pFirstPlayerData = pPlayerData;
    6 a: k4 o; d* {' y7 J        m_OffMapLock.Leave();</P>
    ' a+ w2 X: P: J, f9 C# o* E<P>        // Mark as active
    9 m4 b" f- Q6 Z        pPlayerData-&gt;bActive = TRUE;</P>
    4 X8 b8 a% Q' F: ]+ J* I* W1 t! S+ e- [<P>        UnlockPlayerData( pPlayerData );
      ?; C$ t! U$ w4 l" y) m    }</P>$ y; ^5 D) H  u0 a  W
    <P>    m_PlayerDataListLock.Leave();</P>
    ) Q5 G' g( d% b) S% N, }<P>    return pPlayerData;
    # o+ {+ H  B# I1 T}</P>: d$ Z; x; C2 c2 T2 _% N" m

    , c2 I, i4 _7 i1 t5 d$ Q<P>
    . K" ^+ i. ?! J* n+ N//-----------------------------------------------------------------------------
    : X! t5 f3 f! b( S6 `& o2 F% F// Name:
    : z2 n3 j, A0 Y- r  D# z6 N! Q! l// Desc: 3 E; {3 S) k$ J. C
    //-----------------------------------------------------------------------------0 o, c; N1 g) j3 T9 M
    void CMazeServer:estroyPlayerData( PlayerData* pPlayerData )9 Q2 ^- n" b& @. M" I* K9 f% Z
    {. @, P+ M1 M3 M
        m_PlayerDataListLock.Enter();* R3 ?2 J9 Z4 \. F% J
        LockPlayerData( pPlayerData );</P>
    & Q) W1 M/ T! `<P>    // Remove the player from its cell
    6 ]9 H2 Y$ V, s    RemovePlayerDataFromCell( pPlayerData );</P>
    1 o, {) K! m1 M- u" d  V<P>    // Mark as inactive0 e5 D* F/ P: @8 i' H" u4 o! p
        pPlayerData-&gt;bActive = FALSE;</P>- B/ j; j/ D- c4 F( l+ T
    <P>    // Remove player from active list, ^; E: ~# m- a  r
        if( pPlayerData-&gt;pPrevious )
    ' q  i: B6 i7 d$ y8 ^        pPlayerData-&gt;pPrevious-&gt;pNext = pPlayerData-&gt;pNext;
    4 t% E+ h* J8 h% G" J    if( pPlayerData-&gt;pNext )6 a8 G( |5 P* k' l
            pPlayerData-&gt;pNext-&gt;pPrevious = pPlayerData-&gt;pPrevious;</P>7 i. a8 r" ^3 L! m
    <P>    if( m_pFirstActivePlayerData == pPlayerData )! T- P/ G) W5 S8 ~: _9 b5 a
            m_pFirstActivePlayerData = pPlayerData-&gt;pNext;</P>6 ]% \& Q. p+ i6 z( U4 W
    <P>    // Add it to the free list* |, k6 u0 z; h: S
        if( m_pFirstFreePlayerData ). N  j8 a# @* @2 D* t
            m_pFirstFreePlayerData-&gt;pPrevious = pPlayerData;2 B9 w  \# W# Q/ T
        pPlayerData-&gt;pNext = m_pFirstFreePlayerData;
    4 G. Y8 D! q' {2 [6 d% t7 J    pPlayerData-&gt;pPrevious = NULL;
    ! w! N/ S. X3 E" _7 r% z3 p* ?3 B    m_pFirstFreePlayerData = pPlayerData;</P>1 P6 c" s% N4 }" t
    <P>    // Update count of players; ?& h! Y/ t* z$ I
        m_dwActivePlayerDataCount--;</P>
    2 B9 P8 Y, U4 J: ^1 R3 q<P>    UnlockPlayerData( pPlayerData );/ O! M/ h9 q( d1 A* x1 h
        m_PlayerDataListLock.Leave();: c# r1 y9 J6 q/ E4 p
    }</P>
    & ~" Y8 G/ d. N" k2 s- k3 H$ m* Z! g
    <P>$ _  V  q  s/ |' k" q# g
    //-----------------------------------------------------------------------------
    : Q; N6 e+ M8 C% y1 G/ Z1 J! b// Name: 0 i% g" g  S. O  O0 u
    // Desc:
    ( N8 ~/ u0 d" Q7 {8 `# A//-----------------------------------------------------------------------------
    / A. P, E, h: |, a+ [! R3 Rvoid CMazeServer::RemovePlayerDataFromCell( PlayerData* pPlayerData )
    / E$ n0 h! O" `$ _{
    8 p5 r6 k9 q- A$ B    // Lock the player2 b. }8 m9 c/ M
        LockPlayerData( pPlayerData );</P>
    - f1 d; M" \# W8 e<P>    // Lock the cell the player is in
    % J7 e3 [- W7 g0 M7 `& ?* P; r    ServerCell* pCell;8 B; T. L% h1 Q% k$ g8 Z  ?
        if( pPlayerData-&gt;wCellX == 0xffff )
    # M) J  Z$ d+ ^0 [    {
    0 D" s' L0 P* X( P& Z3 f        m_OffMapLock.Enter();! @! I" ]* l$ t3 \" c& ~; Y8 y$ Q
            pCell = &amp;m_OffMapCell;
    $ B5 D8 f' O8 A' m; K8 z    }
    $ l3 N1 G) A5 O9 F$ D    else0 j9 h, u  _( |' J3 T2 a
        {- a# }' a# W# k. D1 e: `8 C4 W
            LockCell( pPlayerData-&gt;wCellX, pPlayerData-&gt;wCellY );/ [/ v) V% B6 E2 g. ^. w: \' K  ^% J
            pCell = &amp;m_Cells[pPlayerData-&gt;wCellY][pPlayerData-&gt;wCellX];
    ! C( f1 N* V; I# }2 L5 J    }</P>
    1 F/ w* x) ?- w$ j, r7 O+ C# G. ?<P>    // Remove it from the cell
    1 {: U  `" `3 x    PlayerData* pPt = pCell-&gt;pFirstPlayerData;8 Z/ S1 \  p0 l# \, I& H( t
        PlayerData* pPrev = NULL;6 f" X8 c( i" v: c% a' |  Z# C  r
        while ( pPt )
    - }# E/ [; w) ?7 \    {
    & e& o6 e$ ]; u% E        if( pPt == pPlayerData )  U8 e8 Y, o5 Z& a; ~. b
            {
    / [6 t+ d" E  S7 _7 i( E0 b; X            if( pPrev )
    ) J6 T! @9 B' k- @                pPrev-&gt;pNextInCell = pPlayerData-&gt;pNextInCell;
    0 T6 r* }0 U4 [            else
    / [! [1 c3 i+ F' n1 \- }3 t/ ~5 T                pCell-&gt;pFirstPlayerData = pPlayerData-&gt;pNextInCell;</P>
    ( ?0 H! E" m1 N3 E<P>            pPlayerData-&gt;pNextInCell = NULL;
    8 ~  n# B1 i1 ^8 N+ A) P3 J. w& t            break;4 [- Z9 A) h4 \+ }4 {8 O; R
            }5 E3 k: V& ]$ S' u) }, w5 |
            pPrev = pPt;5 }! \8 m+ F3 V# R; I9 l7 p5 a
            pPt = pPt-&gt;pNextInCell;. T4 u+ Z0 F% K2 G
        }</P>) f8 z; {, f4 {4 N6 T
    <P>    // Unlock the cell, y  ~) E8 T1 Y  N- v  y
        if( pPlayerData-&gt;wCellX == 0xffff )
    ' I0 V! ?6 E. j8 f        m_OffMapLock.Leave();
    $ e: i9 m. _# k* \& P; l0 x    else3 G8 [% c8 S/ h. n
            UnlockCell( pPlayerData-&gt;wCellX, pPlayerData-&gt;wCellY );</P>
    3 [2 x1 ~* |% h5 v; b7 Y<P>    // Unlock the player
      J7 P. ~. ?! N. u! k# Y1 Z6 z    UnlockPlayerData( pPlayerData );
    " j. Y# p( e, Y+ `! @% q}</P>, S: }4 n  D1 L% }4 }. _3 [% O9 C
    # H! ]; Z. ?8 h( N8 {8 L
    <P>
    ' l/ E6 B4 \4 e//-----------------------------------------------------------------------------
    5 x2 \5 C. S, e3 k// Name:
    ; `0 d! O" j/ L1 y// Desc: ' |- D6 Y, n8 r; W7 {% {2 z- P
    //-----------------------------------------------------------------------------
    ) m+ E! m1 _) ?! i' }# M- P0 Tvoid CMazeServer::UnsafeRemovePlayerDataFromCell( PlayerData* pPlayerData )) X' q8 I& ?6 @2 B  B0 f5 s& r3 C
    {9 b) I; e6 ]3 e9 q) s
        ServerCell* pCell = GetCell( pPlayerData );
    $ O7 U5 ]& [: z    PlayerData* pPt  = pCell-&gt;pFirstPlayerData;
    ' j2 s, H5 {1 X5 N1 w- [% B% s    PlayerData* pPrev = NULL;9 x; ]- R' }! A0 K2 }1 r( Y
        while ( pPt ). z: m- y1 m% a
        {" w8 O! R1 O" L$ s# ]  K
            if( pPt == pPlayerData )) L: j  W0 R4 }( x- N( g" B1 e
            {
    1 ^  x9 l' Y) C2 s% d5 M            if( pPrev )9 h/ ~) M9 b- Q+ N
                    pPrev-&gt;pNextInCell = pPlayerData-&gt;pNextInCell;
    ! u8 i" h# z6 I1 C- e# ~6 w( J/ d            else
    / v1 m( x: j2 E  a                pCell-&gt;pFirstPlayerData = pPlayerData-&gt;pNextInCell;
    3 p) [/ h4 e. m2 K            pPlayerData-&gt;pNextInCell = NULL;" v* P3 b0 @. P8 L  H0 L# {# h
                break;$ c7 B) O+ y6 a% t  Z; h
            }9 w* M8 T! j0 A, T
            pPrev = pPt;
    ! e/ E- q1 H/ Y  j1 p        pPt = pPt-&gt;pNextInCell;
    , U2 f3 N( e* j    }% r$ g% h: ]/ Q3 N8 }: q
    }</P>
    ' X) W% X8 ]' F7 k
    0 t1 g, o( k: h0 i<P>
    ' ~. ~9 |  U+ B: o9 S0 d0 |/ U//-----------------------------------------------------------------------------+ C. G: ]* K. @4 h
    // Name:
    " {' _- a5 e2 _* ?- ^# D// Desc:
    + a- Y- s) H/ Y6 Q//-----------------------------------------------------------------------------3 W% i5 L" r) l8 ~- _! `8 e% ^4 |
    void CMazeServer::UnsafeAddPlayerDataToCell( PlayerData* pPlayerData )6 \, A; v4 Q( g7 A
    {! t/ a0 M# C6 |6 ?- k
        ServerCell* pCell   = GetCell( pPlayerData );) v/ B5 [0 G9 {5 p, x
        pPlayerData-&gt;pNextInCell = pCell-&gt;pFirstPlayerData;
    % u  k- W. X$ E( L' s5 g" ~    pCell-&gt;pFirstPlayerData = pPlayerData;
    / @2 a6 ]: W8 u& o1 {$ F- J}</P>- N. C& p: }, B2 {! V- x

    % D/ \" L/ H  w' P<P>
    . F* x) h( `( }  U* Q- a//-----------------------------------------------------------------------------& S( w& y  b% u3 D# {5 n
    // Name:
    + ~( x; g( ^& |. Z$ b// Desc: 4 j; _6 z- Y& A% L- C
    //-----------------------------------------------------------------------------( ]3 [% H  [* m: _$ B6 m2 w' M2 X4 g
    void CMazeServer::HandleClientPosPacket( DWORD dwFrom, ClientPosPacket* pClientPosPack )& {4 }' L$ L* @1 k5 y% Y% K/ e
    {5 H+ T9 a- H- ~' Z' l$ p9 j! w
        // Grab player for this client and lock it
    0 k+ z/ J3 z, V/ |/ O6 Q# P    PlayerData* pFromPlayer = GetPlayerDataForID( dwFrom );4 Z: K# ^8 J" F% e
        if( pFromPlayer == NULL )3 E4 E* i7 I3 o8 i
        {6 M- z8 i5 D. W+ R: H9 n2 m
            if( m_dwLogLevel &gt; 1 )" H4 q4 U: N8 ~3 P! z% D/ `/ i
                ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Could not find data structure for this player"), pFromPlayer-&gt;NetID );4 R4 _, B7 G3 k! `  A0 u( f: t* @
            return;% ?8 s. F# n9 T
        }</P>
    : S# n, T* u. u" ?<P>    LockPlayerData( pFromPlayer );</P>
    ) B* h$ n: S3 t<P>    if( FALSE == pFromPlayer-&gt;bAllow )
    + Y9 l1 p' B# w7 }& n- x4 b2 W& _    {; N: b1 p: K; I0 O6 L9 B
            if( m_dwLogLevel &gt; 0 )
    : G  c: y  z- f+ Q8 ]0 v            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Got position packet from bad client.  Rejecting client"), pFromPlayer-&gt;NetID );</P>$ k: I5 g1 x3 F+ W) D+ x4 h
    <P>        m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );8 i9 a& u- a( Z
            UnlockPlayerData( pFromPlayer );* S" v6 R' c5 O! v8 l9 Y
            return;
    ' F  n( x% g# i" d    }</P>! |  ?* [$ U: P% k% Y; J) I
    <P>    // Compute the cell the player should be in now
    ( F6 H1 i6 w* y* a& `    DWORD newcellx = int(pClientPosPack-&gt;fX);+ M: F. u8 \/ a& {% o
        DWORD newcelly = int(pClientPosPack-&gt;fY);  G( h) X- X$ ]7 s, B+ Z
        DWORD oldcellx = pFromPlayer-&gt;wCellX;2 O% Z* J% Z$ M/ [
        DWORD oldcelly = pFromPlayer-&gt;wCellY;</P>
    , d+ N0 i$ M$ a3 m<P>    // Have we moved cell?, E9 D; l  |5 `# Y# ]/ o% S) L8 v
        if( newcellx != oldcellx || newcelly != oldcelly )
    & B3 L& \0 w$ I; J0 R    {7 o' Y8 x$ x8 m$ T% p( d
            // Yes, so lock the pair of cells in question
    ! ?2 @2 e+ b9 M        LockCellPair( oldcellx, oldcelly, newcellx, newcelly );</P>
    8 I( l3 Y/ X7 @2 ?# }5 y: ]& q<P>        // Remove from old cell and add to new cell7 B# ?, K& ^5 a8 y% q7 o
            UnsafeRemovePlayerDataFromCell( pFromPlayer );
    2 ?. P% A0 h# P$ @$ Y: Z4 O        pFromPlayer-&gt;wCellX = WORD(newcellx); pFromPlayer-&gt;wCellY = WORD(newcelly);
    , h2 R- J6 M% {) P& C. [        UnsafeAddPlayerDataToCell( pFromPlayer );</P>* c' t9 I- U: F1 t  D! z! Q4 f
    <P>        // Unlock cells% R# u4 g0 h, F6 ~
            UnlockCellPair( oldcellx, oldcelly, newcellx, newcelly );& c2 E4 z. m4 g" Y/ X' u
        }</P>$ w/ Z  U9 F& P8 Z1 H
    <P>    // Update player position
    5 h% K! S8 g5 {' b: Y    pFromPlayer-&gt;fPosX      = pClientPosPack-&gt;fX;6 [$ t9 d/ {6 k2 E" p' _4 N+ H
        pFromPlayer-&gt;fPosY      = pClientPosPack-&gt;fY;$ k! }7 w- N$ c1 B
        pFromPlayer-&gt;aCameraYaw = pClientPosPack-&gt;aCameraYaw;</P>; t/ a1 M; w3 w" R7 G  f: N
    <P>    // Allocate space to build the reply packet, and fill in header
    ) d' E6 d; Z6 M" c    DWORD dwAllocSize;, T8 d" k9 Y3 q* E' V
        ServerAckPacket* pSvrAckPack = NULL;</P>
    4 N. M! Q. Q, K4 K<P>    // Begin by allocating a buffer sized according to( b- @. n2 r) f3 v8 g/ S
        // the current number of nearby players + 4.  This will give
    . p, E/ B8 J- A: n    // a little room for more players to come 'near' without resize
    + t) _$ y1 A3 h    // the buffer.3 Y3 Z1 `/ k7 z0 |1 _2 ~$ Z! w
        DWORD dwMaxPlayerStatePackets = pFromPlayer-&gt;dwNumNearbyPlayers + 4;</P>' @/ e3 J& N% U# d5 _' S
    <P>    dwAllocSize = sizeof(ServerAckPacket) + dwMaxPlayerStatePackets*sizeof(PlayerStatePacket);
    6 a1 ]6 ]# j0 C: K8 h4 P    pSvrAckPack = (ServerAckPacket*) realloc( pSvrAckPack, dwAllocSize );
    4 c4 w- O: h0 Q, C! W4 i    if( NULL == pSvrAckPack )
    + w$ t' H& W* _9 O2 B' u) Y    {
    2 H. V) Z- E8 _, B: [        // Out of mem.  Cleanup and return5 t/ d6 P$ R0 a2 y8 e" O
            UnlockPlayerData( pFromPlayer );
    9 ]+ P$ ~* k6 N& o9 X( G" [        return;      
    ! E0 }! G. v2 _. @* y0 ]1 a    }
    ! n5 ~$ W$ S2 J- d! u    ZeroMemory( pSvrAckPack, dwAllocSize );</P>, K) B( z/ I, U0 F' P* Y
    <P>    *pSvrAckPack = ServerAckPacket(m_dwPlayerCount);  l* X5 D% e- g6 M0 c
        pSvrAckPack-&gt;wPlayerStatePacketCount = 0;5 {* O6 o5 K0 M9 F' Q
        PlayerStatePacket* pChunk = (PlayerStatePacket*)(pSvrAckPack+1);</P>$ c9 @; P& S3 L! i
    <P>    // Compute range of cells we're going to scan for players to send
      Q' f. W  z# V' ^    DWORD minx = (newcellx &gt; 7) ? (newcellx - 7) : 0;- m) Q5 j. D, K
        DWORD miny = (newcelly &gt; 7) ? (newcelly - 7) : 0;
    , V8 y* z7 O/ Z* H+ H) T% P    DWORD maxx = (newcellx+7 &gt;= m_dwWidth) ? m_dwWidth-1 : newcellx+7;
    ' D) b2 A4 N" D3 y% N1 w    DWORD maxy = (newcelly+7 &gt;= m_dwHeight) ? m_dwHeight-1 : newcelly+7;</P>' v" l+ w+ ^- M( n5 d( R
    <P>    // Lock that range of cells* K5 l6 G7 e! `; C2 ?$ n4 [
        LockRange( minx, miny, maxx, maxy );</P>
    . J2 q5 E+ b$ Y! @+ j; B, d7 {% ~<P>    // Scan through the cells, tagging player data onto the end of- @# i8 _4 o7 ]6 Q8 r( s' J1 l
        // our pSvrAckPacket until we run out of room
    % L- H7 g& f/ o. y5 G  y! j    for( DWORD y = miny; y &lt;= maxy; y++ )% S: [2 z( m* {  O/ n* G
        {
    - Y1 S$ B, S5 N' s$ {! H8 Y: I; j        for( DWORD x = minx; x &lt;= maxx; x++ )) b8 z8 u2 C6 n- D( K
            {
    4 v6 [5 `2 G/ ?" U( j            PlayerData* pCurPlayerData = m_Cells[y][x].pFirstPlayerData;& _- k7 |  E! A
                while ( pCurPlayerData ). |" [5 T& n% D$ f, p/ G
                {
    ' x5 z* f$ s5 U6 I" b) g                if( pCurPlayerData != pFromPlayer )
    , S- x" A' b2 L9 F5 w: g                {3 H  {1 y/ H$ l
                        if( pSvrAckPack-&gt;wPlayerStatePacketCount &gt;= dwMaxPlayerStatePackets )
    , q* C4 [! Q% x                    {# W( F; ^+ V) b4 f! X# B
                            // Make sure pChunk is where we think it is
    : C+ B3 \- Y6 V                        assert( (BYTE*) pChunk == (BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket)) );</P>
    ( f5 o) d. H) L. m<P>                        // There are more than just 4 new nearby players, so resize the
    : E; \/ X& r. B  O                        // buffer pSvrAckPack to allow 16 more PlayerStatePacket's.0 m. d$ ^1 s1 u2 q8 g$ \
                            dwMaxPlayerStatePackets += 16;' y4 a- H# }/ X7 u
                            dwAllocSize = sizeof(ServerAckPacket) + dwMaxPlayerStatePackets*sizeof(PlayerStatePacket);/ P4 `4 f6 H. C, x; ?
                            ServerAckPacket* pNewSvrAckPack = NULL;$ M' W. c- @! T6 F; O& `; {/ p
                            pNewSvrAckPack = (ServerAckPacket*) realloc( pSvrAckPack, dwAllocSize );
    5 i! V  m1 K! R; e                        if( NULL == pNewSvrAckPack )
    % D, {" b  \6 t, d2 S; S, T                        {
      o9 k. U6 x9 u                            // Out of mem.  Cleanup and return
    0 A2 a* ^/ Z: ]/ ]/ O                            free( pSvrAckPack );1 C+ F( P: q7 w9 S- z% w
                                UnlockRange( minx, miny, maxx, maxy );
    $ P: g6 z% K' s! H( {9 s                            UnlockPlayerData( pFromPlayer );
    1 U: \7 y; e+ h" W' p2 ]                            return;      
    $ F% c* Y" i6 J0 X. ]- u                        }</P>
    5 X: y, {+ a" [1 a<P>                        pSvrAckPack = pNewSvrAckPack;
    & o/ z3 G) ]5 E7 h. @+ C6 y                        pChunk = (PlayerStatePacket*) ((BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket) ) );</P>2 \$ [1 g9 v. h: M" R; s! |3 c' `
    <P>                        // Make sure pChunk is still where its supposed to be
    . l1 T& b" q! s. Z$ O# U                        assert( (BYTE*) pChunk == (BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket)) );
    - P$ s" P7 Y  |  ~+ ]                    }</P>
    1 c" V" C1 W8 A2 i<P>                    pChunk-&gt;dwID       = pCurPlayerData-&gt;dwID;6 ~  l, T$ [8 U# T: ~& f$ I
                        pChunk-&gt;fX         = pCurPlayerData-&gt;fPosX;
    ! H7 ?: B+ C7 C+ J- x# i. h                    pChunk-&gt;fY         = pCurPlayerData-&gt;fPosY;! c$ f6 z$ C! D2 M2 I) Z& X
                        pChunk-&gt;aCameraYaw = pCurPlayerData-&gt;aCameraYaw;
    $ T9 `8 w5 T( ^8 F* s' z7 }" V                    pChunk++;# z6 q4 f  n+ A! y1 t; P; J
                        pSvrAckPack-&gt;wPlayerStatePacketCount++;9 ~3 b& y! J  X$ D/ H4 D' O- j
                    }1 \1 m6 K" K8 A) c* @5 n
                    pCurPlayerData = pCurPlayerData-&gt;pNextInCell;
    & w8 b' j- ^, r# N: a            }2 [8 z& Z: H' {; r9 G5 [: o+ m# c; a
            }) J7 i5 b. ~2 x3 n& n; q
        }</P>
    2 v7 h! W( h2 X+ N6 Y. R<P>    // Update the dwNumNearbyPlayers for this player
    / o" r" t5 L6 x! U! c' s# w    pFromPlayer-&gt;dwNumNearbyPlayers = pSvrAckPack-&gt;wPlayerStatePacketCount;</P>! g" c3 u8 U, s
    <P>    // Unlock range of cells: m7 k8 g! h- J0 [. h+ M
        UnlockRange( minx, miny, maxx, maxy );</P>
    # m# ^3 _, }8 i<P>    if( m_dwLogLevel &gt; 2 )
    4 T. L$ A  J& Y# K4 z  X    {9 q  M4 t- A3 J& ^
            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Position is (%0.2f,%0.2f)"), pFromPlayer-&gt;NetID, pFromPlayer-&gt;fPosX, pFromPlayer-&gt;fPosY );: A. ]  ~% H0 j6 W  A  `0 p
        }# L7 k8 O5 S2 |# R7 \, [' r/ s
        else if( m_dwLogLevel == 2 )
    4 v' o4 ^* b4 f$ D# J  L/ Q+ O    {
      q5 X- H% i& j' b( H* H* j+ H& e        FLOAT fTime = DXUtil_Timer( TIMER_GETAPPTIME );
      [/ ~: F0 |+ j( r5 S& F        if( fTime - pFromPlayer-&gt;fLastDisplayTime &gt; 60.0f )
    + _0 \$ J% N5 M/ c! [9 E& U0 Q        {% j% r8 W' T& c( Z. Z8 t5 q
                ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Position is (%0.2f,%0.2f)"), pFromPlayer-&gt;NetID, pFromPlayer-&gt;fPosX, pFromPlayer-&gt;fPosY );3 v6 v! ~8 [* U  [+ x
                pFromPlayer-&gt;fLastDisplayTime = fTime;/ z  g2 M4 ^- O5 M
            }3 Y0 k# n; \0 e/ k% C
        }</P>2 t) Y( R( X& F
    <P>    // Unlock the playerdata5 a/ o& W" G6 ~3 s
        UnlockPlayerData( pFromPlayer );</P>
    2 @4 N5 d; z) A! a0 J<P>    // Send acknowledgement back to client, including list of nearby players ) t# y) p0 D5 ~! X
        DWORD acksize = sizeof(ServerAckPacket) + (pSvrAckPack-&gt;wPlayerStatePacketCount * sizeof(PlayerStatePacket));
    : `+ F# j. P% M! f* I: E/ v + h) v# e7 {6 w) Y' d
        // Pack the buffer with dummy data.
    $ m' X1 X8 e+ x2 M" u; U) @: g    if(m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex] &gt; 0); {$ j. A5 k7 c9 [
        {
    ; s9 B$ E, j/ G4 w: P        DWORD   dwBufferSize = acksize + m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex];9 e3 ?4 g( g! d
            VOID*   pTempBuffer = 0;</P>
    8 T0 o. L9 e- L! T% u7 Q<P>        pTempBuffer = malloc(dwBufferSize);: ?# n2 P7 f6 e$ m9 G
            if( NULL == pTempBuffer )
    ' }3 c6 Z4 Y0 g; [        {
    % k( h8 A2 B0 Z0 t7 A& w' r            //Out of memory* r$ e- X8 J% G: |) V3 ~1 j
                DXTRACE_ERR_NOMSGBOX( TEXT("System out of Memory!"), E_OUTOFMEMORY );" P5 e9 U% w) |0 l/ K" C
                free( pSvrAckPack );
    3 t# s5 t3 L' a" A+ k7 L            return;: C5 {# _8 i. M. L" g
            }</P># d% b( X" g* x6 P* c. ?
    <P>        FillMemory(pTempBuffer, dwBufferSize, 'Z');
    & H5 q: b6 x8 s. Y' _5 n        memcpy(pTempBuffer, pSvrAckPack, acksize);</P>& a  k. \; i1 P; L
    <P>        SendPacket( dwFrom, pTempBuffer, dwBufferSize, FALSE, m_dwServerTimeout );
    ( m4 C# M; M3 s  R   
    * i; H! Z# v. ~        free(pTempBuffer);
    ) z$ i5 {  ]' Y2 j# @$ y    }   
    ! X# i* J) C. R2 |    else
    ! A6 I" d8 F- G; ?* y0 D/ J    {
    ! u, @% D0 w, i1 F- j# X        SendPacket( dwFrom, pSvrAckPack, acksize, FALSE, m_dwServerTimeout );# l# [3 ?! _. f5 L; c
        }</P>. L1 X9 `( H5 z& r
    <P>    free( pSvrAckPack );</P>- {% Z( |' _* b' f; L4 S$ a
    <P>}</P>; K8 q6 L% }! n8 g  F$ t# Q% |

    # b6 U4 Q- W0 x6 ?% c" E9 w<P>% r5 z8 F1 Q( \3 b
    //-----------------------------------------------------------------------------6 }! G) D+ N8 N9 v
    // Name:
    " J, \9 l% T: q! `- a* ]// Desc: 3 q3 ]$ D; f# j  N9 @
    //-----------------------------------------------------------------------------
    2 F% R' j; p: T& F5 I  y& P2 Cvoid CMazeServer::HandleClientVersionPacket( DWORD dwFrom, ClientVersionPacket* pClientVersionPack ); w+ ]: P/ G$ |3 L
    {  X+ a! q& k1 ?* K. _
        // Grab playerdata for this client and lock it. R& ]0 H5 v3 w8 Y9 ^
        PlayerData* pPlayerData = GetPlayerDataForID( dwFrom );8 x; t; v; a4 E
        if( pPlayerData == NULL )
    , w* p* Q& s' r        return;7 }; Z5 b7 S: C: d# V7 t
        LockPlayerData( pPlayerData );</P>1 y$ y2 M# I1 S+ ?# z
    <P>    // Record the version number
    - f2 G& Y6 p  P6 D    pPlayerData-&gt;dwVersion = pClientVersionPack-&gt;dwVersion;</P>
    # I3 I8 N+ [" m<P>    if( m_bLocalLoopback )
    0 m' w" h( x5 j        pPlayerData-&gt;bAllow = TRUE;9 P) ~2 g' L3 y
        else8 c3 ~; n0 X  F) G
            pPlayerData-&gt;bAllow = IsClientVersionSupported( pClientVersionPack-&gt;dwVersion );</P>
    * z3 D/ O4 \2 T) L. q<P>    if( m_dwLogLevel &gt; 0 )
    $ O# j: Q$ o$ H  n1 {" @        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>- @# d( Y& Q9 ~9 z- C: w6 k% l
    <P>    if( FALSE == pPlayerData-&gt;bAllow )
    2 z+ X4 J  n( i. b9 U/ O. m    {
    ' j: c* S3 D, Y        if( m_dwLogLevel &gt; 0 )6 l" M$ q$ m! u
                ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Rejecting client"), pPlayerData-&gt;NetID );</P>
    * x2 ]- }# Q1 y* U9 _! t<P>        m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );8 E- |5 ~' }2 R8 n
            UnlockPlayerData( pPlayerData );
    ; `  k6 |. }: c! N        return;
    8 H, ]  ]2 O, w, {( a5 w    }</P>- l" }; P7 B  r2 f# O
    <P>    // Unlock the playerdata
    ) s! \! P5 E+ c3 d# t( q; q    UnlockPlayerData( pPlayerData );</P>
    ) Y( l2 j- d6 Y. k" A1 J<P>    // Send acknowledgement to client that the client was either accepted or rejected
    : R, n/ M& a" B/ ^3 V# P/ P    ServerAckVersionPacket packet( pPlayerData-&gt;bAllow, dwFrom );4 a2 u8 Y6 R0 l
        SendPacket( dwFrom, &amp;packet, sizeof(packet), TRUE, 0 );
    5 C+ }! a) x9 k/ ]! ~* C}</P>
    ! p6 n2 J. q- k" m
    7 G- J9 d5 t5 l0 u+ I1 q<P>1 c& ?/ T" U  G. [2 C8 B# t3 o2 T
    //-----------------------------------------------------------------------------8 p: I& S% v$ }- o( r' x% D
    // Name:
    0 d( W7 F6 ], n9 O* K0 p- t! o// Desc:
    ) f7 g$ o6 C! e//-----------------------------------------------------------------------------
    " e4 p7 J7 C  o  w- W! ]5 `BOOL CMazeServer::IsClientVersionSupported( DWORD dwClientVersion )$ Y9 p" W5 L1 k% B
    {& u2 e( I' W$ e% e, \( L
        switch( dwClientVersion )
    ( D* S$ ]. l& O( B5 s    {
    & y' o! t, p2 `8 D        case 107: // only v107 is supported
    $ n, c% @( e2 p% ~" I% f" R            return TRUE;0 m# t' N' O6 j, d" U
            default:0 ?2 M' y, _3 E. d8 C
                return FALSE;& Y- D2 Z1 R# N' U0 y3 P- g' ]' S
        }2 |3 i3 v7 V8 ]" o
    }</P>
    4 @( z* B2 g0 t9 j# k/ ?! E8 l+ o" \, E, y& T0 B
    <P>. Y. M5 v( [" T, m8 b# h
    //-----------------------------------------------------------------------------
    , I& P- ?# X8 P& d2 X// Name:
    5 y7 O- F; H. ^: N! E$ }. A9 X// Desc:
    & Q& K. J6 m" O. ]" n//-----------------------------------------------------------------------------
    1 o4 O3 N3 b- i/ Bvoid CMazeServer::HandleUnknownPacket( DWORD dwFrom, ClientPacket* pClientPack, DWORD size )+ S9 B- ^) i# ~7 w* }' L  X4 H
    {
    : h) E! y5 s/ b* b    if( m_dwLogLevel &gt; 1 )
    3 L! S6 g7 x, }- O$ {. F! d        ConsolePrintf( SLINE_LOG, TEXT("ERROR! Unknown %d byte packet from player %0.8x"), size, dwFrom );</P>$ p0 z6 Q% W' ]* `/ J9 t
    <P>    m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );8 x- ]  G8 ]2 D5 ~1 |( ]
    }</P>
    5 X# ]9 G, e9 V# W' L4 k+ Z9 k2 s! f* |1 H+ n& ?" B+ B4 v  R
    <P>
    . K& w' A4 Z7 a" C8 ^, w- Z  ^//-----------------------------------------------------------------------------
    . z# C' I1 ]: l// Name: 5 J) V4 h: @  f" t2 m7 i1 K6 ]5 X
    // Desc:
    9 U  p, |/ m" a//-----------------------------------------------------------------------------
    % H' a1 t: G! ODWORD   CMazeServer::IDHash( DWORD id )
    1 ~( n# @/ E( a{
    + h/ x- A) t1 K    DWORD   hash = ((id) + (id&gt;&gt;8) + (id&gt;&gt;16) + (id&gt;&gt;24)) &amp; (NUM_ID_HASH_BUCKETS-1);
    ; r8 }% u$ f" [3 t    return hash;5 V" K% \7 o8 O, `
    }</P>+ y4 V2 q  E( v( T1 D  z

    ( i6 t0 E7 }7 U& ^# E7 `<P>
    , c* f- }+ u0 S- ^. a: o//-----------------------------------------------------------------------------0 |4 k" _- Z! x, P9 Z
    // Name:
    ( ]+ O3 n4 n! H2 a+ Y// Desc:
    % m6 b% J+ H" i+ J5 H//-----------------------------------------------------------------------------* R9 F! J6 v% E" u7 u* P
    void CMazeServer::RemovePlayerDataID( PlayerData* pPlayerData )0 `3 o4 n7 k, M6 t
    {
    2 R+ l7 K: f4 h& U) j9 O    // Hash the ID to a bucket number
    4 K, C6 Z: j2 Q  l( v- f; I6 C: W: C    DWORD   bucket = IDHash( pPlayerData-&gt;NetID );</P>
    7 F  j) }( d5 O! c7 _# j% J9 c<P>    // Lock that hash bucket7 v1 |( s+ D8 u. v. v6 z' d" I
        const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;. ]! m8 N( P; W
        m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>& I( H3 O+ y) c' W
    <P>    // Loop though players in bucket until we find the right one# ^; I; I3 m& W- X; z) o& q
        PlayerData* pPt = m_pstIDHashBucket[bucket];/ ]* J) K1 a: z5 E
        PlayerData* pPrev = NULL;
    ) j0 n. ^% [* S) F    while( pPt )
    7 H! G! `8 L" R, a$ ^' A0 k    {' z( D- v: G: S. y! W
            if( pPt == pPlayerData )* J3 ?! ]7 D1 S3 N0 {
                break;% Y& X; x+ Y* ?7 ^+ J! u
            pPrev = pPt;( \& W7 J; G0 _7 k, H
            pPt = pPt-&gt;pNextInIDHashBucket;
    % z2 X0 f/ Q" u" R, V1 v7 L% Y    }</P>
    * g& j+ c5 `+ X2 h* A+ h<P>    if( pPt )+ l# _: J# g% x6 ]6 \7 m4 a
        {' H9 b1 Q6 z* M/ p9 P
            if( pPrev )
    - u* y8 u7 ~- J# o: f+ y( S$ M            pPrev-&gt;pNextInIDHashBucket = pPt-&gt;pNextInIDHashBucket;
    # q- F* e8 ~* I- }4 m- @' x) N        else# N% e+ h. }6 N
                m_pstIDHashBucket[bucket] = pPt-&gt;pNextInIDHashBucket;; \. ?# V! F+ [4 H3 k* G8 I3 F
            pPt-&gt;pNextInIDHashBucket = NULL;
    ; X; F% |; ?' ~. j  T: g' q    }</P>
    % O0 a, F/ m7 [( d2 J<P>    // Unlock the hash bucket
    2 _# i/ b9 n" X3 s9 ~    m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();
    3 F, Q+ n, r9 [' I( t2 Y}</P>
    6 }5 U5 N+ ?" g! A3 L, A% R# a2 N# D6 I! ~4 ?! I. k
    <P>) F0 {, l8 |& Q+ w. }9 t% L9 I0 Z
    //-----------------------------------------------------------------------------8 X4 B% s$ U/ k( j2 e  E3 u3 ~6 [
    // Name: % b' H; F1 r, E
    // Desc:
    & ]* k4 U/ s) G) g( G0 [( j$ M//-----------------------------------------------------------------------------
    7 _7 `: |: U% S9 ~void CMazeServer::SetPlayerDataForID( DWORD id, PlayerData* pPlayerData )) M+ G2 N/ [& R- {
    {
    4 F7 x1 ~7 K8 n3 m6 x    // Make sure this player isn't added twice to the m_pstIDHashBucket[]
    & h) A% w3 W/ F3 ^( @* y* o. J2 Y    // otherwise there will be a circular reference
    4 c! Q! w) z: D- y, c    PlayerData* pSearch = GetPlayerDataForID( id );
    7 A- Y6 H4 w' S1 S    if( pSearch != NULL )
    ' p, u) M0 b, {2 ~$ e3 X        return;</P>
    * a; q# [9 A" s, E6 ~<P>    // Hash the ID to a bucket number( `& j. J( n/ v- z  K% M) l7 l
        DWORD   bucket = IDHash( id );</P>( R. v" i5 i$ V, d
    <P>    // Lock that hash bucket" S* e/ R  `4 b6 V0 Y
        const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;
    / J' M2 B) t. I  ^. T1 b# ?1 f    m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>; y! N$ M+ G, X+ ?: d
    <P>    // Add player onto hash bucket chain
    ( t5 O; p" n+ j6 _# V    pPlayerData-&gt;pNextInIDHashBucket = m_pstIDHashBucket[bucket];
    # _. n5 b8 t$ E, X' M2 L    m_pstIDHashBucket[bucket] = pPlayerData;</P>
    4 I! T/ Q; s  p/ D2 p7 {& Z8 O<P>    // Store net id in player
    0 W  ]. W3 t( w% f6 j: @, ^0 j    pPlayerData-&gt;NetID = id;</P>
    / r) ~' P' Z4 q& @  ~<P>    // Unlock the hash bucket
    ; _* v2 u3 f$ U' L' F3 w    m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();) A4 U6 L. T, p' l3 W' L4 _8 t
    }</P>) }$ O; w" b9 P( }9 S: F! o

    ( m+ f& P  `$ Y+ {<P>
    ! f& \! i7 W# R$ ?. q7 j9 Q9 O+ j& A. p//-----------------------------------------------------------------------------+ l5 @) }+ {3 W5 `* t9 `1 m& o& k
    // Name: 4 r. T; l9 J  F6 x0 N1 x
    // Desc: 5 ]* {, ]& [- n1 U9 H- P
    //-----------------------------------------------------------------------------
      @' g9 C/ ~+ x6 }PlayerData* CMazeServer::GetPlayerDataForID( DWORD id )" b* H' C/ O5 ], Z
    {
    , ~+ D, J" n- E) E0 E    // Hash the ID to a bucket number/ i' d" H. h0 L9 s/ Z' C
        DWORD   bucket = IDHash( id );</P>2 P1 x4 F1 ^$ T! E
    <P>    // Lock that hash bucket
    ' ~& P/ P) m  z9 W+ `# z    const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;( n( w1 x) A* S( G1 X( P# U
        m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>
    6 [+ ^# _6 @9 F9 W+ Y<P>    // Loop though players in bucket until we find the right one  v" b2 g0 u: T1 ~
        PlayerData* pPlayerData = m_pstIDHashBucket[bucket];
    ; V2 e0 P, l" y2 c    while ( pPlayerData )7 M$ ~0 o( r& l. d
        {
    * x+ Y* f7 P" k( o0 L  Q7 D        if( pPlayerData-&gt;NetID == id )
    ' v8 ~: i# ?2 I0 v! \# O: G- L            break;% _8 _3 L1 @/ v6 N* t
            pPlayerData = pPlayerData-&gt;pNextInIDHashBucket;
    5 p9 a0 }: U% ?3 n0 a    }</P>9 s" b  j- l% E# _
    <P>    // Unlock the hash bucket/ q% K) W8 D; i1 {; \6 Y0 ^# v
        m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();</P>' O5 P- A9 }1 M3 P, o
    <P>    // Return the player we found (will be NULL if we couldn't find it)
      C8 ]% r# Y6 R# f1 o5 ~    return pPlayerData;# @) P  x6 e+ ?& o0 Q$ h' i
    }</P>% Q+ K( N8 v) Y' P) O4 a- K- `* Y& `

    6 Q8 s0 ?" k8 \' a: L- S( _( F! U<P># v; X# [6 V! a5 @; x& M2 m+ O
    //-----------------------------------------------------------------------------% P2 r0 H& f* |+ T, q
    // Name:
    " h& X( N9 M: N' E: o// Desc: calls DisplayConnectionInfo for each connection in a round-robin manner
    & f2 p7 A$ m6 }& \7 u: x# b//-----------------------------------------------------------------------------: A6 t& O/ ?1 G8 d0 o
    void CMazeServer:isplayNextConnectionInfo()
    9 i/ |8 W2 M0 [  w; V! t{1 r9 R/ p" `) ~  z- \% `
        if( m_pNet ): v' Y, B; r3 m8 n' N) }5 X, a
        {
    : Z/ s- d* \: p        // Find the player that was displayed the longest time ago, and display it.
    1 M, T1 v& a" ^        FLOAT fCurTime = DXUtil_Timer( TIMER_GETAPPTIME );: N( \: F2 `; `2 F. k- J2 F3 v
            PlayerData* pOldestPlayerData = NULL;
    : [, W7 p( D0 ^- D1 U4 H        FLOAT fOldestTime = 0.0f;</P>
    ) z* Z% ]% l2 n) |0 r<P>        m_PlayerDataListLock.Enter();</P>
    ) n  E4 Z/ E" @& m5 K- ~" a; m<P>        PlayerData* pPlayerData = m_pFirstActivePlayerData;
      ?' O) V, m- s" g. o        while ( pPlayerData )' R& N: r6 {7 _; I* Z3 M' X4 @$ X
            {6 g; ~4 Q0 b% G. [: t/ G9 ~
                if( fCurTime - pPlayerData-&gt;fLastCITime &gt; fOldestTime )
    1 g: U! r8 e" Z( x4 ^            {
    " I9 P* l& @2 |2 d/ }( x( v) m                fOldestTime  = fCurTime - pPlayerData-&gt;fLastCITime;% u" g8 n. B  m& h; u' b  i3 a
                    pOldestPlayerData = pPlayerData;
    # l8 ~: o# }' |4 S! f6 n, p            }</P>
    , x% n( n! P& ?2 a<P>            pPlayerData = pPlayerData-&gt;pNext;
    9 t' N. E: j& [+ h9 y6 _1 z        }</P>
    : H+ c5 e2 Y: M/ S- t: A<P>        // Display the player with the oldest CI field, and update its CI field.
    " ^* S, H4 ^/ z4 q/ o" u0 H2 K) A6 f        if( pOldestPlayerData )7 Y! ?; ^/ I% |: t4 H/ T
            {2 p' f. W; h$ w* y7 k+ P7 |
                ConsolePrintf( SLINE_LOG, TEXT("Displaying connection info for next player") );
    ( I+ _6 p1 `* x. c            DisplayConnectionInfo( pOldestPlayerData-&gt;NetID );0 i! h$ ]& e' m9 w
                pOldestPlayerData-&gt;fLastCITime = fCurTime;
    # a& e1 |# e7 m9 B7 V, o/ {# y2 ]        }
    6 F; b/ A; d0 S        else
    ) \) s. p' Y8 j, q        {
    , N( P5 V0 R4 `+ M4 s* m            ConsolePrintf( SLINE_LOG, TEXT("No players found") );# y+ m1 c5 L8 Q# M
            }</P>3 C. I& q) Y/ F0 C8 P: n
    <P>        m_PlayerDataListLock.Leave();
      C2 u$ K3 x" \    }
    " G* f8 _: q7 g. A7 M2 E* S. n}</P>
    1 g* g! l7 @/ j1 I1 y+ Y8 x1 [
    ) P7 w: u, `: R- m$ A<P>
    # Y" S# C1 _* Z2 b1 A2 B//-----------------------------------------------------------------------------+ b/ v& ?9 @% N* P
    // Name:
    * J+ Z" H$ F) v7 K) }. m// Desc: + @/ X6 ]: k: A1 D, }
    //-----------------------------------------------------------------------------
    + S4 N. M+ I) o3 {: p: p/ Kvoid CMazeServer:rintStats()' z$ o4 r7 n/ s( }+ F2 U
    {
    3 X  P( s$ H/ f; ~5 q) S- U    ConsolePrintf( SLINE_LOG, TEXT("Thread count: Active=%d Avg=%.2f Max=%d"),
    ) |% ^3 Y& ]/ W! y. F! {/ H                                    m_wActiveThreadCount, m_fAvgThreadCount, m_wMaxThreadCount );1 {9 W: E; ^. V* s% R
        ConsolePrintf( SLINE_LOG, TEXT("Thread Time: Avg=%.4f Max=%.4f(s)"),; Y/ j4 ?' g  k% X: {
                                        m_fAvgThreadTime, m_fMaxThreadTime );
    1 v# S1 W  u( r/ H! n+ @    ConsolePrintf( SLINE_LOG, TEXT("Players online (not including server player): %d"), m_dwPlayerCount );& H; q: ]  s& M# x* z2 j- s
        ConsolePrintf( SLINE_LOG, TEXT("Peak player count: %d"), m_dwPeakPlayerCount );
    . h5 d3 s7 e1 V, b* l1 T}</P>
    ' |; c& ?" i" |2 u9 n
    " L. X9 S9 {$ B5 P% m) D8 U7 l<P>
    ! i. s9 ~1 E5 T5 s/ b" n: T  Y, A9 v//-----------------------------------------------------------------------------
    5 H6 C7 X/ N5 k// Name:
    2 S2 \8 q# b( \  M2 Q// Desc:
      W; Y+ H) a  n9 a//-----------------------------------------------------------------------------
    / W  p+ o! e. A. ~void CMazeServer:isplayConnectionInfo( DWORD dwID )
    ) I4 S* f+ g/ @  k( f{9 O# t* K  e1 u/ R6 K1 [5 X" c& c
        TCHAR strInfo[5000];
    6 V& \* ~. J; \# s. O    TCHAR* strEndOfLine;
    ; C" z( O6 D" H0 Y3 E8 p; a# u, ?    TCHAR* strStartOfLine;</P>/ w, p  ^$ J6 @6 d; C, t3 G* D
    <P>    // Query the IOutboudNet for info about the connection to this user
    4 I: ^, Z! V, M  n    m_pNet-&gt;GetConnectionInfo( dwID, strInfo );</P>
    + c. X. t2 f- g  M. u! a<P>    ConsolePrintf( SLINE_LOG, TEXT("Displaying connection info for %0.8x"), dwID );& Q4 o( b! D1 N" Q- ^4 L# D4 r& c) D
        ConsolePrintf( SLINE_LOG, TEXT("(Key: G=Guaranteed NG=Non-Guaranteed B=Bytes P=Packets)") );</P>
    6 w9 J9 U3 T& m0 @# C6 x" o<P>    // Display each line seperately  n+ L% r* ^6 m6 Y1 |% o/ b; y
        strStartOfLine = strInfo;
    ) I; q' l6 l1 Q: A& a& g% T% r    while( TRUE ): d' n5 N( {* ?$ Y
        {/ }3 C5 b5 P  [$ G3 d5 e" t+ V
            strEndOfLine = _tcschr( strStartOfLine, '\n' );
    1 E% `# k  @; P: T! y- v        if( strEndOfLine == NULL )
    ) _& g2 S5 P$ H            break;</P>
    * M- j; T) M# T' H( P6 F" f<P>        *strEndOfLine = 0;
    & `1 Z, c" z2 u4 f        ConsolePrintf( SLINE_LOG, strStartOfLine );
    % Z7 r% D: K% }        strStartOfLine = strEndOfLine + 1;7 C% v8 d& p" Y: B2 x
        }" w* n) a3 b% |; z7 G, o
    }</P>. D" w6 I5 H& q0 W

    ) ~. Y3 y$ \& ?( w<P>
    . d' F( {0 g3 O8 G8 P//-----------------------------------------------------------------------------
    / |# z+ G( I: r" J$ }// Name:
    % b3 Q* N' h1 @) x// Desc:
    7 C" ?3 I' ]7 B6 O9 Z  q5 F0 Y//-----------------------------------------------------------------------------7 k! O  K1 n) s5 D. U6 T5 R2 K
    HRESULT CMazeServer::SendPacket( DWORD to, void* pData, # ^2 U  o! K* X/ B
                                     DWORD size, BOOL reliable, DWORD dwTimeout )
    ! _1 C1 z# a  M' G. Q" W{( S7 D) `  d' e6 n) e! P
        // Chance of forcing any packet to be delivered reliably
    ( \/ ~: _6 m! ^# A2 z+ d    if( m_Rand.Get( 100 ) &lt; m_dwServerReliableRate )
    0 Z! u+ `) f& G1 |9 Z% y        reliable = TRUE;</P>
    # ~0 d) X7 a2 W7 E<P>    return m_pNet-&gt;SendPacket( to, pData, size, reliable, dwTimeout );( j0 M" x  b3 G
    }</P>! `  U) u: J% q/ K: v
      i5 N. Y2 a- [+ }, `! c; N" O
    <P>
    0 l/ ^5 C$ U* f6 p7 \! _. ]2 ?//-----------------------------------------------------------------------------3 q/ f4 }: `, k( e+ n: ?
    // Name:
    1 L" F! C* t1 q. @  Y( Y( P9 T// Desc: ' @* N% F* B' X
    //-----------------------------------------------------------------------------7 y4 r3 F, |+ X- D
    void CMazeServer::SendConfigPacketToAll( ServerConfigPacket* pPacket )% x. {+ F& a: m7 V1 i  x! z
    {
    ! ]+ g9 s6 @5 U  u1 X3 f% v1 Q3 e    // If we're up and running, then send this new information to all clients
    8 b+ f0 Y) l, C6 G! M. G    if( m_pNet )
    6 k3 V- ~3 k: ]0 _    {
    , R; w1 s1 v( g1 t        //Use the AllPlayers ID4 P. N: J8 F/ E
            SendPacket( DPNID_ALL_PLAYERS_GROUP, pPacket, sizeof(ServerConfigPacket), TRUE, 0 );( i! l; E2 l" d
        }
    ) J$ P0 I% R3 o}</P>; b4 T; e- I' Y' u- m

    8 A" Q6 g" ?6 @8 `/ E( ~<P>
    ; c' R5 D: u% z9 O//-----------------------------------------------------------------------------6 y! f/ o/ B# b% M" c5 b6 |' i
    // Name:
    1 R/ }3 E. Z- w! c// Desc: % c8 o1 z. c8 M& z
    //-----------------------------------------------------------------------------
    3 c, C) L2 @/ U9 Cvoid CMazeServer::SetClientReliableRate( DWORD percent )$ S( y' [. W1 H% A$ y/ Q0 e! C
    {
    1 \0 R9 }- h! ?3 O' m9 |5 E3 T( `    // Update client config, and build packet containing that data+ q$ E1 Q" s, O$ h7 O4 J9 ?
        m_ClientNetConfigLock.Enter();
    8 u, `" K4 N& `    m_ClientNetConfig.ubReliableRate = BYTE(percent);! O+ m3 M& x$ S) l
        ServerConfigPacket packet( m_ClientNetConfig );$ S5 c$ u  l$ H
        m_ClientNetConfigLock.Leave();</P>
    & t. Z7 Y0 H% O$ p$ P6 S( U1 z<P>    SendConfigPacketToAll( &amp;packet );
    % `3 \8 E; l0 j  w}</P>
    2 n1 m' V6 v) Q) s2 f& B. z$ D, |: {9 ?
    <P>
    * F5 P* b" m% y9 [7 _2 R, h! h) E" G//-----------------------------------------------------------------------------
    6 f9 {0 P& c$ g/ G9 \// Name: ! J' t- }' [# q% l
    // Desc:
    , u8 E5 h4 q3 `* R//-----------------------------------------------------------------------------
    6 a2 i3 c$ [8 b$ mvoid CMazeServer::SetClientUpdateRate( DWORD rate )/ j3 N9 Z8 R' ~7 N
    {
    * q% g( ~+ k& a( l8 }    // Update client config, and build packet containing that data
    . n9 u- b; O1 C9 I( w9 H* P/ c. d    m_ClientNetConfigLock.Enter();
    * P# c' }4 b% j4 _" |, ~    m_ClientNetConfig.wUpdateRate = WORD(rate);
    0 r$ n2 S" f% ~0 t& \2 c- H! b    ServerConfigPacket  packet( m_ClientNetConfig );( q' w' L* C+ t1 |
        m_ClientNetConfigLock.Leave();</P>6 g! z( j* `2 ~- r
    <P>    SendConfigPacketToAll( &amp;packet );" n* R5 g- F6 V( ]* j6 T3 t. V1 B
    }</P>4 H* A2 Q6 m# [! Z9 D5 j! V

    5 X( G+ i! z( G, }( Y9 F<P>
    & ]! L2 m( E! Y" p//-----------------------------------------------------------------------------
    : y- H& v8 k. z  k// Name: 7 t6 S8 n# S  }, D8 [
    // Desc:
    7 t1 U2 h) F  x' i# w5 L$ [//-----------------------------------------------------------------------------5 \4 b- r8 a8 a# e
    void CMazeServer::SetClientTimeout( DWORD timeout )
    7 @2 Y' v1 `; [, R* T' B1 V{
    6 T1 X+ Z* {' R1 O    // Update client config, and build packet containing that data7 {5 `6 p2 k7 L+ ]7 a6 ]0 B
        m_ClientNetConfigLock.Enter();4 e. {3 Z5 [/ N7 e
        m_ClientNetConfig.wTimeout = WORD(timeout);
    ) u8 Z: F$ a! l9 A+ x6 X) w& C    ServerConfigPacket  packet( m_ClientNetConfig );
    * s) D2 [- r: p    m_ClientNetConfigLock.Leave();</P>, z) z9 L" T8 ]4 J' c$ @  `/ t
    <P>    SendConfigPacketToAll( &amp;packet );/ b! B0 F% w7 d1 I% b
    }</P>3 D9 a. l& ~9 |# e8 s- d. e
    4 T. S8 ^/ t7 u7 q% e
    <P>* @8 @6 N' W$ ]" n9 Y3 v* N- U3 X
    //-----------------------------------------------------------------------------/ V$ H5 O6 B* T6 @8 X
    // Name:
    5 ?0 ^+ Q- b) T. j: d6 J3 J1 B// Desc:   _& E2 R$ U- k( t- q" c
    //-----------------------------------------------------------------------------
    % @1 V; @( y* a: Evoid CMazeServer::SetClientPackSize( DWORD size )
    - Z# d. c  m& E7 S; p* d{  H9 v" ~5 ~+ a3 t5 W8 h
        // Update client config, and build packet containing that data; d! I5 b/ U+ R1 y3 b) k
        m_ClientNetConfigLock.Enter();
    4 F6 g6 ], K1 V" B5 ^* j   
    + P8 Q* }+ W/ q0 I  R    m_ClientNetConfig.ubClientPackIndex++; //Increase index and verify location in array.- `- ^! A5 T8 \% R8 a* e7 m* A
        if(m_ClientNetConfig.ubClientPackIndex &gt;= PACK_ARRAY_SIZE)   
    ' P& c! c) k$ O( x8 E7 P7 \! \        m_ClientNetConfig.ubClientPackIndex = 0;</P>
    ( J$ ~3 }, V3 y/ F9 S+ f: b& k<P>    m_ClientNetConfig.wClientPackSizeArray[m_ClientNetConfig.ubClientPackIndex] = WORD(size);3 J' R0 a2 q% Z' x7 |
        ServerConfigPacket packet( m_ClientNetConfig );7 y, i5 v! u# c" I
        m_ClientNetConfigLock.Leave();</P>! ^' T3 b. ?  ]( ^# ?& c  J3 u
    <P>    SendConfigPacketToAll( &amp;packet );
    - f! ?- P! U7 i$ C}</P>
    : R% C3 {3 K6 \7 a
    ; m$ p! D2 J4 X& B9 r2 ~<P>
    5 r2 M0 f8 o" Q( w: a//-----------------------------------------------------------------------------+ L. _, G2 I$ {; Q* q" b
    // Name: ) v5 x$ Q5 o: d2 c+ F# [
    // Desc:
    0 e5 _' [( _- F9 ]//-----------------------------------------------------------------------------
    ) }+ {3 P+ j, S. evoid CMazeServer::SetServerPackSize( DWORD size )
    : K. ?2 d0 l( n% I9 H8 g5 x+ G0 G{
    5 g# e: Q" i  u' X" S$ R6 {    // Update client config, and build packet containing that data; j0 P  v: h6 ~5 b& W- F7 K3 _
        m_ClientNetConfigLock.Enter();
    8 Q8 E" E& ?, J4 `- h    2 u* e6 [5 t  g0 g, d
        m_ClientNetConfig.ubServerPackIndex++; //Increase index and verify location in array.3 }) P8 B! t& J
        if(m_ClientNetConfig.ubServerPackIndex &gt;= PACK_ARRAY_SIZE)   % q& f# c8 M- K) Q6 q
            m_ClientNetConfig.ubServerPackIndex = 0;</P>9 T6 l$ b" ~7 ~5 H
    <P>    m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex] = WORD(size);! i; `+ w1 K& P/ t9 S, r
        ServerConfigPacket packet( m_ClientNetConfig );
    , F5 W$ l2 N1 h4 s  w6 t/ B$ N! B    m_ClientNetConfigLock.Leave();</P>5 v/ ?! y7 ~6 a. ~! S9 p
    <P>    SendConfigPacketToAll( &amp;packet );- I6 c! x+ O3 J% w/ [! F* i, V
    }</P>) q; R& v$ M, i( [
    <P>
    ; h) z+ l, O, a$ G//-----------------------------------------------------------------------------
    + B* a0 Z. S) \& a) X/ t2 [, j// Name: , s3 y! [  L7 G( P
    // Desc: 9 z( [/ R$ l- T" F# [
    //-----------------------------------------------------------------------------# s6 d3 \6 @( g9 A: [0 ~4 \5 E
    void CMazeServer::SetClientThreadWait( DWORD dwThreadWait )" o( E7 u% {4 `& ]) u8 f. A% ?
    {4 U% l- i  o! Z; O% q8 e
        // Update client config, and build packet containing that data
      D2 e& w" K7 p- e$ P/ @( v- l    m_ClientNetConfigLock.Enter();
    & P; \  x* k. ~9 j4 O   
    1 |1 Z0 r& H/ `! j5 g8 _9 x$ @$ G    m_ClientNetConfig.dwThreadWait = dwThreadWait;9 @) |  n4 v5 L$ I
        ServerConfigPacket packet( m_ClientNetConfig );
    ( C8 j" |& ^& W/ f+ k    m_ClientNetConfigLock.Leave();</P>+ ^/ U, v, l8 q) I/ j& d% j
    <P>    SendConfigPacketToAll( &amp;packet );# v0 u2 }# D& i
    }</P></DIV>
    zan
    转播转播0 分享淘帖0 分享分享0 收藏收藏0 支持支持0 反对反对0 微信微信
    您需要登录后才可以回帖 登录 | 注册地址

    qq
    收缩
    • 电话咨询

    • 04714969085
    fastpost

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

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

    蒙公网安备 15010502000194号

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

    GMT+8, 2026-4-14 16:32 , Processed in 0.420461 second(s), 51 queries .

    回顶部