QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 4179|回复: 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>: O$ b5 A( c6 d6 q, [# E* h
    <>// File: mazeserver.cpp
    5 v* R, U# G5 U) ^; u//
    3 l+ ~, O! c  L9 P// Desc: see main.cpp7 ~* F* L9 }) \: z( i
    //
    + |' B# k& X; [8 s// Copyright (c) 1999-2001 Microsoft Corp. All rights reserved.
    $ l( L8 _3 J6 ~& i1 j//-----------------------------------------------------------------------------6 m$ l5 p% E" a' Q4 L
    #define STRICT
    4 p) Z' v) r. v' Z4 D( T#define D3D_OVERLOADS' X/ S) b/ W; n/ H0 b" x
    #include &lt;windows.h&gt;
    9 ]9 [- `, o9 y8 f; i#include &lt;d3dx.h&gt;; @3 u8 V" F- V: b" ^$ `/ f
    #include &lt;stdio.h&gt;
    ' v6 o& e( j( N8 I* C3 G#include &lt;math.h&gt;1 [7 N+ k& v' R" t2 i' O- l& k
    #include &lt;mmsystem.h&gt;
    * n6 ^. G/ [8 @& r#include &lt;dplay8.h&gt;
    1 y" G& D2 z2 q0 s1 N3 Z#include &lt;dpaddr.h&gt;# p5 d( V* v% u1 K
    #include &lt;dxerr8.h&gt;- |  U: H% S8 ]! X0 Z
    #include "DXUtil.h"
    8 `* t  L) Y  [" f5 ^#include "MazeServer.h"
    - w, M9 d1 J: s% x: T#include "ackets.h"
    " E  ^, `: S' c#include "Maze.h"
    ; n8 i( I8 E* D#include &lt;malloc.h&gt;( A& A/ l0 D1 L: W3 A9 r  \9 y
    #include &lt;tchar.h&gt;</P>
    ) X3 [0 a6 V: H
    0 v$ z$ \) j  h9 ?! ?<>//-----------------------------------------------------------------------------: \1 M; J* s7 f! Y* q7 s
    // Name:
    # u  v/ H7 N0 H4 k// Desc:
    . R0 H( _( a0 F8 y* B2 H7 y% o* e6 {//-----------------------------------------------------------------------------  P! i1 t/ u) T! \
    CMazeServer::CMazeServer()& i# \8 z6 F8 X5 I
    {6 I7 L" N7 a; F2 X+ R
        m_dwPlayerCount         = 0;
      N( X3 R* Z% ^   
    * y( a' g- a3 \+ h/ u$ ]    m_wActiveThreadCount   = 0;
    " _) @8 ?0 u+ Q% S1 M! h    m_wMaxThreadCount      = 0;& P  c, ~( _1 a4 h; s- O
        m_fAvgThreadCount      = 0;7 a2 h4 I3 R! k, j! Y) `
        m_fAvgThreadTime       = 0;& }, L. @* C6 N# q
        m_fMaxThreadTime       = 0;</P>
    4 Z  J' ^# I) a* z1 z6 _) z' ]$ Y<>    m_dwServerReliableRate  = 15;
      W$ @* G9 `1 U; N    m_dwServerTimeout       = 150;
    : k: H7 G( [  _+ r/ \0 m    m_dwLogLevel            = 2;
    : J. T0 Q8 B. w# m+ e' Y$ `    m_pMaze                 = NULL;</P>
    7 T) n+ E1 x% N0 j# t; M+ M<>    m_ClientNetConfig.ubReliableRate = 15;
    ; Z* ]! g1 n- t' ?' [    m_ClientNetConfig.wUpdateRate    = 150;) `& {9 P1 @9 C8 Y- j7 Z
        m_ClientNetConfig.wTimeout       = 150;</P>. i+ z% ?" o& \( F/ t, n" M
    <>    m_ClientNetConfig.dwThreadWait = 0;</P>
    # j* z+ A  g4 F6 p0 n+ ?/ V% ^) H<>    m_ClientNetConfig.ubClientPackIndex = 0;( C2 e  v$ _, `$ i
        m_ClientNetConfig.ubServerPackIndex = 0;
    7 r7 C" u% A; V% o8 [    for(WORD x = 0; x &lt; PACK_ARRAY_SIZE; x++)
    - W# m3 M2 _9 q" X6 D3 t' Z    {
    0 a( T1 h9 W$ z9 ?5 A        m_ClientNetConfig.wClientPackSizeArray[x] = 0;6 I% e  p4 _& E. o: D/ A& Z
            m_ClientNetConfig.wServerPackSizeArray[x] = 0;
    ! z# W2 |; ^( \) G2 k    }4 b2 y% ?! O* w. w: @8 F; }2 q* h
    }</P>4 N- n  ]  m# {
    8 H- M2 z2 a2 `3 b
    <># z$ A3 c) ?; W3 W9 l
    //-----------------------------------------------------------------------------+ o7 D& m4 h3 Q
    // Name: , X( [* r; b( a- u( l3 r; `+ t
    // Desc:
    " L0 d; K9 @: m6 e3 D//-----------------------------------------------------------------------------: J- o0 H5 ?4 b. @$ o
    HRESULT CMazeServer::Init( BOOL bLocalLoopback, const CMaze* pMaze )' {, v' G6 X, E6 e  Z; Z5 K0 k/ Q
    {
    2 H: `' ^8 v* t5 d. V* e    m_bLocalLoopback = bLocalLoopback;
    4 @" [' Z( i# T# D& \    m_pMaze = pMaze;/ o$ \" J' s* v9 m2 \! B
        if( m_pMaze == NULL )
    ' R0 k5 g' K- a' a  j        return DXTRACE_ERR( TEXT("aram"), E_FAIL );</P>
    8 l; [: ]6 g8 m; @* O/ q<>    // Grab height and width of maze
    9 Y6 j0 I# \( a0 ~5 R    m_dwWidth = m_pMaze-&gt;GetWidth();
    ( i0 Q( _5 v5 v* ~    m_dwHeight = m_pMaze-&gt;GetHeight();</P>; }% X' S" ~. A( `. E
    <>    m_ClientNetConfig.dwMazeWidth  = m_dwWidth;
    / ~$ |% V6 C% ^$ n7 r( v2 `9 x% ?    m_ClientNetConfig.dwMazeHeight = m_dwHeight;</P>
    * f+ z* ^: v7 h0 r6 V' {! |! H<>    // Validate size. Must be a power-of-2 times LOCK_GRID_SIZE. Compute the shifts.6 B, H. c5 S/ E3 m5 q
        if( m_dwWidth &gt; SERVER_MAX_WIDTH || m_dwHeight &gt; SERVER_MAX_HEIGHT )3 K! U# p$ H' ]4 z% _6 ^
            return DXTRACE_ERR( TEXT("Maze height and width need to be less than 128"), E_INVALIDARG );, o$ i3 N2 i2 @$ ]4 A' k4 i- B
        if( (m_dwWidth % LOCK_GRID_SIZE) != 0 || (m_dwHeight % LOCK_GRID_SIZE) != 0 )- E6 M& ~" g9 p. z6 `  ]' \6 ~; E
            return DXTRACE_ERR( TEXT("Maze height and width need to be divisable by 16"), E_INVALIDARG );</P>4 U; Q5 P8 j4 M% z% s/ {0 o) [
    <>    DWORD scale = m_dwWidth / LOCK_GRID_SIZE;
    . x  s9 p- d0 w. s& P( ]* ]    m_dwMazeXShift = 0;: ]& ^" ^. U& j4 @3 L+ U
        while ( (scale &gt;&gt;= 1) )
    ; i# Q$ h! ?9 q  L        m_dwMazeXShift++;</P>) ~/ `( i" i* T% C8 |1 e# |
    <>    scale = m_dwHeight / LOCK_GRID_SIZE;
    / W6 }4 a0 p* X: m    m_dwMazeYShift = 0;
    5 w" L6 R. O+ B2 }$ J, P    while ( (scale &gt;&gt;= 1) )# z* Z; f* y8 E- p
            m_dwMazeYShift++;</P>* }% k- d6 u" |& L5 v, d
    <>    if( ((DWORD(LOCK_GRID_SIZE) &lt;&lt; m_dwMazeXShift) != m_dwWidth) ||
    ! c, _. Y! U% `+ R! \        ((DWORD(LOCK_GRID_SIZE) &lt;&lt; m_dwMazeYShift) != m_dwHeight) ), J) F1 V8 S# q0 C5 F" c( R
            return DXTRACE_ERR( TEXT("Maze height and width need to be power of 2"), E_INVALIDARG );</P>
    ' f8 V6 f0 Y: g; W<>    // Initialise the player list
    9 }6 c) I/ D0 R$ K    ZeroMemory( m_PlayerDatas, sizeof(m_PlayerDatas) );# C6 @( c0 r" X9 j) j$ _
        m_pFirstActivePlayerData = NULL;
    + L6 J9 [2 v& u3 z1 S' e0 E2 X) i    m_pFirstFreePlayerData = m_PlayerDatas;" }$ e) x, y8 `$ O0 H* j; j$ e1 v
        for( DWORD i = 1; i &lt; MAX_PLAYER_OBJECTS-1; i++ )
    ) Q7 I1 ]: a$ Q6 S5 h" G, W! {    {
    4 F; f- J, O! X* f        m_PlayerDatas.pNext = &amp;m_PlayerDatas[i+1];4 r: F9 J" ^( g0 ]( U7 ^0 e1 b- }* n  I
            m_PlayerDatas.pPrevious = &amp;m_PlayerDatas[i-1];
    . x( K; P6 T' z6 t1 l% L' E    }</P>
    , S7 k2 i, q9 B( e<>    m_PlayerDatas[0].pNext = &amp;m_PlayerDatas[1];
    6 Y* M# U  m) |    m_PlayerDatas[MAX_PLAYER_OBJECTS-1].pPrevious = &amp;m_PlayerDatas[MAX_PLAYER_OBJECTS-2];+ I( @  f" T" r, r8 c* Y
        m_dwActivePlayerDataCount = 0;9 r: K  k9 t# B3 g; n- X
        m_dwPlayerDataUniqueValue = 0;</P>
      t6 d9 S1 c7 f' B$ y4 h<>    // Initialise the cells: Y( n9 M. d" y. R; V4 E
        ZeroMemory( m_Cells, sizeof(m_Cells) );5 D/ s: K' i) J  |
        ZeroMemory( &amp;m_OffMapCell, sizeof(m_OffMapCell) );</P>) h5 K5 K) p! I0 x
    <>    return S_OK;
    ) l+ H: w0 U6 v( u, }/ z}</P>
    6 F( t( o. ]. p) F: @" q8 d* T6 F. h( w3 q& I6 Z( r
    <>
    ' X; k7 p1 {: v//-----------------------------------------------------------------------------' Y5 q+ v4 f" J) d# X9 f
    // Name: $ K, M& H, A7 e2 C: G
    // Desc: ! \! }" Q$ t" b: a  L
    //-----------------------------------------------------------------------------
    ' n/ j! G+ z+ ]1 e; c$ dvoid CMazeServer::Shutdown()
    : O4 e; J. |. O! @% y1 |{' `9 o. {6 j/ l2 s
    }</P>2 m& G% b! z' ]& x/ ]

    ) n, t( e, C1 T8 g6 g<>
    6 S7 t$ C" X" g( z" U/ a//-----------------------------------------------------------------------------
    , u/ H' q5 Y! E: w% J6 u% M// Name:
    8 y8 N) Y% J  ~* a6 b( ?$ k// Desc: # Y5 N# N$ V1 U& s. \3 `3 |
    //-----------------------------------------------------------------------------
    - I3 d* w* L+ e# M# q- ^" L" o- }5 ]4 [, Vvoid CMazeServer:ockRange( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )+ D0 G  G( e. r  B* A; X- f- L
    {
    + C- S4 K! U( ?1 O% T    m_LockGrid.LockRange( x1&gt;&gt;m_dwMazeXShift, y1&gt;&gt;m_dwMazeYShift ,; @1 f2 Q" B7 L2 Z. ?( e' a8 a3 G9 Q
                              x2&gt;&gt;m_dwMazeXShift, y2&gt;&gt;m_dwMazeYShift );
      |# B4 e/ a7 [}</P>
    , D( [# A' k& Z/ [6 B1 j
    9 j4 @" `% x3 J; Z) E<>- C' P% y3 c; |  ^3 C, p& G* C
    //-----------------------------------------------------------------------------) s) x: f1 a. G+ f: u% P
    // Name:
    0 H' [- Q7 ]$ b- \' t- L- j// Desc: " @' v; P  K( ~% b: s' a
    //-----------------------------------------------------------------------------
      t2 G# |5 @! g9 `" L# nvoid CMazeServer::UnlockRange( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )- ~8 [4 l9 A. X5 @. ?, f% b. `
    {, f/ j3 @' L1 @0 H3 T
        m_LockGrid.UnlockRange( x1&gt;&gt;m_dwMazeXShift, y1&gt;&gt;m_dwMazeYShift ,2 j/ u  U8 N) ~% k8 K5 e1 x) u% B
                                x2&gt;&gt;m_dwMazeXShift, y2&gt;&gt;m_dwMazeYShift );6 G3 O4 P* y% g/ ], D, w: P, g
    }</P>
    # z4 X. k4 }. U4 j' E$ K" S+ W4 _# _$ M. X; Z9 P: e4 p6 K
    <>) h  I( _7 |* g; M/ L2 v1 \* F  K/ j
    //-----------------------------------------------------------------------------( \" q5 @1 \7 ]: J0 x9 A' P
    // Name: % \% @$ v4 M! x- G
    // Desc:
    % v6 q* ?: S$ Z//-----------------------------------------------------------------------------
    9 _" X  H% t4 Rvoid CMazeServer:ockCell( DWORD x, DWORD y )' I9 |  K1 M( b6 f
    {
    / h! P+ n& o8 J, ^! O' @9 @+ L    if( x == 0xffff )
    & q: E# |5 H$ X8 o: u5 K/ N# V        m_OffMapLock.Enter();
    7 L, d8 {7 ~8 N    else- a  {2 d1 X/ k5 {' G
            m_LockGrid.LockCell(x&gt;&gt;m_dwMazeXShift,y&gt;&gt;m_dwMazeYShift);
    6 R  f: q! `/ d" ^- k, x7 z}</P>
    7 y. y( j( P, j8 o0 L. L7 Z) y$ P; L7 j# J
    <>
    * s# G% o& }0 \//-----------------------------------------------------------------------------4 }2 c. Q% H# L; m# w  y4 H
    // Name:
    / Y% K3 J% ?2 Y* H4 }// Desc:
      W5 b% {6 u: J//-----------------------------------------------------------------------------8 b) y4 a6 {* v/ ~3 _
    void CMazeServer::UnlockCell( DWORD x, DWORD y )) {  z# H( ]6 H' t! [: M
    {
    3 z# @' C( f/ I* ]- }    if( x == 0xffff )$ z& o) Z  Z& o5 n# L+ Q
            m_OffMapLock.Leave();4 r" H& h) Y! j6 F
        else
    7 s) N. m/ {/ h( f" G3 i% V/ C        m_LockGrid.UnlockCell(x&gt;&gt;m_dwMazeXShift,y&gt;&gt;m_dwMazeYShift);  D% R2 ~/ p' {- u
    }</P>
    0 t! d( ?& \5 O: q) T# H
    ; \1 m. o: f* B" O1 c, }! \<>5 L7 r* h+ x) W8 R( P; V( e; J
    //-----------------------------------------------------------------------------
      k* T7 U4 ~8 u// Name: ! D4 W" n- e7 z# I: a& S# d
    // Desc:
    6 ~8 P/ G9 ?- O7 l2 X( x, |//-----------------------------------------------------------------------------
    ( S4 j$ }2 s$ m9 q/ G1 _void CMazeServer:ockCellPair( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )8 o- N: D1 ]1 z, `$ n
    {% V# h6 n) O9 t
        if( x1 == x2 &amp;&amp; y1 == y2 ): J- l8 D7 g* R, T6 ^
        {
    4 U  n" \  v1 P+ k& W        if( x1 != 0xffff &amp;&amp; y2 != 0xffff )
    1 l) U( Y4 I% Z; S            LockCell( x1, y1 );% k. Y( V6 `5 K' R+ B1 c1 I/ Z
            else- e9 S6 E- ]1 O0 A6 @. y
                m_OffMapLock.Enter();</P>) m/ G7 ^; b/ w$ q% v6 L
    <>        return;+ L. Q( e5 R% F
        }</P>
    / q1 h* g, l  l+ ?<>    DWORD x1shift = x1&gt;&gt;m_dwMazeXShift;
    / n8 m- ~) u1 x4 E, H8 G% o    DWORD x2shift = x2&gt;&gt;m_dwMazeXShift;
    7 q2 ]- n3 d$ n1 D! Q! Y    DWORD y1shift = y1&gt;&gt;m_dwMazeYShift;
    % j0 M& K" |0 _! x' _5 ~5 O; k    DWORD y2shift = y2&gt;&gt;m_dwMazeYShift;</P>7 j2 `' |& F2 e4 \- z
    <>    if( x1 == 0xffff )0 y! k8 P$ V0 h9 R
        {
    6 K1 k" {5 `" M' j6 \, i- T        m_OffMapLock.Enter();/ n0 ^& z5 j/ o4 E" j! V/ L. \3 z
            m_LockGrid.LockCell(x2shift,y2shift);
    8 P) @9 U( |2 L8 V2 O: D    }* b- R. O: ~0 G5 s4 o9 C4 z6 T
        else if( x2 == 0xffff )& M7 P8 [+ l( b7 V
        {9 l) r. L4 V4 n( d4 V# `& a
            m_OffMapLock.Enter();
    # [2 {( z; d  D+ g# [        m_LockGrid.LockCell(x1shift,y1shift);/ [  m6 _% l& g- X/ T
        }* e, u4 Y/ s( t; G* ~! F
        else * v  W9 [! O# Y9 F/ f: G2 K
        {' B' n! m- d7 l* a. e7 _
            m_LockGrid.LockCellPair(x1shift,y1shift,x2shift,y2shift);8 {3 Z7 v3 s6 z# \
        }# p( r- }+ w: W, A
    }</P>& D9 C/ v6 D* L6 N7 P1 i8 m0 p

    8 }+ R- A! G2 [! ^<>
    + v1 [- a: ?* P* z//-----------------------------------------------------------------------------$ j/ C1 u8 i3 H" }9 D% f, L
    // Name: 6 M9 J, S4 p7 y8 `1 [6 R
    // Desc: ) B6 e, w1 p. [; t2 N9 b
    //-----------------------------------------------------------------------------9 n0 h% g/ `0 C2 p( p$ V4 P+ z" _/ A# c
    void CMazeServer::UnlockCellPair( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )6 I9 [7 T8 ^: k9 f
    {% w2 l" s( b" @: w; y& T1 Q
        if( x1 == x2 &amp;&amp; y1 == y2 )
    : b% n" q2 M1 Y% H6 z& x0 G    {
    / H) t3 Y8 F6 L5 e, i+ a! f        if( x1 != 0xffff &amp;&amp; y2 != 0xffff )) ?. @6 k+ o: |% g! ~" G4 a1 q
                UnlockCell( x1, y1 );# R8 h) W6 V' I1 f3 Q5 V
            else
    2 Z& `1 S( m, x' Z! U* V% s* K            m_OffMapLock.Leave();</P>. A" i) ]1 N; [2 `1 _0 O  g- L
    <>        return;
    1 U& A0 g) f1 e5 @    }</P>
    9 [; H1 W2 Z2 |1 }7 e; U<P>    DWORD x1shift = x1&gt;&gt;m_dwMazeXShift;6 ]* ^" `' W% L% F
        DWORD x2shift = x2&gt;&gt;m_dwMazeXShift;
    4 P& ]5 e9 q, V% ]( Y) |7 u# q    DWORD y1shift = y1&gt;&gt;m_dwMazeYShift;+ |  w: M2 Y( z! _( W& H$ o% ^3 y
        DWORD y2shift = y2&gt;&gt;m_dwMazeYShift;</P>. }$ k0 T% M& {+ F, J, _7 y6 q4 M
    <P>    if( x1 == 0xffff )
    - x4 `% G' ~' \" F" J    {% t4 D, E& O" K+ s
            m_LockGrid.UnlockCell(x2shift,y2shift);$ K( H9 n$ C4 W. X! p8 D2 v
            m_OffMapLock.Leave();
    ; f- T( l4 W8 D/ g0 `) ^. ^    }0 d2 ~/ {. Q* g- @* r! q
        else if( x2 == 0xffff )
    ! V! S! k! V2 u% G/ n$ x    {& ], q- R& X8 ~0 K. q" Y8 _
            m_LockGrid.UnlockCell(x1shift,y1shift);5 P; I7 p9 O" q; m  U
            m_OffMapLock.Leave();
    1 s! X4 t) y; R    }
    0 t* A6 e; r7 ~3 B4 v    else
    : v2 y/ E' [9 D7 t  T    {
    " F1 Y. x( ?: L6 b        m_LockGrid.UnlockCellPair(x1shift,y1shift,x2shift,y2shift);
    , p, B% s/ }$ p( D9 b    }
    7 n0 r+ k- U/ H2 Y2 p}</P>- P5 f$ Z- f6 ]2 @1 q" a

    5 m+ ~/ D0 N# ?2 T6 F7 J<P>: c4 t% p/ X4 R7 w- g' D/ S4 q
    //-----------------------------------------------------------------------------( _' f# W) e- j7 e5 ^8 a! D
    // Name:
    6 L9 t# n* M# a// Desc:
    : R$ r; j) B" H3 j9 |) r3 x1 i/ \& B//-----------------------------------------------------------------------------% j1 V; z! X$ W7 e
    void CMazeServer::OnAddConnection( DWORD id )+ ^' c8 C2 v: l' p
    {
    + W7 B; c. N0 Q( O6 C  t    m_AddRemoveLock.Enter();</P>0 T1 P! M  D9 M. t% S/ [7 v
    <P>    // Increment our count of players. m9 T' o3 K& W- W: L& q1 @
        m_dwPlayerCount++;- p/ K  p7 W) C" a
        if( m_dwLogLevel &gt; 0 )8 `5 E2 D# h. E: }0 Q( J, w  Z
        {5 \4 @9 r  {! m* I, U
            ConsolePrintf( SLINE_LOG, TEXT("Adding player DPNID %0.8x"), id );
    ! B! ]7 e& h( @* j        ConsolePrintf( SLINE_LOG, TEXT("Players connected = %d"), m_dwPlayerCount );
    ) C0 d% y! D3 M0 b+ x! a4 t" i    }</P>/ D0 h) ~' ?: F8 e
    <P>    if( m_dwPlayerCount &gt; m_dwPeakPlayerCount )
    ' `! H0 U" \6 z0 W! }  Q- V        m_dwPeakPlayerCount = m_dwPlayerCount;</P>2 [+ \* G& g6 e: x
    <P>    // Create a player for this client
      P" {0 F; A0 o: }% X    PlayerData* pPlayerData = CreatePlayerData();$ A+ O4 o% K) A* W% A3 H
        if( pPlayerData == NULL )
    ' L  O0 ~$ u! {8 F) X) U/ [( I' j    {
    9 c. B1 j' y  W% ]        ConsolePrintf( SLINE_LOG, TEXT("ERROR! Unable to create new PlayerData for client!") );" _: g9 u- ]# e( m% D2 R
            DXTRACE_ERR( TEXT("CreatePlayerData"), E_FAIL );
    ' s$ w* P4 U+ i/ `# v8 R        m_AddRemoveLock.Leave();
    . ^$ A: [* S) P& [$ T        return;
    5 ]7 E& V6 j" J% q) S    }</P>- |' R( X& W- y$ J% \$ L! {% |  m0 ^
    <P>    // Store that pointer as local player data) ?- {5 O) F: u; k) t
        SetPlayerDataForID( id, pPlayerData );</P>$ U4 o  ~+ x! C. Z4 H- M1 W7 K7 A
    <P>    // Grab net config into to send to client1 [7 y$ |2 F, I* x
        m_ClientNetConfigLock.Enter();0 T( t: c# m6 r5 L. \# x3 W
        ServerConfigPacket packet( m_ClientNetConfig );! F4 t4 s; ]) O& N
        m_ClientNetConfigLock.Leave();</P>. b4 l& u3 T3 V* t. W" b
    <P>    // Send it
    & o* f3 B/ o+ B5 b, c  k    SendPacket( id, &amp;packet, sizeof(packet), TRUE, 0 );</P>
    7 |2 W! z, w8 A0 O4 \<P>    m_AddRemoveLock.Leave();+ r8 C# K9 i( o
    }</P>
    ; Y/ S2 B) ]) m2 ^( x) c) A; S: }# n9 d' X' X2 m8 O
    <P>
    / }' I# u. k  Y) W//-----------------------------------------------------------------------------
    3 K" k4 j0 ~% a* @: W- H) G// Name:   e* y4 @( F1 @, p5 w+ t) t
    // Desc: ' v+ P7 ~! T: g7 h
    //-----------------------------------------------------------------------------" L1 W4 i+ K3 ?0 O. u
    void CMazeServer::OnRemoveConnection( DWORD id )
    / q! h0 p+ c* \{
    8 e' t( p! b9 \0 C* ]2 V8 q    m_AddRemoveLock.Enter();</P>
    : V. h  n* x, m/ \; E' A4 b4 F( P<P>    // Decrement count of players3 D' I/ R; X8 ]' E( t9 Y
        m_dwPlayerCount--;</P>
    # H" S; B" u" P# C! e<P>    if( m_dwLogLevel &gt; 0 )
      @" Q5 O% X2 C9 I9 d" K    {2 G  C% i& K8 q5 [" S) m$ V
            ConsolePrintf( SLINE_LOG, TEXT("Removing player DPNID %0.8x"), id );
    2 h* F, B. M- e5 L2 M        ConsolePrintf( SLINE_LOG, TEXT("Players connected = %d"), m_dwPlayerCount );
    7 b) P4 F4 h- ?. @    }</P>' @& n) F5 G  ]$ _% I$ \
    <P>    // Find playerdata for this client* o& t& ~7 t, s# w' P
        PlayerData* pPlayerData = GetPlayerDataForID( id );
    5 F8 E& ^& X! d6 [* U    if( pPlayerData != NULL )
    4 }" z" U4 l& b, H; W    {
    7 N9 U1 H8 t3 B( N8 ~$ R5 n; l  [        // Destroy it
    ' x( i: ~( A& L        RemovePlayerDataID( pPlayerData );2 `) y* {. k9 R# V; A
            DestroyPlayerData( pPlayerData );
    & U& g0 C" M- D% j7 m& Y  d    }</P>
    & @; X' H8 W' M. I0 W4 s4 k<P>    m_AddRemoveLock.Leave();) R+ h3 ?, D1 b7 v0 ~& ~7 \3 C
    }</P>* ?! Q! u( L2 h# w+ x
    8 n% a/ l' G: ]: W8 p: p' y/ R- q
    <P>% V' ~( r) u! j" o" u0 A! D2 d3 A
    //-----------------------------------------------------------------------------
    ; k$ P) n# `6 E: A// Name:
    2 B/ G8 e- A) U" ]// Desc:
    . N2 t: c/ x8 s$ r+ @& Z//-----------------------------------------------------------------------------
    2 |4 I5 }$ |3 f; G! fHRESULT CMazeServer::OnPacket( DWORD dwFrom, void* pData, DWORD size )
    ( h" L8 r; m' M( m8 h) [{+ Q, P! f0 _' \
        BOOL fFoundSize = FALSE;</P>
    * L" e- i" D8 {* q, v<P>    // Increment the number of thread we have in this process.
    & ^, n4 Q8 f' a2 K- r# E9 t    m_csThreadCountLock.Enter();</P>, ?) `, T0 u' D5 W
    <P>    //Get the start time of when we entered the message handler.
    0 s2 w- @9 v6 n    FLOAT   fStartTime = DXUtil_Timer( TIMER_GETAPPTIME );</P>
    / P( {0 a- m* m& P$ L" ~) X<P>    m_wActiveThreadCount++;
    % B( ?2 C/ s  c, m    if(m_wActiveThreadCount &gt; m_wMaxThreadCount)
    $ r; E1 ~4 s! c1 X: Z2 ]        m_wMaxThreadCount = m_wActiveThreadCount;
    4 x+ T. d  A+ t; v. z# ?    * ~* o" ?3 n, h  q0 s
        // Calculate and average.8 ~6 ?) P$ j3 @
        FLOAT fdiff = m_wActiveThreadCount - m_fAvgThreadCount;
    3 H4 b0 E- c3 m2 ^1 y& @9 }' `    m_fAvgThreadCount += fdiff/32;- o/ m, v9 E, C) t& K
       
    5 g% U; I$ q+ c5 a7 {) X    m_csThreadCountLock.Leave();</P>5 {  m8 q7 ~1 N# H! o8 `
    <P>
    + O% A' S# H8 l2 \    ClientPacket* pClientPack = (ClientPacket*)pData;
    6 M+ S5 k2 M$ d' ^( L    switch( pClientPack-&gt;wType )
    . J1 t8 y. N/ S2 G; Z    {& k# `8 F1 l7 V6 w5 Y- J2 P
            case PACKETTYPE_CLIENT_POS:" w) Z, K& d! n( u6 R
                
    : I, ?1 {$ s3 B            // Check to see if the packet has a valid size. Including
    & C! ?, C! V% \% f; C7 a            // the custom pack size.
    - x: k! R8 H" A  F4 a0 k  E' k8 T- g            if( size &lt; sizeof(ClientPosPacket))
    8 c% s( P4 p4 C+ q                fFoundSize = FALSE;
    ( F' O" ]% q% {' [6 k# Z7 v            else if( ! IsValidPackSize(size - sizeof(ClientPosPacket)))
    " r3 |5 x: t# ^8 ?( q8 _2 v                fFoundSize = FALSE;
    ! y! @- \/ i5 }! `" w. x' n            else# }( q# X1 ?! _
                    fFoundSize = TRUE;</P>
      O$ m; |- c  A* ^* C) Z6 f3 ~<P>            // If valid sized packet, handle the position.$ {0 K9 E$ B  z4 g, i
                if(fFoundSize)
    & F& a; y7 k5 ~7 ?: |1 [                HandleClientPosPacket( dwFrom, (ClientPosPacket*)pClientPack );
    ( X& t7 S5 ?: b% {3 O! j            else
    & N' e7 q, w2 ]1 F( j                m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );</P>
    6 e" H" b, W& j5 _<P>            break;</P>
    2 ]; a! c- Z5 o2 U+ g$ ~<P>        case PACKETTYPE_CLIENT_VERSION:
    & a/ A# _0 B* V+ ?! T( w, D- J            if( size == sizeof(ClientVersionPacket) )
    $ }/ G+ S" X. W2 r) g                HandleClientVersionPacket( dwFrom, (ClientVersionPacket*)pClientPack );
    2 R0 X# L6 }  y            else* J, D) j% b' `& }
                    m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );- A; s3 k' c. t
                break;</P>
    $ Z; k$ p" V$ E1 _% B! a<P>        case PACKETTYPE_SERVER_CONFIG:</P>2 q! ]) c, F% S- I( s9 R
    <P>            // Server config packet sent to all users (including server). Just ignore and continue.</P>9 p. l) _. m; }* l
    <P>            break;# X7 r) M! s- L9 Z( o1 P  [
            default:
    / L! H8 _. S/ D% f4 d            HandleUnknownPacket( dwFrom, pClientPack, size );& x( l+ A6 b4 `( m  j) n8 H
                break;
    0 p. B5 W) _0 A0 H; f$ s    }</P>  H2 l. R4 ^+ {8 ?7 e$ V
    <P>    //If the user wants to hold the thread, Sleep for given amount of time.' v+ w$ G( d; S( r& M& V
        if ( m_dwServerThreadWait &gt; 0 )
    # N' I! }( d- O    {; C) R% |2 i& X( d- c( Q1 o0 B
            Sleep( m_dwServerThreadWait );
    1 _0 J; A6 Y  L9 F7 `8 [2 D    }
    2 d5 a/ r9 X+ \+ n, t  X7 G   
    : X: p" o' Q' {# r* p2 |    // Retrieve thread data for this process./ s9 q+ e0 l% x7 u9 e
        m_csThreadCountLock.Enter();</P>
    ; o* \6 H4 L6 R! d' v% U. V<P>    m_wActiveThreadCount--;</P>
    + @1 X# @' V+ D) \* R  W<P>    FLOAT fDiffTime = (DXUtil_Timer( TIMER_GETAPPTIME ) - fStartTime) - m_fAvgThreadTime;
    0 I1 Y9 J3 j" C, v( D    m_fAvgThreadTime += fDiffTime/32;</P>
    + G8 X+ D8 k4 u/ g5 {) ~9 z% h  @" F<P>    //Get the Max time in the thread.5 d. W( Z) G) K7 N1 y
        if ( fDiffTime &gt; m_fMaxThreadTime )
    + A  G( u- R0 N. G: u/ p5 ^    {
    & |4 X8 F1 J8 {9 _: R  O# Q! O        m_fMaxThreadTime = fDiffTime;
    0 Z5 B, O5 E7 u- ]- C+ C    }</P>+ z1 C; O/ Z* f5 I5 {- c
    <P>    m_csThreadCountLock.Leave();</P>
    / B6 C: n+ L; i* m<P>    return S_OK;9 S$ X/ C: x5 R" D3 k
    }</P>1 q' ~: l6 a- M  x7 W$ L' E5 ?
    - D  B/ R# J. S) `2 C  V
    <P>//-----------------------------------------------------------------------------; y! w) t$ B/ s/ S7 T
    // Name: 2 Y5 R/ C0 ^6 Z/ s; ]
    // Desc: # l& q* g( B8 O0 }6 L$ c+ {- u
    //-----------------------------------------------------------------------------
    : b7 V" G4 G4 D4 L* zBOOL CMazeServer::IsValidPackSize( DWORD dwSize )  Q8 h- o5 s6 z: X! }# O
    {
    + a* Z  Q1 O) @. \    BOOL fFoundSize = FALSE;1 ]% d6 Y" q$ q2 w0 `
        BYTE ubPackLocation = m_ClientNetConfig.ubClientPackIndex;" a+ J) E- A2 {6 L. A  [
        1 R& _0 W7 C' m3 \+ [/ ?
        // Check through the array of valid pack sizes.
      u! q8 n+ `* w    if(dwSize != m_ClientNetConfig.wClientPackSizeArray[ubPackLocation])" I& u6 `4 B  J3 c: M
        {3 j% T* j; _# t; l
            for( --ubPackLocation; ubPackLocation != m_ClientNetConfig.ubClientPackIndex; ubPackLocation--)- I7 L" p; y5 g7 S$ I
            {( Z; c4 B2 o! g8 u
                if(dwSize == m_ClientNetConfig.wClientPackSizeArray[ubPackLocation])
    9 |6 p* {1 y- M2 \& F' N) v7 ^# f( K$ z            {% b# W4 r9 a9 b+ M: q6 c  K" x
                    // Found valid size in the array.
    8 P- Q; m7 o  H$ t: _' P+ ^  ~                fFoundSize = TRUE;6 `/ q9 |4 \2 u7 ~( o% _9 x
                    break;+ P- q2 R0 t; e4 {
                }
    $ Y% P5 f6 s2 {4 O7 B            if(ubPackLocation &gt;= PACK_ARRAY_SIZE)  ubPackLocation = PACK_ARRAY_SIZE;  //Wrap the array./ Z9 C  P! r* D1 @
            }5 k7 _9 w1 C0 `! B; b" K
        }
    1 m3 b$ Z# X! R4 Q8 `* @" a8 D    else
      n6 x1 U3 S9 Y7 q2 }/ j9 ?    {
    2 e4 _0 s' T' K8 T& s        fFoundSize = TRUE;2 ]+ }3 _0 E: t0 r) V, W
        }</P>
    ! N9 J$ p* E4 j1 c3 u& B7 l. C<P>    return fFoundSize;
      v( B; z7 e3 V5 `}</P>
      x* f, S: m, \4 [! w% C<P>
    $ h- x& G' ~2 @3 z6 D//-----------------------------------------------------------------------------* B' i0 {/ G2 K! R
    // Name:
    : t+ Q9 f& M- u9 J2 O6 I// Desc:
    , ~) Y/ a( h" p& Q) j//-----------------------------------------------------------------------------9 X# B1 I# F  F" t8 @
    void CMazeServer::OnSessionLost( DWORD dwReason )1 F; u4 f+ V' M1 G4 @: @, g
    {" k( _1 I+ M$ h, x' G( Z1 Y
        ConsolePrintf( SLINE_LOG, TEXT("ERROR! Session was lost") );
    7 F4 X/ A5 V* A& K}</P>
    3 |1 W% j) X+ _3 V
    + Q7 V3 {8 L; Z5 ^. D, s4 T; j<P>" w& [" E5 Z$ b& Z# k
    //-----------------------------------------------------------------------------
    0 [9 f/ H  i5 I8 }8 f& i+ M// Name:
    % s! |" [9 `. V4 A// Desc:
    ) L+ _$ ^8 `( b; p//-----------------------------------------------------------------------------) ?  U1 l; a( ^1 T3 z
    PlayerData* CMazeServer::CreatePlayerData()
    1 |& x2 x9 ^% v0 Q. l; n( }{7 s8 y! L4 C5 S7 x2 n9 Z
        m_PlayerDataListLock.Enter();</P>' M1 M7 g9 i& V
    <P>    // Grab first free player in the list* {: Z% @- W5 E; N5 r. b2 h
        PlayerData* pPlayerData = m_pFirstFreePlayerData;</P>/ g5 J) t) P6 p% J( |  q- w
    <P>    if( pPlayerData )6 p& R6 W8 }7 F9 J5 }* u" ^
        {( z( w  W5 K4 j% z2 w, K
            LockPlayerData( pPlayerData );</P>1 A/ C$ h7 I+ Y! w
    <P>        // Got one, so remove it from the free list
    , L) Q$ e- j+ n" z0 t        if( pPlayerData-&gt;pPrevious )3 `8 B) O' ?) {- V6 Y5 K1 d: K# I
                pPlayerData-&gt;pPrevious-&gt;pNext = pPlayerData-&gt;pNext;9 I6 Y2 Z5 j( t5 Q1 _
            if( pPlayerData-&gt;pNext )
    8 e7 w- Q2 |0 Z* _9 _6 Q            pPlayerData-&gt;pNext-&gt;pPrevious = pPlayerData-&gt;pPrevious;) ~: u: Z5 m; b9 O& N3 w
            m_pFirstFreePlayerData = pPlayerData-&gt;pNext;</P>; I3 _" y# R, h  \1 U
    <P>        // Add it to the active list
    8 @# w! z, F! q7 q. x/ ^        if( m_pFirstActivePlayerData )
      y2 y* S4 U* f, Z0 k6 b            m_pFirstActivePlayerData-&gt;pPrevious = pPlayerData;/ x, L; w/ W1 W6 Q6 r4 J
            pPlayerData-&gt;pNext = m_pFirstActivePlayerData;/ g- h  W" h6 [: a, U
            pPlayerData-&gt;pPrevious = NULL;* v0 J8 T6 e, g3 v# X
            m_pFirstActivePlayerData = pPlayerData;</P>9 u4 Z; A. e' X& [, E3 ?
    <P>        // Update count of players3 H( R* L0 E; r- F
            m_dwActivePlayerDataCount++;</P>
    : T: |8 X2 {! v/ [+ D5 D7 g<P>        // Generate the ID for this player: J+ K7 e6 J) ]' s. O
            m_dwPlayerDataUniqueValue++;
      d7 m4 U: v6 T, \        pPlayerData-&gt;dwID = (DWORD) ((pPlayerData-m_PlayerDatas)|(m_dwPlayerDataUniqueValue&lt;&lt;PLAYER_OBJECT_SLOT_BITS));</P>
    ) f) b# ?% s& L; Y% R  K$ d) L<P>        pPlayerData-&gt;pNextInIDHashBucket = NULL;0 g5 Y2 b; B/ E' @9 W: Y
            pPlayerData-&gt;NetID = 0;' q4 l& S* U, F" ~3 v
            pPlayerData-&gt;dwNumNearbyPlayers = 0;</P>  L% v* l2 l: ]5 j+ d, Q* I1 g
    <P>        // Insert into the "off-map" cell
    * E; R% F7 U' O, O! P: ?        pPlayerData-&gt;fPosX = pPlayerData-&gt;fPosY = -1;" T2 i1 v' i( ~! |* ~! D. O
            pPlayerData-&gt;wCellX = pPlayerData-&gt;wCellY = 0xffff;
    9 d& I7 U: @( u6 {        m_OffMapLock.Enter();
    ; G6 ^; ?9 Z, |) ^        pPlayerData-&gt;pNextInCell = m_OffMapCell.pFirstPlayerData;; g  `, q2 h3 W0 E/ Y
            m_OffMapCell.pFirstPlayerData = pPlayerData;& S4 u* V7 S, I9 R2 ?
            m_OffMapLock.Leave();</P>, y: D% L+ I+ a/ u& [9 N+ M
    <P>        // Mark as active
    9 b: U# R  |" Q6 `8 y6 U        pPlayerData-&gt;bActive = TRUE;</P>
    6 X! [( {0 b+ T! _  c0 n<P>        UnlockPlayerData( pPlayerData );
    ' F3 I% Q1 V9 A7 Y" z    }</P>8 X0 L5 V: D% l3 @' H6 X
    <P>    m_PlayerDataListLock.Leave();</P>
    3 Q" X' r: x4 k: j3 K<P>    return pPlayerData;
    & e" ~7 _6 X2 B7 G. h# x4 q) M}</P>2 W4 F' }( W4 `& W7 Y. A9 W. p( n/ s# J
    . }' j. B6 {% j) F2 B
    <P>
    ' v6 M( x9 F4 Q  {, w! A% X//-----------------------------------------------------------------------------
    7 x6 g1 ^4 Z& o7 v; L5 d// Name: ) l7 T, ]3 Z4 }' w
    // Desc: 9 S$ u8 z! T8 L$ J2 \9 x4 e& [0 H: m* n
    //-----------------------------------------------------------------------------; k. }3 C$ I2 f' j2 V
    void CMazeServer:estroyPlayerData( PlayerData* pPlayerData )7 a. E- H0 m$ t; `4 l* T0 u* _
    {
    1 z' T5 v8 ?* B6 b3 n. z- ?    m_PlayerDataListLock.Enter();& e' @+ L1 j/ z& m; Q" y8 g' x
        LockPlayerData( pPlayerData );</P>
    / p) d/ Y5 I0 U2 b4 c" |, W<P>    // Remove the player from its cell
    4 _2 H5 ~$ n! E- o' Q8 Z! _2 W, B    RemovePlayerDataFromCell( pPlayerData );</P>
      W& f( H) y  s( Y: I<P>    // Mark as inactive  @' ~9 N" k8 u  T
        pPlayerData-&gt;bActive = FALSE;</P>% }7 h3 |- M& ~1 \
    <P>    // Remove player from active list
    7 n0 Y; M; @* P# }/ y1 ^/ ^    if( pPlayerData-&gt;pPrevious )0 ?7 ?# l0 t3 F, k# g6 O, m+ X
            pPlayerData-&gt;pPrevious-&gt;pNext = pPlayerData-&gt;pNext;/ t- N/ ^; s2 q5 q0 f4 @
        if( pPlayerData-&gt;pNext )
    ) I( P( z6 z0 i8 G, `9 i        pPlayerData-&gt;pNext-&gt;pPrevious = pPlayerData-&gt;pPrevious;</P>
    . e# o# _5 c& M<P>    if( m_pFirstActivePlayerData == pPlayerData )
    ' H, a9 k/ W% T( @6 d+ m& H% O- c        m_pFirstActivePlayerData = pPlayerData-&gt;pNext;</P>) u# z1 x) X+ h9 S, [; I& P  i4 V: E
    <P>    // Add it to the free list
    - Q& b+ V# C9 `% s    if( m_pFirstFreePlayerData )
    9 I6 ?, |. W- Z7 Z8 O        m_pFirstFreePlayerData-&gt;pPrevious = pPlayerData;
    ( P5 _% r  b1 k# G$ j$ p0 x% w+ J    pPlayerData-&gt;pNext = m_pFirstFreePlayerData;, N: I% p2 N+ O- L9 y
        pPlayerData-&gt;pPrevious = NULL;
    4 J8 K" D' ?; V    m_pFirstFreePlayerData = pPlayerData;</P>
    1 l3 l. _' V7 q  J8 k<P>    // Update count of players  j- Q$ `2 u3 {7 o$ w
        m_dwActivePlayerDataCount--;</P>2 {  g- R7 Y. V5 i. o
    <P>    UnlockPlayerData( pPlayerData );0 \  P# a3 C. F& k, l: T
        m_PlayerDataListLock.Leave();0 D) D- X! O  _' F! u
    }</P>3 h. V6 `1 h6 Y0 @: t
    4 P- D% ]. Y9 y- B8 z$ e
    <P>
    ( q- f- Z2 U6 z; O* }2 F" v//-----------------------------------------------------------------------------3 D# k2 l1 I/ {
    // Name: * D1 w: p1 p3 C- h9 a
    // Desc:
    % t$ |! A& E: Y/ x8 o//-----------------------------------------------------------------------------
    4 i/ f9 m5 i3 I: U! U5 Jvoid CMazeServer::RemovePlayerDataFromCell( PlayerData* pPlayerData )
    ; y$ W; Z  m: x( f6 e8 U3 ?{
    ' G/ W3 E) Z6 M5 ^% }    // Lock the player3 x- m7 ^) N, {' P' _' F: ?- H- t
        LockPlayerData( pPlayerData );</P>
    8 I, Y$ ~: y5 D& d" S& e, W<P>    // Lock the cell the player is in$ ^0 A4 U8 V4 u; j; a: t, [
        ServerCell* pCell;$ `0 O# V# p5 s. g4 v  T1 a
        if( pPlayerData-&gt;wCellX == 0xffff )8 Q3 v0 b/ s1 S8 F" I
        {! X3 A; f/ S  M' b. ?0 @
            m_OffMapLock.Enter();
    * _* d4 N4 B8 y0 Q. `" d        pCell = &amp;m_OffMapCell;
    * y" Y# M2 W2 N- p1 K8 \4 I( w8 w4 b    }3 Y9 L- c; L' J
        else
    " j; U0 U' \4 ^" k9 d$ r1 P    {
    / j8 ], `0 T+ d- m* F) k+ |/ ~        LockCell( pPlayerData-&gt;wCellX, pPlayerData-&gt;wCellY );4 U# m! y& y# `& Y* |) e/ U& ^
            pCell = &amp;m_Cells[pPlayerData-&gt;wCellY][pPlayerData-&gt;wCellX];
    ) m9 [* ^7 i. D    }</P>; G2 ~6 ~; i" q( w
    <P>    // Remove it from the cell; b3 l1 Z; r% R4 d
        PlayerData* pPt = pCell-&gt;pFirstPlayerData;5 n: M  ^, k# c% n
        PlayerData* pPrev = NULL;
    ! b$ e9 H; ]& u( ^; n# ^$ s$ d( X    while ( pPt )5 F# {8 X  V% ]; J1 g
        {" a, i3 U5 ]; [1 F  Q" k) q
            if( pPt == pPlayerData )
    : s' f6 L8 n3 t        {* T0 d: T; b- m' P2 y
                if( pPrev )
    - U# {8 e$ y* }                pPrev-&gt;pNextInCell = pPlayerData-&gt;pNextInCell;
    9 o1 K) m/ {7 c; L            else$ t1 @$ h: |9 r7 u3 E' I; r
                    pCell-&gt;pFirstPlayerData = pPlayerData-&gt;pNextInCell;</P>6 c$ n/ k7 I% M1 F1 C
    <P>            pPlayerData-&gt;pNextInCell = NULL;' k* f( L) [1 h' j
                break;6 B& g7 z! |+ {8 Z8 p# q
            }1 x7 q, H4 M. x+ f3 ^
            pPrev = pPt;! X9 j+ c+ G$ j8 ~- }
            pPt = pPt-&gt;pNextInCell;
    4 E: s. H: Y* V: I2 c* y- Q8 L    }</P>
    2 Y4 {4 h4 F0 m/ ~8 _( u+ F- p& D3 _<P>    // Unlock the cell- t/ e& q/ V; w
        if( pPlayerData-&gt;wCellX == 0xffff )3 C+ h- V6 n2 }. d& g* z# n
            m_OffMapLock.Leave();
    9 G% Z9 o/ G  E- B6 a    else! N4 k" A% ]. B/ y, j
            UnlockCell( pPlayerData-&gt;wCellX, pPlayerData-&gt;wCellY );</P>
    7 }4 a6 B' G+ S4 Z3 Q" x' c<P>    // Unlock the player% ^% j5 C- F; A! D" K4 a) P+ Q$ V
        UnlockPlayerData( pPlayerData );
    ( B4 ?, f5 j: o9 t0 Z, X, n* y}</P>
    ) i( l7 O* M) {, q! ?+ K
    - J3 d$ S, o# p+ D# d<P>
    1 p. ]/ L: p5 u//-----------------------------------------------------------------------------
    4 T+ _7 E3 ^5 \8 l// Name: , D! J$ v6 i* w
    // Desc: : S' e* J" p4 C3 q  l
    //-----------------------------------------------------------------------------2 j  V, x. V3 i" q: a
    void CMazeServer::UnsafeRemovePlayerDataFromCell( PlayerData* pPlayerData )3 ?7 ^( T1 {7 G' H# K! I  D: j( Q* E: B
    {4 ?* [+ t+ m: C- U6 E# j
        ServerCell* pCell = GetCell( pPlayerData );
    6 ^8 {$ @& ?: k% J0 c    PlayerData* pPt  = pCell-&gt;pFirstPlayerData;, g8 y4 ]3 I2 H; {
        PlayerData* pPrev = NULL;
    0 b2 J; u8 Z+ l- u7 R. T) ?( [    while ( pPt )
    : |! t2 r$ V5 }0 O+ h& p1 Y    {, z6 Y  O% j4 N. S7 k- v) y
            if( pPt == pPlayerData )
    ; S# J9 g4 V7 t        {
    5 f$ B6 m" P6 h            if( pPrev )9 a/ i3 J) ~! C! I2 |4 @  {
                    pPrev-&gt;pNextInCell = pPlayerData-&gt;pNextInCell;% }7 A' Q  K/ b2 y0 q
                else
    % e# A: y- m  x% w( V+ Q                pCell-&gt;pFirstPlayerData = pPlayerData-&gt;pNextInCell;9 f4 m: s( R# o9 ?7 ?! C
                pPlayerData-&gt;pNextInCell = NULL;
    * w) u: A' b. ~6 g$ _- j            break;3 m% h8 F; M5 u( l% g6 G7 L$ m3 V$ N
            }! n# s+ Y3 F1 y2 o# G$ z! p
            pPrev = pPt;% W) u# |) A: h8 X& F* Q0 b& n( Z9 s9 S6 Z
            pPt = pPt-&gt;pNextInCell;6 a# [) o9 U$ l) n- ^
        }
    ! {2 O2 C" E& e: F3 b6 T8 Z, b}</P>& k% i  @, K, ~3 C4 X. f; x
    2 C: {" z% a7 D1 J. U( I  t
    <P>: _5 @2 ]: A% R0 `$ |4 W5 M4 @
    //-----------------------------------------------------------------------------
    * ?( \5 g4 s# i2 D+ c// Name:
    - d/ E- {, w" W2 i0 ?// Desc: , p( e$ z3 j  f, k2 Y" P, `- V
    //-----------------------------------------------------------------------------& A4 Z: y2 {/ }2 W4 ]' b
    void CMazeServer::UnsafeAddPlayerDataToCell( PlayerData* pPlayerData )
    # I1 I  e+ n2 v8 d- W, [{
    ; u$ R) j" k3 d$ [% k    ServerCell* pCell   = GetCell( pPlayerData );2 r& @" m5 ^3 R6 g8 w/ N( m
        pPlayerData-&gt;pNextInCell = pCell-&gt;pFirstPlayerData;" m3 }; h. G2 u9 H+ c) {
        pCell-&gt;pFirstPlayerData = pPlayerData;/ [3 `( _4 w) k( M. y$ f
    }</P>0 \9 E$ _) O+ `- X

    ' n& r  |2 U* T3 c, ~. T- `" A+ j<P>
    ' J1 s+ V0 J9 t/ ]! b( E& v//-----------------------------------------------------------------------------
    0 P" J1 i5 P: I8 a  @; c3 |// Name:
    ; R( \/ Q1 y0 K, S// Desc:
    * w* X& \( o* N/ P//-----------------------------------------------------------------------------) @! F" q6 n2 r# Z: r6 Z
    void CMazeServer::HandleClientPosPacket( DWORD dwFrom, ClientPosPacket* pClientPosPack )
    . j% f2 k5 ?5 u{
    4 t4 P# N6 S5 g( Z' m& |    // Grab player for this client and lock it
    + M9 p1 L3 d1 U% e* U    PlayerData* pFromPlayer = GetPlayerDataForID( dwFrom );
      r3 C, b$ B; h1 n( B( m    if( pFromPlayer == NULL )
    + v/ V, a7 s8 d0 _    {
    $ c0 R. C. R( S+ l! B        if( m_dwLogLevel &gt; 1 )* M6 T7 s) A9 a4 r0 v7 i% \
                ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Could not find data structure for this player"), pFromPlayer-&gt;NetID );5 P- d9 {) v: b% M# n+ V! o
            return;$ f- M  Y% ?3 a% L/ B
        }</P>/ A4 [& u1 M1 Y% S4 y1 I% N' U
    <P>    LockPlayerData( pFromPlayer );</P>- y7 J/ S3 Q$ O
    <P>    if( FALSE == pFromPlayer-&gt;bAllow ); H; Z; |4 D# c7 I( l
        {
    0 z5 c3 ^* J9 F* M& I3 R        if( m_dwLogLevel &gt; 0 )! \4 U6 R3 x# |7 {# u
                ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Got position packet from bad client.  Rejecting client"), pFromPlayer-&gt;NetID );</P>2 @( l8 E$ K# |; L' Q; t2 T
    <P>        m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );9 C. G5 w8 V, O7 `7 k+ }  ^
            UnlockPlayerData( pFromPlayer );/ C! ^0 ?- R* |/ f; z- N6 N6 t
            return;
    3 L8 h3 M3 _% j* x0 I    }</P>8 `3 d5 u3 M$ }, v! v0 w# l9 m
    <P>    // Compute the cell the player should be in now
    : @0 M" F7 X  n7 ]7 F    DWORD newcellx = int(pClientPosPack-&gt;fX);
    & W9 K" X& R; `/ H    DWORD newcelly = int(pClientPosPack-&gt;fY);5 p- L3 N/ j4 F( V5 S" C
        DWORD oldcellx = pFromPlayer-&gt;wCellX;- k: h. P$ `' k' b4 f5 e5 I: e
        DWORD oldcelly = pFromPlayer-&gt;wCellY;</P>2 D$ v/ v9 w4 t' l9 h# X
    <P>    // Have we moved cell?# {2 J2 V+ |+ U. D/ J- u% F
        if( newcellx != oldcellx || newcelly != oldcelly )2 z2 q9 ?0 z- L' v
        {" a/ C: A" a: ~1 B& H& g5 k
            // Yes, so lock the pair of cells in question
    * s1 K, x0 B7 a9 p1 L5 k        LockCellPair( oldcellx, oldcelly, newcellx, newcelly );</P>
    # T: x& Z' b  v  z<P>        // Remove from old cell and add to new cell5 k3 a9 n! ~& h2 {5 b, I
            UnsafeRemovePlayerDataFromCell( pFromPlayer );
    8 }! z+ u' i0 S$ X8 P, a        pFromPlayer-&gt;wCellX = WORD(newcellx); pFromPlayer-&gt;wCellY = WORD(newcelly);
    & B  q' }3 q8 a( d        UnsafeAddPlayerDataToCell( pFromPlayer );</P>& y& K+ c$ X! P' m, B& m( i
    <P>        // Unlock cells: x" ?0 j' ?9 ]+ H
            UnlockCellPair( oldcellx, oldcelly, newcellx, newcelly );1 H, g. r7 p; w& D3 j
        }</P>8 Y" l( ~) o0 d" ~2 @
    <P>    // Update player position  _+ c8 s- z( x: R* d
        pFromPlayer-&gt;fPosX      = pClientPosPack-&gt;fX;  L& J2 ~5 ]$ s1 ~3 Z2 J% c1 a6 ]
        pFromPlayer-&gt;fPosY      = pClientPosPack-&gt;fY;
    5 r+ ^6 g8 t% |( q' ]% O    pFromPlayer-&gt;aCameraYaw = pClientPosPack-&gt;aCameraYaw;</P>
    : r! H. i2 f3 N/ z1 h4 k9 i) \! L/ @  T5 Q+ H<P>    // Allocate space to build the reply packet, and fill in header * o1 K& l; _+ H/ \
        DWORD dwAllocSize;
    ( k! J2 o3 j* f    ServerAckPacket* pSvrAckPack = NULL;</P>+ d' A8 f; C5 K* T% W. l' t
    <P>    // Begin by allocating a buffer sized according to+ n9 b6 M" `' Y& g- A3 \
        // the current number of nearby players + 4.  This will give 2 c  s% f; p2 {4 N" \
        // a little room for more players to come 'near' without resize, ~  ~, N) h) b! q: B
        // the buffer.
    0 h8 [! d- i3 [- }( \) M    DWORD dwMaxPlayerStatePackets = pFromPlayer-&gt;dwNumNearbyPlayers + 4;</P>4 u/ W, w7 G' w
    <P>    dwAllocSize = sizeof(ServerAckPacket) + dwMaxPlayerStatePackets*sizeof(PlayerStatePacket);3 l7 v9 e2 U9 T# J0 p1 W, B' b
        pSvrAckPack = (ServerAckPacket*) realloc( pSvrAckPack, dwAllocSize );
    ' y, q2 H5 j6 r- D+ V    if( NULL == pSvrAckPack )
    8 W) i: q. n0 d    {8 Q1 x5 X  L+ r1 N' w
            // Out of mem.  Cleanup and return0 j3 P1 Z3 u( w2 p) u4 b7 ]
            UnlockPlayerData( pFromPlayer );, N8 Q. ^+ o6 D, X' A
            return;      
    7 a) w) S. U0 ], \. E3 m$ G    }
    % j2 J. U+ l5 Y+ Y& {6 [    ZeroMemory( pSvrAckPack, dwAllocSize );</P>9 e* A$ }: U  X6 o9 a; y
    <P>    *pSvrAckPack = ServerAckPacket(m_dwPlayerCount);
    4 Z. V7 g6 y6 E) f    pSvrAckPack-&gt;wPlayerStatePacketCount = 0;
    : I* C1 Z+ H2 `' j- A    PlayerStatePacket* pChunk = (PlayerStatePacket*)(pSvrAckPack+1);</P>( W# A: {: J& P; U8 ]) }* i1 \
    <P>    // Compute range of cells we're going to scan for players to send
    9 g7 F5 P2 a/ j    DWORD minx = (newcellx &gt; 7) ? (newcellx - 7) : 0;+ v% E! h0 W, Z+ g
        DWORD miny = (newcelly &gt; 7) ? (newcelly - 7) : 0;
    6 k3 M8 N" }3 x$ n    DWORD maxx = (newcellx+7 &gt;= m_dwWidth) ? m_dwWidth-1 : newcellx+7;
    ) u; a; ?4 Q1 B# B* `0 D/ m    DWORD maxy = (newcelly+7 &gt;= m_dwHeight) ? m_dwHeight-1 : newcelly+7;</P>
    " [; c2 k; n4 n. l7 v, p<P>    // Lock that range of cells
    . d( }! S: O7 N4 n    LockRange( minx, miny, maxx, maxy );</P>4 U' p& p: n& k# W0 o. t5 J
    <P>    // Scan through the cells, tagging player data onto the end of0 ^0 _; i: P$ i/ s8 P0 \$ C
        // our pSvrAckPacket until we run out of room, D% p% ~; ]" a
        for( DWORD y = miny; y &lt;= maxy; y++ )
      _# Y, d2 `% g/ G8 b    {
    5 V* i; t0 ?$ ]' V% I0 j% W        for( DWORD x = minx; x &lt;= maxx; x++ )( E) C' ^$ K* D, y
            {
    ) }8 w( B% L+ I( e, J& w            PlayerData* pCurPlayerData = m_Cells[y][x].pFirstPlayerData;
    1 ^% M1 s& `. W& x/ p0 F" m; n            while ( pCurPlayerData )
    : J) k- ^7 N  w% W            {
    ) k4 c  Y2 J; o                if( pCurPlayerData != pFromPlayer )
    4 w" |0 z1 C8 W3 W( A                {) h: I8 W4 H/ O/ v. ~2 G  I7 L1 j
                        if( pSvrAckPack-&gt;wPlayerStatePacketCount &gt;= dwMaxPlayerStatePackets )* w. @2 V9 o/ U
                        {; }8 H7 q! ~" v4 z( g' _% g% R
                            // Make sure pChunk is where we think it is( P+ I3 a; R3 q, J. u
                            assert( (BYTE*) pChunk == (BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket)) );</P>" L9 ^) o! c3 I; c+ X
    <P>                        // There are more than just 4 new nearby players, so resize the . r8 b% D% J* t( h& q# K9 |
                            // buffer pSvrAckPack to allow 16 more PlayerStatePacket's.
    % \6 L$ m8 i6 C, p1 J2 _% t                        dwMaxPlayerStatePackets += 16;
    ) K4 o  X+ V/ f9 ^# t7 s0 L, E                        dwAllocSize = sizeof(ServerAckPacket) + dwMaxPlayerStatePackets*sizeof(PlayerStatePacket);2 \: d* X8 k1 Z) I4 j8 J! J
                            ServerAckPacket* pNewSvrAckPack = NULL;6 Y/ e' H- e, `( Q
                            pNewSvrAckPack = (ServerAckPacket*) realloc( pSvrAckPack, dwAllocSize );& J, M% U& b& @1 x) \
                            if( NULL == pNewSvrAckPack )
    " A: l( q9 Z$ i' H' j5 M  j( Z                        {& h7 B6 D& K* y. z; B: {
                                // Out of mem.  Cleanup and return
    , q6 J! ?) U  F4 q7 D) A                            free( pSvrAckPack );
    4 u+ k8 B8 a; G2 @. B                            UnlockRange( minx, miny, maxx, maxy );
    ; s$ S: v4 @% }" S% e0 N! x                            UnlockPlayerData( pFromPlayer );7 k3 H+ z* R+ i5 \
                                return;       7 j8 U/ |+ T3 N. r% E
                            }</P>
    & _" g* M  L! W. h  E+ m$ e<P>                        pSvrAckPack = pNewSvrAckPack;
    6 t5 C4 S. N% B                        pChunk = (PlayerStatePacket*) ((BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket) ) );</P>
    . T& R6 d' ~2 r  b6 C' t<P>                        // Make sure pChunk is still where its supposed to be
    " D. M$ y3 f: E  k                        assert( (BYTE*) pChunk == (BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket)) );* K2 s2 q2 \$ W- H
                        }</P>7 V8 v$ [+ F9 y0 K5 s
    <P>                    pChunk-&gt;dwID       = pCurPlayerData-&gt;dwID;
    - v. K" S3 J7 w- |. a5 K% @                    pChunk-&gt;fX         = pCurPlayerData-&gt;fPosX;4 z( T  m# G+ ]$ }$ w; C
                        pChunk-&gt;fY         = pCurPlayerData-&gt;fPosY;: z0 M6 W) z* w( T5 L7 r, k
                        pChunk-&gt;aCameraYaw = pCurPlayerData-&gt;aCameraYaw;
    5 e0 N' `# j8 I9 N9 i5 u5 s                    pChunk++;% c( u$ c. a  O" ^% y  r9 i
                        pSvrAckPack-&gt;wPlayerStatePacketCount++;7 G( h! F2 d+ G% G$ N
                    }
    . G$ k. B8 [" u8 Y8 w* R                pCurPlayerData = pCurPlayerData-&gt;pNextInCell;
    . B- R6 Y3 e# ^' o            }
    - R8 _0 m0 X. y        }
    9 I2 j( q. u4 s0 l9 v    }</P>
    , P$ ~1 Z; u7 ]! O4 \<P>    // Update the dwNumNearbyPlayers for this player
    6 b9 g# j! w, s0 e9 b    pFromPlayer-&gt;dwNumNearbyPlayers = pSvrAckPack-&gt;wPlayerStatePacketCount;</P>- ^0 N4 o% H7 ?: O/ F0 ~
    <P>    // Unlock range of cells
    * E1 V5 C- n8 L& C# h! K- T    UnlockRange( minx, miny, maxx, maxy );</P>
    7 A  m$ O: _& g6 @; T. }<P>    if( m_dwLogLevel &gt; 2 )
    & p  n0 J( U' r+ v    {
    4 K9 e/ H! E" W" c" v        ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Position is (%0.2f,%0.2f)"), pFromPlayer-&gt;NetID, pFromPlayer-&gt;fPosX, pFromPlayer-&gt;fPosY );5 N  j" o% l) _( ~5 h6 M* R
        }! O8 T& i; H+ \0 X
        else if( m_dwLogLevel == 2 )
    6 r; I2 q7 N1 [& P/ m( x+ u% e    {
    + p  c# H/ f  R: g( ?- w        FLOAT fTime = DXUtil_Timer( TIMER_GETAPPTIME );# c6 v2 B4 f* Y, e1 O! J0 U
            if( fTime - pFromPlayer-&gt;fLastDisplayTime &gt; 60.0f )/ l+ c/ Z5 d& c; E) }) p) K1 `
            {+ R: i  O) K9 M1 w: Z4 M
                ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Position is (%0.2f,%0.2f)"), pFromPlayer-&gt;NetID, pFromPlayer-&gt;fPosX, pFromPlayer-&gt;fPosY );, z2 w2 R* O& Y& c
                pFromPlayer-&gt;fLastDisplayTime = fTime;- G; t' L' o# x8 S
            }
    9 d9 k9 g8 _; B1 ]    }</P>/ i- D% Z* C! S& X( Y2 G
    <P>    // Unlock the playerdata
    7 @9 k% `3 v5 p    UnlockPlayerData( pFromPlayer );</P>- ]- k" F1 `: p
    <P>    // Send acknowledgement back to client, including list of nearby players
    2 _9 y! s  b* {$ p/ m+ b    DWORD acksize = sizeof(ServerAckPacket) + (pSvrAckPack-&gt;wPlayerStatePacketCount * sizeof(PlayerStatePacket));
    7 ^. ^7 A+ h( H . R8 L  h; p, T5 \, F- c! q" Q2 {, F0 V
        // Pack the buffer with dummy data.
    " C8 V! I( K, e, R4 a- ^  f    if(m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex] &gt; 0)
    3 u4 c' n, y3 Z0 [, ~! Z1 V    {3 l- Y& @( j# `/ B
            DWORD   dwBufferSize = acksize + m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex];
    ' Q( p) f- @0 {9 l; O9 P0 q        VOID*   pTempBuffer = 0;</P>
    " v) K' B. f( r* ^% r/ r8 Y/ W2 `5 j1 N<P>        pTempBuffer = malloc(dwBufferSize);7 s( q6 G- d- h0 f. ?0 y7 }  \
            if( NULL == pTempBuffer )
    : o) p$ ^- ~6 k- i" c        {- {3 O% u2 r$ {5 c: c2 f
                //Out of memory
    ; }% a3 F6 C; y' G4 O            DXTRACE_ERR_NOMSGBOX( TEXT("System out of Memory!"), E_OUTOFMEMORY );& U0 F- b$ c- q! D5 t
                free( pSvrAckPack );! T; ?7 W- p* b/ p
                return;- O. _( G- o2 V6 A; j8 g
            }</P>1 w  Z* u4 m2 B, ^% L( g
    <P>        FillMemory(pTempBuffer, dwBufferSize, 'Z');
      P. f+ c- O& s% J4 y# b        memcpy(pTempBuffer, pSvrAckPack, acksize);</P>! `! C8 ~" K2 m- d9 j
    <P>        SendPacket( dwFrom, pTempBuffer, dwBufferSize, FALSE, m_dwServerTimeout );: n3 t6 x4 V2 u4 u' P
        5 K- J0 r( X" h1 l0 a# _' ]  P0 k
            free(pTempBuffer);1 O+ f6 A  H- A3 y
        }     a. h; w4 ]) J1 r) P+ H1 ~6 l- A
        else- D8 f- |& Q8 n+ T, ^* x7 y
        {
    9 B% A. f' ]4 `: c/ z" a. C        SendPacket( dwFrom, pSvrAckPack, acksize, FALSE, m_dwServerTimeout );
    8 J5 M3 r* k3 I8 d- s/ q7 {    }</P>
    3 V) t2 A, G! r6 z' \<P>    free( pSvrAckPack );</P>
    7 U2 j  R( [  c( p<P>}</P>
    ' l& f% l' e" W; v- I* m7 r+ l2 L+ b- `# d1 H' t% L
    <P>
    4 q% o+ O- m5 \3 m7 P8 D: P0 Z//-----------------------------------------------------------------------------
    1 P6 P7 z* L- I% t  p7 o& q// Name:   V* f7 N: W: b7 w# S0 A2 w) i
    // Desc:
    " ]) O' _2 ~4 E- t" ]8 Z//-----------------------------------------------------------------------------/ }0 ^' ^+ Y. l/ E
    void CMazeServer::HandleClientVersionPacket( DWORD dwFrom, ClientVersionPacket* pClientVersionPack )
    / y- U0 N" F; D% F4 P# x" I6 p3 @+ q{
      o& l* ]. G7 [" [8 @8 g$ v    // Grab playerdata for this client and lock it
      E, Y' N) d7 _* V7 w7 }( O0 s) o    PlayerData* pPlayerData = GetPlayerDataForID( dwFrom );
    4 [& k+ i  L; F. y! h  {    if( pPlayerData == NULL )
    * G/ f0 i/ J5 L! J! J/ |        return;! F3 Z9 D- X( C
        LockPlayerData( pPlayerData );</P>
    - P2 `( Q1 j3 N+ I% O( C<P>    // Record the version number ' V# O! G& f( C2 t0 t
        pPlayerData-&gt;dwVersion = pClientVersionPack-&gt;dwVersion;</P>
    8 D' u& S3 F0 M* N  ]5 m/ u( r<P>    if( m_bLocalLoopback )
    ! K/ [0 T) [  q& k, f        pPlayerData-&gt;bAllow = TRUE;
    ' s5 x( t; Y* X0 ], }- V3 i    else
    ' q5 V: _5 g3 e# G: ?; `        pPlayerData-&gt;bAllow = IsClientVersionSupported( pClientVersionPack-&gt;dwVersion );</P>9 h2 U8 W2 h8 L& Q# ~. g
    <P>    if( m_dwLogLevel &gt; 0 )
    $ O' D$ ?6 g0 o, d5 F- A        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>
    " B* K8 ~: G3 p& z9 H/ |<P>    if( FALSE == pPlayerData-&gt;bAllow )$ y; g& G5 A" h/ [% [
        {
    , ]' m, |! N/ V: Q        if( m_dwLogLevel &gt; 0 )
    / ?; g8 k/ F- P4 z3 F            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Rejecting client"), pPlayerData-&gt;NetID );</P>1 u6 _3 K1 K- q7 p% Q) V
    <P>        m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );
    . j5 @" ~% F1 d% g% E  J; W; X6 \( e        UnlockPlayerData( pPlayerData );
    0 a6 l4 g9 Q* P# M, H1 L        return;
    ) G7 M, l/ Z# a5 p1 ], \5 ?% @    }</P>
    6 n* Q' ?' P3 v) P) D" P3 @1 x<P>    // Unlock the playerdata
    $ G5 v$ w4 I0 U, d2 O- Q+ z0 u    UnlockPlayerData( pPlayerData );</P>
    1 h  i' H* G9 D; E- w$ N<P>    // Send acknowledgement to client that the client was either accepted or rejected8 n  z+ _+ U2 o8 Y
        ServerAckVersionPacket packet( pPlayerData-&gt;bAllow, dwFrom );# w- j/ _1 [- V6 \
        SendPacket( dwFrom, &amp;packet, sizeof(packet), TRUE, 0 );$ B, P7 Z8 L* n4 }1 ~3 T
    }</P>
      J, e2 y% `+ @! h9 i- t" }& d/ b
    <P>7 f) j2 G1 s( S4 k; A
    //-----------------------------------------------------------------------------0 f3 A! l# I8 t% @+ R$ C
    // Name: ; M6 T: X9 ~; s& c2 {% W
    // Desc: . L6 B8 q( G0 E% I# Q( u
    //-----------------------------------------------------------------------------% r/ A& ~, c) r. p& F) k- K
    BOOL CMazeServer::IsClientVersionSupported( DWORD dwClientVersion )
    + x& O4 m5 h1 [9 ^2 ?: I9 \, H{8 C! f, s# o5 k3 n" P. H# d# N7 K, n
        switch( dwClientVersion )
    5 ~: H, `' K6 }& x# b$ D8 _: b    {
    # _- L! \8 r+ D        case 107: // only v107 is supported
    5 T! X0 e* x  E3 i5 J7 R! [            return TRUE;2 V4 Z$ z$ I( Z6 R+ O. Z. e+ ^
            default:  L5 W/ v# ^2 D8 h
                return FALSE;
    , ?# E3 M* ?4 D+ A$ B2 p' C7 d9 @# r    }- c0 Y% Y  W; |  }8 U( u9 P0 V' c
    }</P>( j3 i) A" e* g( D! _

    . c5 U9 {: M" b& T<P>
    5 D! p0 D9 P- G, N//-----------------------------------------------------------------------------
    - ?* x: I+ [8 Q8 w// Name: * h9 W8 v4 e( K( o. W  y, B7 B
    // Desc: 9 g1 ~, ]& b2 C
    //-----------------------------------------------------------------------------
    & J( \1 E, c) A$ ?: jvoid CMazeServer::HandleUnknownPacket( DWORD dwFrom, ClientPacket* pClientPack, DWORD size )* ~, f, `) R- M7 y* \
    {: |2 V. D8 S, a8 ]
        if( m_dwLogLevel &gt; 1 )
    . _  z' b- m) N3 p& }' h        ConsolePrintf( SLINE_LOG, TEXT("ERROR! Unknown %d byte packet from player %0.8x"), size, dwFrom );</P>
    ! e- u, E  Q4 ?) X) z<P>    m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );& ^4 U( D# C1 l" y
    }</P>" Z9 k% ?! G& v0 W% h# v

    ! T0 i) E- x' V% E( T<P>
    - ]1 q9 m) {& }//-----------------------------------------------------------------------------: z  G- R9 ?3 T2 T0 N' q
    // Name:
    % Y: A) K" F3 @9 \" x# q! o// Desc: 9 k" q& y' h5 f3 Q! C# }1 h
    //-----------------------------------------------------------------------------% {/ \6 u! G7 Z
    DWORD   CMazeServer::IDHash( DWORD id )
    6 t8 `* n7 J& E, Z- Z$ B{7 v  T6 A* j  X
        DWORD   hash = ((id) + (id&gt;&gt;8) + (id&gt;&gt;16) + (id&gt;&gt;24)) &amp; (NUM_ID_HASH_BUCKETS-1);
    1 D/ p7 ]) e) J* ~0 d! f. j    return hash;% y3 g$ o5 y( S7 C
    }</P>
    # g0 K0 W. ^( U" Z6 h( [2 H0 F3 [% e4 d" k
    <P>% e$ g" q( O) C; k( `
    //-----------------------------------------------------------------------------* f2 ^4 W1 s0 \( }  i
    // Name: 6 U- h' j! _/ b& @9 q: F
    // Desc:
    % t7 m6 Y# c7 n+ j//-----------------------------------------------------------------------------
    0 r) U) [1 @$ U3 L. Kvoid CMazeServer::RemovePlayerDataID( PlayerData* pPlayerData )! U; Q1 r5 \( i
    {
    9 F& A: |4 Q7 L& V# J/ W    // Hash the ID to a bucket number
    . H7 C$ Y9 i7 G3 f9 p    DWORD   bucket = IDHash( pPlayerData-&gt;NetID );</P>+ t- l( C1 ~4 z  |0 P
    <P>    // Lock that hash bucket
    0 [1 j5 N! Y4 |; ?0 H  K    const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;
      f( ~1 w( c) T" ?  l    m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>' |" N# \( ?: Y% ~0 S0 D
    <P>    // Loop though players in bucket until we find the right one6 ]: j2 N; S+ I6 q% P
        PlayerData* pPt = m_pstIDHashBucket[bucket];
    + y; J! I7 t8 \9 _) i5 E8 ?    PlayerData* pPrev = NULL;
    ; p1 a8 o9 A! y    while( pPt )5 \8 j0 A3 l3 S9 Y3 ^3 F
        {
    8 h1 q6 B$ f& W) |: S4 {        if( pPt == pPlayerData )% @" h3 k! r6 v( Q1 x9 [4 r
                break;5 G. Z) @- ?  f' R6 l
            pPrev = pPt;
    & X$ ]( l1 U1 \/ y/ T" @! R        pPt = pPt-&gt;pNextInIDHashBucket;
    ' ~' z$ L: h/ h- ], _: C7 h    }</P>6 l) h3 h- q3 `. g: L
    <P>    if( pPt )
    4 V. i, i" B9 `, j    {/ v& H0 Q1 T+ p- I! B# L9 b6 x. }
            if( pPrev )
    ' O2 ]4 \- n  l" S) V            pPrev-&gt;pNextInIDHashBucket = pPt-&gt;pNextInIDHashBucket;  R6 @# O* e- z& [+ l7 C2 i
            else2 ~& O9 n. i0 p; u7 f$ q; J5 D: G( J
                m_pstIDHashBucket[bucket] = pPt-&gt;pNextInIDHashBucket;
    % l7 h( z6 Q! p( {' E% s7 _0 m        pPt-&gt;pNextInIDHashBucket = NULL;
    8 t$ D5 b7 x, [2 Z. E6 d1 N    }</P>8 h9 x2 Z5 l# y7 a& p; u7 F
    <P>    // Unlock the hash bucket
    9 [  ~( X/ I  R4 E    m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();
    ! l9 c1 Z) a6 _: v}</P>0 M, B3 x: \' n: t. i0 v& r
    * o6 D% J. W. }8 m' g: N8 U0 U
    <P>
    , ?% k! K1 ^+ B- x7 q//-----------------------------------------------------------------------------
    $ i+ `8 ?2 }8 {0 a// Name: " l; e5 i0 `$ |  c' g
    // Desc:
    6 t  A3 J: O6 F4 P//-----------------------------------------------------------------------------# A9 ]! \7 y: I
    void CMazeServer::SetPlayerDataForID( DWORD id, PlayerData* pPlayerData )
    6 [, W; t' k$ P# r, m6 x$ |{
    1 O2 g4 \- t9 O( r+ ?: V( {    // Make sure this player isn't added twice to the m_pstIDHashBucket[]0 ~( q, m$ B& N# h3 m; Q0 Z
        // otherwise there will be a circular reference
    # o! v) G( g. q! t6 F* a+ A$ v  V    PlayerData* pSearch = GetPlayerDataForID( id );/ l3 k2 D0 z4 G8 s
        if( pSearch != NULL )
    / [( B) e. G9 h  X+ Y8 t        return;</P>  j! U4 ?+ u/ y0 q2 n/ ]
    <P>    // Hash the ID to a bucket number
    % D2 x( w# b: ^  }$ y0 t% \: U    DWORD   bucket = IDHash( id );</P>! l1 L& s3 u4 A. t/ W
    <P>    // Lock that hash bucket
    , {! b' M) _+ m* _    const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;
    . G0 }1 p! B$ T. z$ D- P/ _    m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>/ A: k1 ^: m' S' X6 t" K1 r( k
    <P>    // Add player onto hash bucket chain
    2 ]# r% a3 f  u: e3 G    pPlayerData-&gt;pNextInIDHashBucket = m_pstIDHashBucket[bucket];2 @8 A% X5 x" w/ t% ?0 J- {
        m_pstIDHashBucket[bucket] = pPlayerData;</P>
    ) \  T2 `* ]' N4 o) q$ @& m<P>    // Store net id in player0 A& f' W; |: ]) _; Z
        pPlayerData-&gt;NetID = id;</P>
    : n4 x# g/ b) S7 q& W* `<P>    // Unlock the hash bucket
    + M6 k0 g& j( o    m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();  F+ ?( k0 T9 ~8 G5 E! J
    }</P>' y8 b# r+ |% s7 `6 t/ N
    - n9 m$ E$ s8 \
    <P>% P' E* j% o$ e# t# H3 t
    //-----------------------------------------------------------------------------/ b, p# x3 ~( V# z
    // Name:
    0 F. ?) M* ?. D: m  b4 A! {// Desc:
    - N0 M' h1 L" j  S: x//-----------------------------------------------------------------------------
    ' p8 s8 Q' _5 n% v6 C' {% C) }4 a5 vPlayerData* CMazeServer::GetPlayerDataForID( DWORD id )! S' o; e5 _5 }) n
    {  {$ ]. I) {) a1 C1 Y$ N( Z8 |! U9 V! }
        // Hash the ID to a bucket number$ l$ j- f3 F9 @% ]# @4 ^
        DWORD   bucket = IDHash( id );</P>
    ( K5 J( }# C8 K2 v( q% X& _/ n<P>    // Lock that hash bucket
    ) T# W0 [: S3 V8 _' A    const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;' W5 |, V: i5 j$ k
        m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>
    , }' {" S2 b) V2 X' q# J<P>    // Loop though players in bucket until we find the right one
    % O/ _* _& L+ X; ^    PlayerData* pPlayerData = m_pstIDHashBucket[bucket];
    6 B: _" z/ J( B$ V( E; h+ a    while ( pPlayerData )/ V/ B# B7 K4 ?% {
        {0 l% Z9 B3 G. {+ ]* `8 k
            if( pPlayerData-&gt;NetID == id )0 o7 B, M/ {" E  K8 E0 W& D
                break;4 d* D( g  }: h, v+ q4 @2 C: ]* {# g
            pPlayerData = pPlayerData-&gt;pNextInIDHashBucket;+ p' I3 U8 H+ I( t
        }</P>
    # _9 v2 _1 o9 l- q8 ]% `<P>    // Unlock the hash bucket
    0 N1 I# m5 ]1 c0 x8 C    m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();</P>
    # {  H" I8 X7 K5 U<P>    // Return the player we found (will be NULL if we couldn't find it)1 ^: u! R  T- `  ~
        return pPlayerData;; f/ ~! k& p" T5 Y
    }</P>
    - R' h  z: @( f$ e9 g8 z4 [$ X' w3 y; t. D$ w
    <P>
    . j- n7 \% w6 I9 ~+ M- W! C//-----------------------------------------------------------------------------( x0 F- d0 \; U. |6 ~/ a
    // Name:
    6 o/ k) |1 b( p' \: f. A9 P. v" b! I1 l// Desc: calls DisplayConnectionInfo for each connection in a round-robin manner- N3 m  o8 `2 l6 s2 l) s$ T8 \
    //-----------------------------------------------------------------------------: E9 q! t1 B( m3 j3 @/ Z6 |
    void CMazeServer:isplayNextConnectionInfo()
    . S8 d' ?  y, s- V* e; R{, Q8 f, x4 @- M2 C3 ~
        if( m_pNet )
    9 E- n6 ~! A' J4 s    {
    , y2 Z; E' T; t' b; s        // Find the player that was displayed the longest time ago, and display it.* P4 w; }" d; a0 {) T$ Q
            FLOAT fCurTime = DXUtil_Timer( TIMER_GETAPPTIME );
    : g: p$ H0 L( H* D+ t, J; E/ |        PlayerData* pOldestPlayerData = NULL;
    , ?) T, Z: \3 ^' F0 W7 d5 Z( W- `! |6 k        FLOAT fOldestTime = 0.0f;</P>* G& v3 x4 B, u! O6 ~
    <P>        m_PlayerDataListLock.Enter();</P>
    1 G6 W8 u, c3 x- ^; p( D* X( X<P>        PlayerData* pPlayerData = m_pFirstActivePlayerData;0 s) P" N1 z2 ~5 T% W, e+ p
            while ( pPlayerData )2 P: s, ?: i( D0 {
            {- h7 h* [- _# i0 Q3 l
                if( fCurTime - pPlayerData-&gt;fLastCITime &gt; fOldestTime )
    / e/ F+ d8 V0 |. n# N( r5 H            {' \  a( I2 e7 v+ {1 o
                    fOldestTime  = fCurTime - pPlayerData-&gt;fLastCITime;; k& f* S0 M1 n3 K5 u
                    pOldestPlayerData = pPlayerData;  O4 W/ C/ f0 Y& z9 H% M! X
                }</P>
    7 [# d6 {; o  R6 M0 F3 z' g0 N& i$ p5 }<P>            pPlayerData = pPlayerData-&gt;pNext;
    , L  i* e' n7 g        }</P>
    ! [0 ?+ T7 ^# J7 g( \1 `<P>        // Display the player with the oldest CI field, and update its CI field.
    ! V9 K4 s+ P+ }  ~6 s2 D5 j        if( pOldestPlayerData )
    " W) C- i5 g  ~- D5 G        {+ w. y5 \5 n. O5 D% b5 E
                ConsolePrintf( SLINE_LOG, TEXT("Displaying connection info for next player") );
    6 |6 i- v! g$ y& w. K4 |: I            DisplayConnectionInfo( pOldestPlayerData-&gt;NetID );0 q/ d3 V4 e3 v. H2 E( |
                pOldestPlayerData-&gt;fLastCITime = fCurTime;$ ?* I, L! b4 x* _; |# t' i
            }- U% D6 @1 f6 l5 f$ ]
            else- P" r" C% O$ e3 }" F0 }4 K. X1 L
            {
    9 ^$ J3 L$ ^  L  J( i' t2 w$ d7 n            ConsolePrintf( SLINE_LOG, TEXT("No players found") );
    6 Q" B1 P7 u( V' B; E# L/ w9 M        }</P>
    1 e1 B0 \$ Y) |5 n# G. ~6 M# z* I<P>        m_PlayerDataListLock.Leave();
    / F7 N8 s) |9 m  m% m' J    }
    # o- B  O5 s* d% S* x) E' j7 T, e}</P>- t. X& H1 \8 s9 E7 Y* z* |4 F

    $ \8 E7 f. l6 a1 r2 ~) y% {/ k<P>) J6 V% V+ n4 e$ K# \* i! Y7 Q( i' C
    //-----------------------------------------------------------------------------
      b% `/ Z% _$ T// Name: $ y1 u4 u7 [$ j1 G
    // Desc: 2 X, Z; a/ C7 D6 V
    //-----------------------------------------------------------------------------
    . D  @' e5 X. Qvoid CMazeServer:rintStats()8 b* G* d/ e1 G) A3 f+ x
    {' A4 |6 \3 \0 k7 y' g9 z
        ConsolePrintf( SLINE_LOG, TEXT("Thread count: Active=%d Avg=%.2f Max=%d"), ( Q, ^8 ]# T9 o
                                        m_wActiveThreadCount, m_fAvgThreadCount, m_wMaxThreadCount );) c# Y4 w' n8 V, r% @- ^; X
        ConsolePrintf( SLINE_LOG, TEXT("Thread Time: Avg=%.4f Max=%.4f(s)"),
    8 h( r! }! p/ h3 v                                    m_fAvgThreadTime, m_fMaxThreadTime );
    " e1 b6 w# T1 G5 b    ConsolePrintf( SLINE_LOG, TEXT("Players online (not including server player): %d"), m_dwPlayerCount );
    3 G; n* B* W" g6 y# d9 h    ConsolePrintf( SLINE_LOG, TEXT("Peak player count: %d"), m_dwPeakPlayerCount );
    , Y5 w& U* T5 [9 ~# a' n}</P># S: @# J9 v) y: k$ A' f3 T

    8 P( t0 G: |$ e& U<P>; a3 W2 C$ g8 _: ^: c( B$ m
    //-----------------------------------------------------------------------------
    : `" x4 i! ~7 J+ G2 p// Name: : D" z6 O! c% E2 f: c6 h2 P
    // Desc: . u" ~( O6 _8 F
    //-----------------------------------------------------------------------------
    4 j/ [3 ]# l$ d; E% yvoid CMazeServer:isplayConnectionInfo( DWORD dwID )- [/ y9 ?. U! m
    {9 r: D/ M, h& I" ?2 f, `4 r
        TCHAR strInfo[5000];
    0 m8 H0 J  r6 t$ x5 R    TCHAR* strEndOfLine;+ R0 t  ]2 C0 @5 C0 u2 }* ]
        TCHAR* strStartOfLine;</P>6 L" h! w$ x7 O( ~) G# j
    <P>    // Query the IOutboudNet for info about the connection to this user
    3 I; i& d! _( V% Q    m_pNet-&gt;GetConnectionInfo( dwID, strInfo );</P>
    ; P8 A8 l2 @! T2 o/ N5 @<P>    ConsolePrintf( SLINE_LOG, TEXT("Displaying connection info for %0.8x"), dwID );; z8 H; f, o" b# M$ x0 K
        ConsolePrintf( SLINE_LOG, TEXT("(Key: G=Guaranteed NG=Non-Guaranteed B=Bytes P=Packets)") );</P>
    - `6 A. I% o/ v' C& `8 v& D<P>    // Display each line seperately
    # H0 ?: r1 h' o  x    strStartOfLine = strInfo;' i# G+ [1 ]+ x- b$ R7 _  L
        while( TRUE )7 ^4 y, e! G5 f7 z5 t& k
        {( B0 @' {% d7 ^$ |
            strEndOfLine = _tcschr( strStartOfLine, '\n' );! `4 J, v6 E4 D% R; x" B& r2 C+ x
            if( strEndOfLine == NULL )! Y$ G1 @. _; I+ G
                break;</P>
    ) d4 T+ L5 g0 k<P>        *strEndOfLine = 0;
    2 t  ^2 s% J4 V+ L$ T, X0 t( T        ConsolePrintf( SLINE_LOG, strStartOfLine );, t$ x( F' {% \$ w+ ^$ Y7 M9 j
            strStartOfLine = strEndOfLine + 1;+ |/ a7 P+ s7 H/ x! ?1 R1 |
        }
    2 ]7 b: W  G1 g, y* K}</P>
    , ?& v6 \& A' F  e* ^0 x7 h. v1 K. Q) f. c5 y
    <P>6 Z6 K! y5 [: ^8 b! `, S
    //-----------------------------------------------------------------------------
    - h  T. @% G" `// Name: # J5 Z4 u1 G: d! z4 E/ F
    // Desc:
    ) G5 \( U/ l( Q8 H( m//-----------------------------------------------------------------------------
    ( \& T# x, m4 c1 ]& |0 C; dHRESULT CMazeServer::SendPacket( DWORD to, void* pData, * Q6 D' H1 o" W1 f; R& w1 H
                                     DWORD size, BOOL reliable, DWORD dwTimeout )
    ) s+ q3 s0 w1 ~1 m$ {8 E{
    ( }+ R/ P* I& W( p    // Chance of forcing any packet to be delivered reliably
    - Z0 \5 J; G( b  x    if( m_Rand.Get( 100 ) &lt; m_dwServerReliableRate )
    ) n8 e# |+ |8 R- t! S+ p" z1 r        reliable = TRUE;</P>1 r  z; `8 S: L0 x$ r7 I
    <P>    return m_pNet-&gt;SendPacket( to, pData, size, reliable, dwTimeout );" @5 h- o$ `2 N1 D' w" ~& u
    }</P>1 ~/ }2 H- W; z* n. z2 E

    8 |3 h+ A) h  w/ a) I2 q, B5 H<P>
    " K- R* U3 ^( ]8 R& O9 @* C2 K//-----------------------------------------------------------------------------4 p; T9 T/ V0 B* F+ }
    // Name: 4 N/ T( R4 N& S, p# Q
    // Desc: 4 f7 w7 I3 ]" _# c5 e/ }, P
    //-----------------------------------------------------------------------------! ]7 K/ c$ j, z2 p/ W. n
    void CMazeServer::SendConfigPacketToAll( ServerConfigPacket* pPacket )
    $ G2 \8 H- h( p* R* w: _{# _# A' |$ b0 h8 q6 @/ h1 v
        // If we're up and running, then send this new information to all clients
    , _  V% M6 z( S. z) P    if( m_pNet )
    " \7 t1 A9 E  V8 E$ v# w    {
    + S1 U: B# |" _/ F        //Use the AllPlayers ID
    , V4 r. r, W9 ]9 r        SendPacket( DPNID_ALL_PLAYERS_GROUP, pPacket, sizeof(ServerConfigPacket), TRUE, 0 );, L! n' Z/ x/ Y# |/ b$ R
        }
    9 ^! P( Z6 R2 H9 \7 ~; k; |7 U}</P>2 B7 M/ Q, I3 x' a
    4 A, F/ W% b. {$ ]" B
    <P>% q/ r3 \6 Y* Z9 ^' M5 I: c
    //-----------------------------------------------------------------------------
    . S4 N) x' B0 B+ t( C0 v' j// Name:
    5 e2 D3 x: e2 i$ i- R. z// Desc: ) X1 B. e/ v2 C
    //-----------------------------------------------------------------------------
    . _! [( j+ N) |& qvoid CMazeServer::SetClientReliableRate( DWORD percent )
    * T; p" j+ u  m- b0 ?: G{& f. B3 o+ j4 J6 g0 a
        // Update client config, and build packet containing that data
    8 T& q$ _7 u: O9 x    m_ClientNetConfigLock.Enter();- C7 {/ O4 W' a* q: r
        m_ClientNetConfig.ubReliableRate = BYTE(percent);
    . u0 k  D) P" g. a9 e, [, P( K+ R. u    ServerConfigPacket packet( m_ClientNetConfig );& _* I; O: P$ i" R
        m_ClientNetConfigLock.Leave();</P>
    ; E) R" A* h, o' D$ Z<P>    SendConfigPacketToAll( &amp;packet );; Z2 ~2 r# L0 N% _2 P9 ~! C
    }</P>" p  |# l8 E& b$ L1 M5 g
    0 Z# S& Q7 F7 B8 {
    <P>; b$ e, N" b* i4 [/ E8 x
    //-----------------------------------------------------------------------------% H- [# h, b' d' V( ~3 T$ \' G: @
    // Name:
    " W! {2 G; f8 i. J2 M/ W( W" E// Desc: . r9 p7 ~, P9 K
    //-----------------------------------------------------------------------------
      l% N- y( {& {  b4 Lvoid CMazeServer::SetClientUpdateRate( DWORD rate )% e- ?" i' h6 u3 h) R/ T  n
    {
    6 o" {( [* c' n: a, |/ R. i: p    // Update client config, and build packet containing that data3 y8 A; F$ O/ e( Q/ w/ p, B: u
        m_ClientNetConfigLock.Enter();
    - q& u5 t0 J9 q+ l6 O2 p    m_ClientNetConfig.wUpdateRate = WORD(rate);. C, m- b+ `( q8 L& h
        ServerConfigPacket  packet( m_ClientNetConfig );' X& D) C5 U9 c8 [% q* D
        m_ClientNetConfigLock.Leave();</P>
    ' K4 B2 Z5 Q& w. o<P>    SendConfigPacketToAll( &amp;packet );7 {% R- y' g2 S* s( |
    }</P>6 {& K. {# G( m# h8 p
    $ d; R# m( C; G. p; d; w4 p
    <P>$ J0 H( n& N+ j9 B+ L, t# ]5 \/ [: S
    //-----------------------------------------------------------------------------
    9 M( `7 I. _7 J1 i2 B// Name:
      E; \+ ?3 `: K2 F4 l  l// Desc:
    $ `: R5 q4 \; T0 A( m//-----------------------------------------------------------------------------
    / R1 n: W& |- Wvoid CMazeServer::SetClientTimeout( DWORD timeout )' C+ f& x1 g; v! ^& ~/ R1 i: t3 P
    {) E9 N6 n: G8 W! n! l  X
        // Update client config, and build packet containing that data* X$ r$ o" _4 W4 c. [# H
        m_ClientNetConfigLock.Enter();
    + _- D4 K3 V; b# o    m_ClientNetConfig.wTimeout = WORD(timeout);  |* w5 A+ R2 w  x
        ServerConfigPacket  packet( m_ClientNetConfig );
    * d* Y7 E6 f% C/ m! u* L! ?    m_ClientNetConfigLock.Leave();</P>
    8 W! c' o: i; i* B0 c<P>    SendConfigPacketToAll( &amp;packet );$ [( u% Q0 h4 t9 x' }8 B; o9 \
    }</P>4 M4 @6 |4 w/ b) j

    2 K& a/ s% L6 O3 w; K  k<P>
    . T6 A  k9 t) N- i( D& Y//-----------------------------------------------------------------------------
    6 E3 D7 }/ ^) J// Name: 0 k6 s& R7 I7 Z2 h% q' C
    // Desc: - `) l" H3 W1 ^, N1 O
    //-----------------------------------------------------------------------------
    7 J3 l8 Q' {" D  N7 [. s. }void CMazeServer::SetClientPackSize( DWORD size )
    0 o* J. m3 e2 E{) R% p3 X, Y$ I. c# g7 p& I# P7 c
        // Update client config, and build packet containing that data: }# D$ y: c0 [4 r0 X2 e  Y5 m8 C. N* _
        m_ClientNetConfigLock.Enter();
      b3 ], f& i6 {7 U/ V- x1 x* g   
    + O+ G% e, Q# m. [, T( C. Z3 A    m_ClientNetConfig.ubClientPackIndex++; //Increase index and verify location in array.
    1 Z/ A' U( M+ z6 r. R    if(m_ClientNetConfig.ubClientPackIndex &gt;= PACK_ARRAY_SIZE)   
    - }% C- `5 l+ N7 L0 D& p, k8 Q        m_ClientNetConfig.ubClientPackIndex = 0;</P>
    3 _' r% Y! t* A: t. i  H+ a/ _<P>    m_ClientNetConfig.wClientPackSizeArray[m_ClientNetConfig.ubClientPackIndex] = WORD(size);
    * x" D4 W, ^* v3 t6 Z9 i8 f: j$ {    ServerConfigPacket packet( m_ClientNetConfig );
    1 M( ^, M) X. H. m; Y    m_ClientNetConfigLock.Leave();</P>
    6 |1 \8 |4 q4 K' i0 K: [<P>    SendConfigPacketToAll( &amp;packet );) x* A2 v# b/ [3 n, p5 H4 F% E
    }</P>
    + v2 ]& ^+ H# k1 w
    ; N- n2 x+ b6 j& c" L* e. ]& j<P>
    $ u1 t6 R' w( B9 ?//-----------------------------------------------------------------------------
    % j: s  L7 B% H: f+ a2 f// Name:
    0 o# ~0 A& r/ L5 U2 j) E// Desc: , b1 u& B$ P& @1 t
    //-----------------------------------------------------------------------------* V) _- {- z$ l  r6 X) K
    void CMazeServer::SetServerPackSize( DWORD size )! ]: u- P$ Q% [# @, e; K+ _
    {6 n+ F# I1 m5 I, z' A* k
        // Update client config, and build packet containing that data
    8 H! f  g. [+ a& N9 w  n    m_ClientNetConfigLock.Enter();' h; r+ c8 [$ ?% I4 d4 X/ D* E
       
    " V7 {: F$ \1 D  ?    m_ClientNetConfig.ubServerPackIndex++; //Increase index and verify location in array.# q8 g, Q) S$ c1 ^" W% \
        if(m_ClientNetConfig.ubServerPackIndex &gt;= PACK_ARRAY_SIZE)   
    + s+ o  k( O6 l& H        m_ClientNetConfig.ubServerPackIndex = 0;</P>. a# A, C0 e3 f# h/ ~' F, O
    <P>    m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex] = WORD(size);$ }; f' z! C- g5 l# w
        ServerConfigPacket packet( m_ClientNetConfig );7 f- [. y5 z# ?7 N2 ]6 H
        m_ClientNetConfigLock.Leave();</P>
    1 x6 k5 r- ?* X4 p4 d( p+ R% i<P>    SendConfigPacketToAll( &amp;packet );
      X( `: w5 C. A9 x# |2 X4 ]}</P>6 r( b5 O' [4 _! b+ Q) x' Z
    <P>9 Y! x4 f$ _4 w0 G) r( t: P
    //-----------------------------------------------------------------------------
    ( n% {# p) p' y# g8 y4 p// Name: # `; w1 n' N' \4 R
    // Desc:
    4 w. D* ~& M- g8 E1 T7 z) N1 Q//-----------------------------------------------------------------------------# q: A8 g$ M. \1 O) c- B
    void CMazeServer::SetClientThreadWait( DWORD dwThreadWait )
    6 Y0 B: v: j4 X2 k{
    ' ~( B, g* V6 a    // Update client config, and build packet containing that data
    ! v0 D- L3 u5 H. S: C: ?6 i+ D    m_ClientNetConfigLock.Enter();
    * w$ H. n- L( _% o2 R* V% _8 x    0 X0 j8 l* p! M% t: s$ K+ T
        m_ClientNetConfig.dwThreadWait = dwThreadWait;
    / x* N; x, E9 S2 P4 }8 N    ServerConfigPacket packet( m_ClientNetConfig );# c2 X5 A$ {3 N: W
        m_ClientNetConfigLock.Leave();</P>
    . R" W8 c! V- B% x<P>    SendConfigPacketToAll( &amp;packet );
    9 d% J; n; Y. Q3 s3 x}</P></DIV>
    zan
    转播转播0 分享淘帖0 分享分享0 收藏收藏0 支持支持0 反对反对0 微信微信
    您需要登录后才可以回帖 登录 | 注册地址

    qq
    收缩
    • 电话咨询

    • 04714969085
    fastpost

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

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

    蒙公网安备 15010502000194号

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

    GMT+8, 2026-6-11 12:15 , Processed in 0.313784 second(s), 51 queries .

    回顶部