数学建模社区-数学中国

标题: [分享]MazeServer源码示例 [打印本页]

作者: ilikenba    时间: 2005-1-31 11:52
标题: [分享]MazeServer源码示例
<DIV class=HtmlCode>% W4 g' {/ J0 B5 w9 x
<>// File: mazeserver.cpp- E+ e2 f  @, {
//
. @! s0 q& I: g+ m+ e// Desc: see main.cpp
- ~& l+ d5 C4 }) T//8 C# b, Y+ S) ^1 N6 Y
// Copyright (c) 1999-2001 Microsoft Corp. All rights reserved.
9 ?* I# _8 [# y& p) m' D+ v//-----------------------------------------------------------------------------0 @+ a, T5 E5 Q  {
#define STRICT$ n' Z) u; S& ]0 _# @# e0 B, L
#define D3D_OVERLOADS( e4 o6 Z6 m. K2 P
#include &lt;windows.h&gt;& \# ]5 d- K4 I" l
#include &lt;d3dx.h&gt;
# y7 g0 }4 \% ?; u3 i: t#include &lt;stdio.h&gt;
4 x+ n7 t9 [2 ^; w3 F2 K#include &lt;math.h&gt;
# a8 v# ~) C' J: f#include &lt;mmsystem.h&gt;
& f" f; ?5 ?# ?1 o: i. G1 O) U' d3 Q#include &lt;dplay8.h&gt;2 F- D5 b7 ~6 N) L: i
#include &lt;dpaddr.h&gt;
/ ~* U4 }8 Y' ~#include &lt;dxerr8.h&gt;1 I6 ^. r% o& S3 ]* U; h3 g
#include "DXUtil.h"' M8 N: C) S5 |+ C9 \1 T; n
#include "MazeServer.h"
8 i3 O$ ]& Q7 k#include "ackets.h"
4 t. T( C! p5 z# s5 V; ~. v#include "Maze.h"# G2 E( o( Y  Z7 k! W- t( q0 U
#include &lt;malloc.h&gt;
0 M, X* Q4 k0 N4 F#include &lt;tchar.h&gt;</P>7 J5 N/ Y+ O/ q( Z/ Z/ X  w- w
3 c/ d. e9 D( Z. ~8 Z6 Q
<>//-----------------------------------------------------------------------------0 ^4 |/ F' u1 W; c4 L: m& a
// Name: . f0 U/ }  r6 M! ~
// Desc: * C' H* Z1 O# M  e
//-----------------------------------------------------------------------------* f% f& c$ `/ g$ `
CMazeServer::CMazeServer()! v" l  n' M  r! W. U
{' ^' g2 J+ d8 H) I) G1 J& X; C
    m_dwPlayerCount         = 0;
/ m( j* N! ?# c4 M   
4 n- j0 w% S7 O& ?    m_wActiveThreadCount   = 0;/ H8 x- x) r1 R7 A
    m_wMaxThreadCount      = 0;
" Z$ R- p' i8 ~* [1 p9 Y/ t) l    m_fAvgThreadCount      = 0;( G+ H0 U6 N- y2 j  @- P8 i
    m_fAvgThreadTime       = 0;
$ h% ?& l" ^, s" [    m_fMaxThreadTime       = 0;</P>
  R" U6 l- m  R1 M1 m<>    m_dwServerReliableRate  = 15;( K+ Y) @2 w( a$ I+ h" Q
    m_dwServerTimeout       = 150;
2 A, }  T. B( _, ?, K    m_dwLogLevel            = 2;) \# |" L2 i' f! p& C; h. l
    m_pMaze                 = NULL;</P>
1 M- {0 k; E0 e8 L% M<>    m_ClientNetConfig.ubReliableRate = 15;0 Q2 e5 F- U- K5 y
    m_ClientNetConfig.wUpdateRate    = 150;
0 u9 z" ~; X4 ]. }1 m    m_ClientNetConfig.wTimeout       = 150;</P>
- N% f: i2 Q" S$ ^7 ~<>    m_ClientNetConfig.dwThreadWait = 0;</P>
7 B4 J9 Z1 i* I$ g. k<>    m_ClientNetConfig.ubClientPackIndex = 0;
$ r! I" h# [5 T  N2 k: ~1 Z( s    m_ClientNetConfig.ubServerPackIndex = 0;! T- G. Z) ?6 B4 v2 `7 U
    for(WORD x = 0; x &lt; PACK_ARRAY_SIZE; x++)( c# s' d  H; |" d2 A9 a1 D1 b
    {5 C9 D; R% x. _) y" ?
        m_ClientNetConfig.wClientPackSizeArray[x] = 0;' K5 k7 p  X$ z6 I; c" K
        m_ClientNetConfig.wServerPackSizeArray[x] = 0;
+ a  h4 N3 `# d' I( w    }
6 {$ l0 F, j6 P$ r}</P>
: c' s7 D: ~3 C: Z2 G
2 Y' |; P' _6 ]9 g<>. P  v6 c' i& p/ u  u' V- J
//-----------------------------------------------------------------------------: N! ~# C5 F; M8 Y
// Name: # H* }0 o  s/ @* g4 }: f4 |8 d
// Desc:
$ a# I+ c/ b/ ~& e+ ^. t& X//-----------------------------------------------------------------------------
* t8 M: V) B1 p/ [! wHRESULT CMazeServer::Init( BOOL bLocalLoopback, const CMaze* pMaze )1 X% d4 L9 _* {- [( c6 T
{# y% e' F) u9 O% w0 v. k6 `. o
    m_bLocalLoopback = bLocalLoopback;
: V+ Y4 O6 u$ ~0 {    m_pMaze = pMaze;
# A" V* V; ]' B' A0 T" d    if( m_pMaze == NULL )# I$ T1 v& ^- G0 q  b1 c
        return DXTRACE_ERR( TEXT("aram"), E_FAIL );</P>2 O5 D, y) \. [2 _
<>    // Grab height and width of maze
% u) N  M3 K3 {* q) H4 p' b    m_dwWidth = m_pMaze-&gt;GetWidth();6 G7 O+ E; k* H% f; j
    m_dwHeight = m_pMaze-&gt;GetHeight();</P>
, J  h; ?) z; z7 P9 O$ k<>    m_ClientNetConfig.dwMazeWidth  = m_dwWidth;6 y: A: Y( q. e: M0 G; h4 u
    m_ClientNetConfig.dwMazeHeight = m_dwHeight;</P>% ]: q: _5 U1 W) l! C1 W" f
<>    // Validate size. Must be a power-of-2 times LOCK_GRID_SIZE. Compute the shifts.0 X) E) H2 t; Y' Y# {* z
    if( m_dwWidth &gt; SERVER_MAX_WIDTH || m_dwHeight &gt; SERVER_MAX_HEIGHT )
# K1 y) [& O/ t* u5 t! _9 h- r        return DXTRACE_ERR( TEXT("Maze height and width need to be less than 128"), E_INVALIDARG );
) H8 \) J" j5 R    if( (m_dwWidth % LOCK_GRID_SIZE) != 0 || (m_dwHeight % LOCK_GRID_SIZE) != 0 )
- ^; T; v) b- I        return DXTRACE_ERR( TEXT("Maze height and width need to be divisable by 16"), E_INVALIDARG );</P>1 V( s$ F  P! E# ?! _/ d
<>    DWORD scale = m_dwWidth / LOCK_GRID_SIZE;( d$ t) a0 h' U3 q
    m_dwMazeXShift = 0;
: K0 V9 }( M! Y( L4 P6 x9 R    while ( (scale &gt;&gt;= 1) )
2 A. @6 M6 N6 ]5 D! X        m_dwMazeXShift++;</P>
$ U; N8 F* E+ M$ t% R, M( E. Y<>    scale = m_dwHeight / LOCK_GRID_SIZE;) p! M2 ^7 k7 u" U4 i  }, ?
    m_dwMazeYShift = 0;
8 ?* u4 K, P& j8 y    while ( (scale &gt;&gt;= 1) ): G4 ^2 k- c3 Q# }/ Y
        m_dwMazeYShift++;</P>( L6 a. x' |# S8 {6 ]
<>    if( ((DWORD(LOCK_GRID_SIZE) &lt;&lt; m_dwMazeXShift) != m_dwWidth) ||6 h% r6 U' f7 R9 T
        ((DWORD(LOCK_GRID_SIZE) &lt;&lt; m_dwMazeYShift) != m_dwHeight) )6 d' e5 w6 t8 F
        return DXTRACE_ERR( TEXT("Maze height and width need to be power of 2"), E_INVALIDARG );</P>; j3 v6 p" i4 n% p! H
<>    // Initialise the player list/ R% {$ R! J7 x+ j# T7 O- }: x4 I, z! A
    ZeroMemory( m_PlayerDatas, sizeof(m_PlayerDatas) );7 K; Y* E/ Z# H
    m_pFirstActivePlayerData = NULL;
5 W! c; Q0 j' ~2 ]+ j) Z7 ?6 P# o5 ?    m_pFirstFreePlayerData = m_PlayerDatas;, H" t. n' l  F0 }5 |/ g5 S
    for( DWORD i = 1; i &lt; MAX_PLAYER_OBJECTS-1; i++ )
5 w9 ]3 J6 H7 V* Z2 K3 n; v. O6 B: B    {
6 X4 |* O5 E5 Q9 g6 u4 [( L9 [        m_PlayerDatas.pNext = &amp;m_PlayerDatas[i+1];
7 K) |2 x% L8 W3 a5 i5 k! F        m_PlayerDatas.pPrevious = &amp;m_PlayerDatas[i-1];
# Z5 c! s8 l  j( _2 q; j    }</P>5 I' z/ g2 h0 o6 b- @1 ]# }
<>    m_PlayerDatas[0].pNext = &amp;m_PlayerDatas[1];  P* X' E  o4 q( c
    m_PlayerDatas[MAX_PLAYER_OBJECTS-1].pPrevious = &amp;m_PlayerDatas[MAX_PLAYER_OBJECTS-2];
( \/ n! A: s5 m7 e    m_dwActivePlayerDataCount = 0;
$ R( M6 c0 L/ S/ Q; f# p3 @    m_dwPlayerDataUniqueValue = 0;</P>
! z# _3 r, d6 a* y* s: `% Q5 ~1 |<>    // Initialise the cells7 B, D4 p! u7 y& I: `0 R
    ZeroMemory( m_Cells, sizeof(m_Cells) );
# u2 B3 o6 k/ J; x    ZeroMemory( &amp;m_OffMapCell, sizeof(m_OffMapCell) );</P>. l6 ]$ ^) |8 F! d5 j! O- p$ d) i1 v
<>    return S_OK;. S& u4 p- @$ O
}</P>: W- e3 ]; W& p- O
: l! j- ~$ |3 j  `
<>
5 ^4 ?( r. G& J* {//-----------------------------------------------------------------------------. j  j: F( Y; y7 N# C+ p
// Name:
* T$ i. r* b# z, o* }8 t8 }) J4 X// Desc:   V8 O, d  a5 Z: t4 h( o
//-----------------------------------------------------------------------------
5 F6 a9 x- W" P3 Y7 Avoid CMazeServer::Shutdown()5 v6 N9 b& W3 x. w% N' K7 U; Z8 `+ p. D
{9 J5 W$ E8 u( I- i% p+ R. I
}</P>: y, O5 L- u1 k: X& W3 O( P) f

9 z7 w: p  p. l0 A  d<># P  Q) v7 w- _: r: [5 S( b' e, E
//-----------------------------------------------------------------------------% l( B- D! e1 B/ k2 d3 G- u
// Name: 0 {0 `* {, D" ?& k, ]8 x& a# X
// Desc: / G0 I" s9 P+ w# Z# C. D+ b9 l# t
//-----------------------------------------------------------------------------
* R; d, S' \7 M. @9 g, }5 Nvoid CMazeServer:ockRange( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )0 a8 I$ u6 q& R* Y' [& M
{
% u$ N2 e  v6 M) X/ \; W    m_LockGrid.LockRange( x1&gt;&gt;m_dwMazeXShift, y1&gt;&gt;m_dwMazeYShift ,9 Q4 S2 _; w6 I
                          x2&gt;&gt;m_dwMazeXShift, y2&gt;&gt;m_dwMazeYShift );
" z6 O# s! u' J3 f3 f}</P>
, z# d# g- j( C% m/ l/ r
3 U8 R! `  @% N: y& |$ U1 K* t0 V<>% A6 f  ~5 {6 z2 @: j8 D
//-----------------------------------------------------------------------------
9 `: E& O/ d1 _& Z! n- }! p; v8 z// Name:
8 Z* c) v6 l# C5 j5 t1 {( \1 T. n// Desc:
- k! v2 G$ y& W//-----------------------------------------------------------------------------
# O* ~( M/ ?9 A& ]. H% C  \8 ~& vvoid CMazeServer::UnlockRange( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )! W7 b& j# |  I& m% E, Z* [9 T3 `
{
1 I2 [- y. ^2 R1 j, n( R3 q  J    m_LockGrid.UnlockRange( x1&gt;&gt;m_dwMazeXShift, y1&gt;&gt;m_dwMazeYShift ,' T( {9 W2 X+ e, j/ ?
                            x2&gt;&gt;m_dwMazeXShift, y2&gt;&gt;m_dwMazeYShift );6 q$ J5 p& w- j- R
}</P>2 u. r; }8 `) p7 q' Y/ s+ }
0 B5 K5 b5 r# ?1 {  h/ |7 n9 I
<>
( a% E3 S$ l0 f//-----------------------------------------------------------------------------. F' z2 p- v$ s% `
// Name: " n& _7 h0 v  _1 b
// Desc: 1 c7 P1 V* \7 c  G/ C
//-----------------------------------------------------------------------------$ p/ i2 L, Y1 ?' E& T9 s0 m' u
void CMazeServer:ockCell( DWORD x, DWORD y )
6 F, S9 w/ C* Z  n- U% I{
0 V4 R7 s9 p6 t/ F7 G( {1 I    if( x == 0xffff )
) \8 e8 z7 I* a        m_OffMapLock.Enter();9 C  p  y7 f& V, M9 I' u
    else( s8 p8 M/ L8 h" h
        m_LockGrid.LockCell(x&gt;&gt;m_dwMazeXShift,y&gt;&gt;m_dwMazeYShift);
5 Q; h1 {; j4 |1 n1 o}</P>& E* Q$ F( y& S+ J" h3 b* s; ?

$ T1 T/ |" K; ~' I* Q4 I( R8 k<>8 }& `1 J! ~/ E
//-----------------------------------------------------------------------------
" ]- n6 f* C; L6 K// Name:
+ f3 L$ C1 X4 [* \0 P// Desc:
  z6 a3 E% j) w) C" N//-----------------------------------------------------------------------------$ v2 E% y2 v% G- y
void CMazeServer::UnlockCell( DWORD x, DWORD y )) O+ _, d$ K3 U) f, |
{1 d1 T& q% m# v
    if( x == 0xffff )
7 ^. v: F+ U2 ?        m_OffMapLock.Leave();$ E" e. e' v0 @  g* I: `3 P5 N
    else
0 E( E! n# I) k( {6 X8 r        m_LockGrid.UnlockCell(x&gt;&gt;m_dwMazeXShift,y&gt;&gt;m_dwMazeYShift);
9 s. H+ a; u0 `}</P>, I% W6 ^- @0 G+ _: {7 }, ^3 r

( M2 C3 P# A1 E<>2 t! M1 }! h: r4 W
//-----------------------------------------------------------------------------( l/ T; B$ W$ ?% g
// Name: " i, C! b+ ?0 X3 ~) M& A' K
// Desc: 7 D, i  O  X" E1 M8 u
//-----------------------------------------------------------------------------& d/ P" m, X# s9 B$ {
void CMazeServer:ockCellPair( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )
* O- y/ }5 b* _- X( Y" c$ K{
( L% s/ O  x+ o0 L$ r7 z    if( x1 == x2 &amp;&amp; y1 == y2 )
* O7 H4 P! ?+ u7 ]1 U    {4 T1 p6 `7 B$ H4 L1 [  v
        if( x1 != 0xffff &amp;&amp; y2 != 0xffff ): ^. K7 d' X7 ~# i& [2 S+ Z7 H$ n
            LockCell( x1, y1 );
7 `$ I. r. q+ ]0 F7 Z0 m, n        else- Z5 a0 P5 a& G! f
            m_OffMapLock.Enter();</P>
* @6 y$ O- n. v. Q4 {# Y3 ^<>        return;
' A; Z& S8 n) m  c5 {, `    }</P>
# E' l, M  j; F- R<>    DWORD x1shift = x1&gt;&gt;m_dwMazeXShift;( y, ]( @5 H- F0 Z
    DWORD x2shift = x2&gt;&gt;m_dwMazeXShift;
3 ~% w3 k3 J& |5 k    DWORD y1shift = y1&gt;&gt;m_dwMazeYShift;  }  g- v0 F( |. }' d: b
    DWORD y2shift = y2&gt;&gt;m_dwMazeYShift;</P>5 y4 s8 k! V+ N: ?+ d" D
<>    if( x1 == 0xffff )# s' r4 y7 E8 B& \0 [$ C% ?
    {+ C7 E- j3 c" v  _  {$ N" w
        m_OffMapLock.Enter();. s2 v7 t% |! L9 k7 @! \; _3 H
        m_LockGrid.LockCell(x2shift,y2shift);
; h: f7 ~. e+ }' K+ {% \: f    }+ c9 i+ N9 s# ?4 {
    else if( x2 == 0xffff )
; o/ f6 c% k* J4 G    {3 \/ Y5 \1 m# G
        m_OffMapLock.Enter();
4 t3 g" F4 q; ]* a        m_LockGrid.LockCell(x1shift,y1shift);- h4 E" T% _3 A, {
    }
  f; m. W; i  i& K    else % {. ], q, x8 }) X8 i: }
    {
$ A' j# R" B1 T4 {        m_LockGrid.LockCellPair(x1shift,y1shift,x2shift,y2shift);
1 `' Y! w3 B5 G1 i6 ~    }
9 v1 M6 w" z7 T/ V& y' F" g}</P>" N' d- W/ s, Y- ?2 E$ s
4 n' ]. K+ x& G2 r' n0 j! Q
<>
& ]6 q  p: f" [! ^, C0 m6 \//-----------------------------------------------------------------------------+ J) V( L! W7 r' O
// Name: : N( N% P* o! o5 Q' u1 K
// Desc:
+ Q+ O1 Q  u& e1 I& O//-----------------------------------------------------------------------------, R6 C- ^( B- m; T* h9 S  k
void CMazeServer::UnlockCellPair( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )
. L9 U# q: z: t* f9 ]) N1 B{+ E4 @3 ?5 l7 M0 s( \- n9 X
    if( x1 == x2 &amp;&amp; y1 == y2 )
7 b% `! R. E- G; d    {# c' k8 x; X& O: S
        if( x1 != 0xffff &amp;&amp; y2 != 0xffff )
9 N0 E( R5 _  O+ K6 C( u" _            UnlockCell( x1, y1 );. g: _% _& l4 ~
        else; F; U) f: E1 S& l1 `
            m_OffMapLock.Leave();</P>
3 a: w. n3 |  v" q* m1 F' k$ F<>        return;' j4 V4 w5 \2 o9 k
    }</P>
- w2 v6 k" i# i* p* j  }  q3 P7 Z<P>    DWORD x1shift = x1&gt;&gt;m_dwMazeXShift;
6 {! P- W) A4 `& R/ C2 v, Y    DWORD x2shift = x2&gt;&gt;m_dwMazeXShift;
5 o( ?3 Q* ^' o9 t" C    DWORD y1shift = y1&gt;&gt;m_dwMazeYShift;
! _; e4 D1 x; N3 [$ ~    DWORD y2shift = y2&gt;&gt;m_dwMazeYShift;</P>
! c. A  K& E% W) f6 N8 k8 K<P>    if( x1 == 0xffff )
% d! [. B/ ?: Q- u) X3 n3 g/ k3 O    {
/ I$ A) h, K9 j. |3 c$ ~6 J8 L        m_LockGrid.UnlockCell(x2shift,y2shift);
7 ?. {. T  n& M) R9 Y. O( Q        m_OffMapLock.Leave();
" l# l) G/ }/ P- q- ^    }
, k, g1 E- G2 C, _; s3 S8 R    else if( x2 == 0xffff )( k; b, y* j% E; M# x
    {
0 `! m( l- k& p' b( i7 D1 n: z        m_LockGrid.UnlockCell(x1shift,y1shift);6 C& w  p" _' k; q0 u  @
        m_OffMapLock.Leave();! u6 R, u  w/ G& I
    }
# U3 l5 I$ X+ f% T/ e    else % ]* U: d$ ^' D3 \! D1 V
    {
5 u/ Q0 s& P1 D( f7 A6 W        m_LockGrid.UnlockCellPair(x1shift,y1shift,x2shift,y2shift);3 f+ D5 s; J) A
    }: o4 I! \, x$ F& ?
}</P>8 O6 K# J! P/ v7 U( U

; r' K8 J! X4 T; d<P>
+ \+ |8 M- d9 g4 Z//-----------------------------------------------------------------------------3 ~) n2 P( E& N) `
// Name: ' F9 }% A. D9 {/ L) n
// Desc: / C+ x- }' f! Z
//-----------------------------------------------------------------------------
1 }" B! }/ X1 c2 Pvoid CMazeServer::OnAddConnection( DWORD id )
5 H; x! f" Z6 a5 p/ F$ Z# a8 p{
& Q4 i( i& C2 t8 W( Z) }, b    m_AddRemoveLock.Enter();</P>
; O( m+ X* p. F. d& W<P>    // Increment our count of players
3 v( E3 H" ]5 v9 o' ~    m_dwPlayerCount++;6 v+ \  K; {# C7 `& O. y# R
    if( m_dwLogLevel &gt; 0 )
2 T4 d" h8 v: C9 W, U! z    {/ Y' G* u+ z0 b/ W; u
        ConsolePrintf( SLINE_LOG, TEXT("Adding player DPNID %0.8x"), id );, e* Q% v+ b/ _& Y2 r8 z
        ConsolePrintf( SLINE_LOG, TEXT("Players connected = %d"), m_dwPlayerCount );
1 I( e4 j1 F7 R, E    }</P>. J/ b9 z' Y# ?6 C( o; P
<P>    if( m_dwPlayerCount &gt; m_dwPeakPlayerCount )& U2 m  _7 b# C$ |  J
        m_dwPeakPlayerCount = m_dwPlayerCount;</P>
/ ]' o8 ~6 w4 H& T) N+ i" y<P>    // Create a player for this client
" \" I0 V; ~; I* S8 i    PlayerData* pPlayerData = CreatePlayerData();* e$ i9 @& L+ {) o6 _
    if( pPlayerData == NULL )
5 N) I6 |! b" X    {" C" C& ]/ p% E* m
        ConsolePrintf( SLINE_LOG, TEXT("ERROR! Unable to create new PlayerData for client!") );
* e! Z& W% K( k2 j4 r, D        DXTRACE_ERR( TEXT("CreatePlayerData"), E_FAIL );5 W( l6 w! U+ @3 l# T+ R
        m_AddRemoveLock.Leave();: B6 a" G0 F6 X# Z# Y" [
        return;
  L5 B9 ^; J' y    }</P>
, f7 F+ [5 @% M3 X( L$ ~) Y<P>    // Store that pointer as local player data; `" N$ G" ?# K' G, n
    SetPlayerDataForID( id, pPlayerData );</P>6 s/ x) k8 V2 d6 m* s3 I
<P>    // Grab net config into to send to client* x- u; P/ ?; J$ C8 |
    m_ClientNetConfigLock.Enter();6 a5 O4 c# M0 Q  o4 l; l% b
    ServerConfigPacket packet( m_ClientNetConfig );
: K7 q+ Q- X: R* p5 }    m_ClientNetConfigLock.Leave();</P>$ J1 K6 T! H4 d. U* ]
<P>    // Send it* ]; `8 F( `/ V0 `0 x* P4 y
    SendPacket( id, &amp;packet, sizeof(packet), TRUE, 0 );</P>
/ ~3 }- Z" D; e. u0 I9 v<P>    m_AddRemoveLock.Leave();
, D' I& _: ~; ?7 S3 Y  T. Y}</P>) K$ ^( U* h4 U  c
& Y, W; ?( O4 J4 L; u$ D
<P>3 t2 C( a/ Y8 I3 N
//-----------------------------------------------------------------------------6 _% W9 i! N: {2 e4 b0 E
// Name:
, ?6 `& Q0 K4 f' f( ~# M/ c// Desc: : A6 x9 T% I5 t/ P$ d1 B9 b
//-----------------------------------------------------------------------------
3 P2 u! n5 [6 x7 Jvoid CMazeServer::OnRemoveConnection( DWORD id )0 u3 u$ C  F3 \) X1 D
{
3 X% e# z- L' O, U1 [0 u* Z    m_AddRemoveLock.Enter();</P>1 N2 o* e# Y9 L* \" S
<P>    // Decrement count of players5 N# f: D1 i, m! z; }. H
    m_dwPlayerCount--;</P>2 c2 Z1 Y! ?  t5 l1 _0 @
<P>    if( m_dwLogLevel &gt; 0 )+ k: Y3 V6 r% e
    {1 X7 s3 |; i# Q) b; u. |
        ConsolePrintf( SLINE_LOG, TEXT("Removing player DPNID %0.8x"), id );
$ v9 ?  S" a- G0 y' T9 a        ConsolePrintf( SLINE_LOG, TEXT("Players connected = %d"), m_dwPlayerCount );4 Q6 s% ?3 m' I; q7 K1 A
    }</P>
+ E9 r1 b1 ?+ Q  y1 b, p<P>    // Find playerdata for this client
+ y+ D3 E0 n9 f: R2 Y& h! w7 |% h    PlayerData* pPlayerData = GetPlayerDataForID( id );" M& i. X2 d* U# Q. ^8 L9 r
    if( pPlayerData != NULL ); \* }% Q1 |& r
    {
. Y5 F8 |$ W8 V# c; a        // Destroy it; |7 E/ _2 P. g* a. J$ Y
        RemovePlayerDataID( pPlayerData );$ L& m7 n5 O( \$ I% E
        DestroyPlayerData( pPlayerData );
, L: p1 k* F& b% r1 B4 `( q    }</P>
) T. Q# Z& q3 @" a5 C* A# X- j<P>    m_AddRemoveLock.Leave();4 l& X" n5 H% J* P9 [* n
}</P>
! T* s6 z; L  S# ~5 ^; x" }" c( t
0 _$ C6 s  S2 ^& z7 T3 @) s- `- r" ~<P>
: ^! h; }  Y, Z# ~$ o! e( G//-----------------------------------------------------------------------------0 K+ L& g" J% _* ~+ l5 e
// Name: & I7 w; F9 f/ {$ y; ?. ~8 v
// Desc: ( j$ s% \- g* Z# ?: g' d
//-----------------------------------------------------------------------------
0 d4 i3 p9 v( E2 |$ B/ G) OHRESULT CMazeServer::OnPacket( DWORD dwFrom, void* pData, DWORD size )
$ s* G- y1 J! A{
1 \% j" @8 s# e    BOOL fFoundSize = FALSE;</P>( W* r: N; ?2 {0 x
<P>    // Increment the number of thread we have in this process.; _9 B6 a( l+ a
    m_csThreadCountLock.Enter();</P>
2 b. G! b9 v+ N$ o<P>    //Get the start time of when we entered the message handler.
8 `+ b' t1 f8 @2 Q% E2 s    FLOAT   fStartTime = DXUtil_Timer( TIMER_GETAPPTIME );</P>
9 v% S- d: ]4 ?<P>    m_wActiveThreadCount++;$ w% n# |+ V# p5 w! X
    if(m_wActiveThreadCount &gt; m_wMaxThreadCount)
4 M, x) F2 M5 T: F- G( ]) y        m_wMaxThreadCount = m_wActiveThreadCount;5 @% U$ p& \0 h
    8 `' v6 x& v) b! b# c
    // Calculate and average.6 g* {  \. g, w. A2 T0 ^+ g
    FLOAT fdiff = m_wActiveThreadCount - m_fAvgThreadCount;. _4 ~9 A- C0 X; W% a
    m_fAvgThreadCount += fdiff/32;
, ~- j( W) o% Q7 Q3 `      p8 n- s% G" ]& c: Q5 _6 G
    m_csThreadCountLock.Leave();</P>5 j/ p5 w# F  o4 a" P0 N
<P>
0 J, e; Z: Z% a/ U    ClientPacket* pClientPack = (ClientPacket*)pData;
3 v$ Z5 D9 V5 h/ [    switch( pClientPack-&gt;wType )# J# r7 i: C. l( @# j
    {
) O  H9 r8 A  ~9 J9 B& w        case PACKETTYPE_CLIENT_POS:, W! P! Y# d( g; ?% D7 u' u
            9 ]; u1 S6 _- a0 `
            // Check to see if the packet has a valid size. Including
8 A: \+ j0 R' P            // the custom pack size.
' E' g' j& x: [9 G1 b0 K            if( size &lt; sizeof(ClientPosPacket))# M7 M: Q2 u' v
                fFoundSize = FALSE;+ V9 [/ @, f! V
            else if( ! IsValidPackSize(size - sizeof(ClientPosPacket)))7 k) O- M) r9 t: s2 I
                fFoundSize = FALSE;
6 u! C- M1 \) l0 p' n" U4 O' l            else
. V2 S* [1 L, [                fFoundSize = TRUE;</P>" N0 y( o$ ~1 L" b/ E7 u
<P>            // If valid sized packet, handle the position.9 ?1 U4 J1 q5 \% x) N$ R
            if(fFoundSize)1 ~2 [, w# q1 ~+ m$ A1 s, f* Z! Y
                HandleClientPosPacket( dwFrom, (ClientPosPacket*)pClientPack );) z3 K- m( B5 S) A1 r- G
            else
3 L, T, b+ w" j: o+ K7 k* \$ N                m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );</P>
$ L9 C" k" Y! Q# \; L& g, H<P>            break;</P>
5 {$ l$ o' j! }2 l' \" B6 U: c<P>        case PACKETTYPE_CLIENT_VERSION:  r7 V; E  f; d- H/ \+ E! J3 M
            if( size == sizeof(ClientVersionPacket) )0 J. P0 N" R( I! j7 I7 T( c+ Y
                HandleClientVersionPacket( dwFrom, (ClientVersionPacket*)pClientPack );
1 E1 H% o5 \3 P4 S, Q$ M            else
  R& x6 t* t5 l! k! q                m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );
( n( v3 O# t/ o; u+ ~" @. }" `2 o            break;</P>
0 M, T8 R9 F/ j* E; K<P>        case PACKETTYPE_SERVER_CONFIG:</P>7 r0 O: C% N7 d" T/ Z' }
<P>            // Server config packet sent to all users (including server). Just ignore and continue.</P>" z$ c) g5 D- O0 U! u" O$ n" k( j+ R* F
<P>            break;: l& m. U$ ~" d4 w, G; V" M: ~$ q
        default:
: x- T0 l3 m% e            HandleUnknownPacket( dwFrom, pClientPack, size );
5 m, |4 c3 U. b            break;2 K2 n* p% d' P% L$ [# f
    }</P>* w& `0 M: \, C- }2 X
<P>    //If the user wants to hold the thread, Sleep for given amount of time.5 m- {8 o& T" q6 K' H
    if ( m_dwServerThreadWait &gt; 0 )
1 h/ \; q7 g4 o9 G    {6 P2 {& j9 g7 u6 l8 \
        Sleep( m_dwServerThreadWait );
2 ], \6 }: }; R0 B    }( v' |% s2 \3 y3 o! k9 k
    & `& @# e- j0 y% H. d0 L% h0 B9 u
    // Retrieve thread data for this process.+ F( w6 h" G% k9 K! @9 w2 O
    m_csThreadCountLock.Enter();</P>
( r' ?# W+ X7 Y" b- p4 `<P>    m_wActiveThreadCount--;</P># L( @" X: ]6 A
<P>    FLOAT fDiffTime = (DXUtil_Timer( TIMER_GETAPPTIME ) - fStartTime) - m_fAvgThreadTime;) |5 ?! F8 _  B$ l7 w, d% U
    m_fAvgThreadTime += fDiffTime/32;</P>
6 I2 X9 P( D! y% @1 z<P>    //Get the Max time in the thread.
: J1 e& ]2 z( g1 n4 E: F    if ( fDiffTime &gt; m_fMaxThreadTime ). D8 c6 F5 r- m# G  K* Q
    {# b6 H/ C; ~# [, g$ F+ p  ^% L8 O, ]
        m_fMaxThreadTime = fDiffTime;
3 S' X: K+ L$ ?  y) M& c    }</P>' B7 A: p0 i4 @' ^2 _2 P" j% H
<P>    m_csThreadCountLock.Leave();</P>
$ b: h( [3 s% Q; k& b( `% S<P>    return S_OK;
9 F. J" s$ O* m}</P>  t/ s* U( x/ W1 a

/ ^) I. e- a) i' [/ k4 U% J. V6 F<P>//-----------------------------------------------------------------------------
" Z7 \$ f9 I! D% E8 G  P5 V4 s// Name:
3 \2 K* {; `7 |7 T$ s" H3 o// Desc: 2 V% c3 B- N% d! D( [1 `; _: Z( z
//-----------------------------------------------------------------------------7 l. E7 ?( ~, T4 G
BOOL CMazeServer::IsValidPackSize( DWORD dwSize ); r; D5 P9 g/ b
{
1 b4 n$ f0 c2 q4 J    BOOL fFoundSize = FALSE;
  I7 _! |$ H0 C- r    BYTE ubPackLocation = m_ClientNetConfig.ubClientPackIndex;/ r% R/ h* _9 r$ e$ x$ I
    6 l/ j9 g: x* l  M; L$ f# i8 b
    // Check through the array of valid pack sizes.
* i4 x! F" K5 J! B8 ?    if(dwSize != m_ClientNetConfig.wClientPackSizeArray[ubPackLocation])
+ p6 v: j- W# @1 m& `- X8 \    {' A$ Q9 c5 r$ y) M/ ~& r1 B
        for( --ubPackLocation; ubPackLocation != m_ClientNetConfig.ubClientPackIndex; ubPackLocation--)
) [- x; C  p: d/ f        {
3 \7 P& F( b6 b, a/ o# D            if(dwSize == m_ClientNetConfig.wClientPackSizeArray[ubPackLocation])
9 v: y$ G3 f  q  b" \3 t: ?( B            {6 p/ u8 T/ @; \8 e( @# j0 B% A/ ?
                // Found valid size in the array.
/ o! _( a! ~5 m6 k7 [                fFoundSize = TRUE;" A( S& Z" u2 f* D" _7 \! s
                break;3 f# N  F2 o* R$ [
            }5 [  s" P4 }( V  U. A6 U6 Y. Z
            if(ubPackLocation &gt;= PACK_ARRAY_SIZE)  ubPackLocation = PACK_ARRAY_SIZE;  //Wrap the array.
( ^  u4 |2 J/ S& R/ m5 [0 X        }
+ `/ E5 Q/ O$ q' S# N  i    }: d: t5 w+ Y/ Q) y- f! w
    else. Y  E) y7 C2 q
    {
2 @+ ~: i; J7 K5 g- q) ~        fFoundSize = TRUE;
- b. T0 P$ O% s, E' f    }</P>8 I, g" n+ |8 W9 z
<P>    return fFoundSize;
; N1 [  h. _9 m; k4 z}</P>4 @2 |1 X6 f  \0 R3 p8 D
<P>
# [! `  j1 }& [" b+ M( B0 I//-----------------------------------------------------------------------------
' X" q' t5 K1 ~) u. g; N// Name: - b- b" T7 |) V1 f& T* u* {
// Desc:
. `6 M9 ?2 `4 d9 ^8 a6 l6 {6 m//-----------------------------------------------------------------------------
( U9 }9 a6 K; [+ ~0 a0 {void CMazeServer::OnSessionLost( DWORD dwReason )
" r# ^3 H+ P. ~( O{, \5 W5 N0 u8 j2 K% o
    ConsolePrintf( SLINE_LOG, TEXT("ERROR! Session was lost") );
8 b( T. I1 R8 F4 C}</P>
& }: J' }7 i! |# f7 `/ k3 A3 B+ f. N; [/ ~& f
<P>
( \0 Y: @) u0 S4 v+ v0 Y: q//-----------------------------------------------------------------------------
2 V; l2 q7 k4 I" W% ^/ N4 H// Name: + i( l9 E/ r! A1 E
// Desc:
& D, i. a! N9 T//-----------------------------------------------------------------------------
+ f* \- I$ @6 P/ f6 L" D- i4 D; wPlayerData* CMazeServer::CreatePlayerData()
( ^' ~3 m9 P4 ~# q+ t  M! ~0 R% x{  a" k6 a7 v5 P
    m_PlayerDataListLock.Enter();</P>
; F% A6 n* }. l1 e9 W/ x' D7 L$ E<P>    // Grab first free player in the list2 b* q* q- ]" Z; Z# e: h3 y
    PlayerData* pPlayerData = m_pFirstFreePlayerData;</P>3 P8 q. B; S" a
<P>    if( pPlayerData )
0 D) w% G) K7 l& g% S- x$ ]' Z8 }    {
* V9 O0 B: ^; e% l        LockPlayerData( pPlayerData );</P>
+ Y/ b! T9 _9 O- F# u! r<P>        // Got one, so remove it from the free list
' ?% @$ \9 O$ G0 l& B4 i/ i        if( pPlayerData-&gt;pPrevious )+ M3 B  P- r+ N4 H4 j
            pPlayerData-&gt;pPrevious-&gt;pNext = pPlayerData-&gt;pNext;2 F7 _9 b4 O' N9 u+ Y) @- j
        if( pPlayerData-&gt;pNext ). w3 }7 ?& H( }# H' M4 G+ I1 c  C
            pPlayerData-&gt;pNext-&gt;pPrevious = pPlayerData-&gt;pPrevious;
* C7 t, i2 H( ~$ \, a2 v        m_pFirstFreePlayerData = pPlayerData-&gt;pNext;</P>- Z! `7 l) T) \" d6 \6 a) c
<P>        // Add it to the active list
; n! @  q3 |- B8 G4 ?        if( m_pFirstActivePlayerData )+ X# ?) b  d- b5 A, d4 `
            m_pFirstActivePlayerData-&gt;pPrevious = pPlayerData;
; u/ ^& @3 e& }9 x        pPlayerData-&gt;pNext = m_pFirstActivePlayerData;
" p# C" ]6 J/ k7 m( T        pPlayerData-&gt;pPrevious = NULL;
' J" K- z, @+ Z5 S        m_pFirstActivePlayerData = pPlayerData;</P>
0 C6 T; k6 K  L' F<P>        // Update count of players
3 C  ^+ m0 E% s; W        m_dwActivePlayerDataCount++;</P>) p$ v% o% R; T) Z7 k% d  N
<P>        // Generate the ID for this player, N2 M, ]. `2 q5 d8 d5 t
        m_dwPlayerDataUniqueValue++;
' u6 ]2 U5 S  e# `/ Z0 Z# ^. k        pPlayerData-&gt;dwID = (DWORD) ((pPlayerData-m_PlayerDatas)|(m_dwPlayerDataUniqueValue&lt;&lt;PLAYER_OBJECT_SLOT_BITS));</P>
- [& M  @) ~# e& k  n<P>        pPlayerData-&gt;pNextInIDHashBucket = NULL;
& O' L% v# X. x0 q2 P5 y: w$ k        pPlayerData-&gt;NetID = 0;
" o4 h$ }6 W$ e$ w. b5 B        pPlayerData-&gt;dwNumNearbyPlayers = 0;</P>  k3 ]4 ?) K4 F
<P>        // Insert into the "off-map" cell3 P# \3 J2 d2 P* e* r
        pPlayerData-&gt;fPosX = pPlayerData-&gt;fPosY = -1;  o. R- L. W- k8 ]0 _
        pPlayerData-&gt;wCellX = pPlayerData-&gt;wCellY = 0xffff;
/ F8 S+ c8 ?) ?        m_OffMapLock.Enter();# b' H( w% |: _' D9 [
        pPlayerData-&gt;pNextInCell = m_OffMapCell.pFirstPlayerData;
& X0 I9 E' g4 s7 P  p        m_OffMapCell.pFirstPlayerData = pPlayerData;
" b7 s7 _3 r8 q9 M0 F% y4 V1 `        m_OffMapLock.Leave();</P>
$ f# s5 R2 H8 J" {: `# w1 V/ ~<P>        // Mark as active
& S1 {3 p$ G" Y        pPlayerData-&gt;bActive = TRUE;</P>
: @4 v$ h0 d2 U, D, v<P>        UnlockPlayerData( pPlayerData );
$ J' i5 |) F8 Q    }</P>
; R$ n/ T6 [3 |: {- G+ ]% y<P>    m_PlayerDataListLock.Leave();</P>
% t% c1 _9 Q; ~/ @<P>    return pPlayerData;
: M8 r% U/ r! y8 {1 }}</P>9 `) x. a5 I5 y# K$ Z$ N, y
7 V9 S, ^# g( S# P) o  _
<P>& ?# F+ p1 w) S
//-----------------------------------------------------------------------------7 o2 r7 A6 z. H. T, i- e5 G( V( S
// Name: ! ]5 ]+ P, e1 y
// Desc:
9 I1 Q5 ~; w( Y" n$ O//-----------------------------------------------------------------------------
3 _9 Y: k: D) ~9 b6 a9 n; Vvoid CMazeServer:estroyPlayerData( PlayerData* pPlayerData )& G* J2 }) I! Z4 K8 a
{( j) y" r* M' O6 J! [- w
    m_PlayerDataListLock.Enter();
6 v) g  w: j6 q4 _4 j    LockPlayerData( pPlayerData );</P>" K# k% e1 @; j2 _& m( D+ [
<P>    // Remove the player from its cell8 V1 z# d* `" X- o& N$ @
    RemovePlayerDataFromCell( pPlayerData );</P>) d+ F. b8 ^) t; l
<P>    // Mark as inactive5 P  d2 W0 h- [! u, J: z+ [# B
    pPlayerData-&gt;bActive = FALSE;</P>% r8 x5 B/ i1 I6 Z: C* G+ ?
<P>    // Remove player from active list
# j$ _/ n7 M/ q% @9 l: f1 G    if( pPlayerData-&gt;pPrevious )% Y: z3 J0 y8 B
        pPlayerData-&gt;pPrevious-&gt;pNext = pPlayerData-&gt;pNext;4 K, U. q( Q7 g+ W# m$ b3 L2 I
    if( pPlayerData-&gt;pNext )& p" p( ~7 H4 r6 t4 P! w' t% ~, B" q
        pPlayerData-&gt;pNext-&gt;pPrevious = pPlayerData-&gt;pPrevious;</P>  F  N- \( [( x
<P>    if( m_pFirstActivePlayerData == pPlayerData )
4 Z# \. x' w8 f0 g. ^        m_pFirstActivePlayerData = pPlayerData-&gt;pNext;</P>
9 _, r  y6 ?9 i- D5 ~' q<P>    // Add it to the free list
8 d+ R% b. w0 u, @1 f- q3 U9 ~    if( m_pFirstFreePlayerData )
. I( Q) ~; _+ G        m_pFirstFreePlayerData-&gt;pPrevious = pPlayerData;
4 e- \; ?& ^9 ^) m! o% u7 ]' ^    pPlayerData-&gt;pNext = m_pFirstFreePlayerData;
2 q  a5 u$ y' H% _: N    pPlayerData-&gt;pPrevious = NULL;( [! N" S' P# C( V' k
    m_pFirstFreePlayerData = pPlayerData;</P>9 W3 @3 a( \" x
<P>    // Update count of players
1 C9 M' E  A! K) L5 U9 \    m_dwActivePlayerDataCount--;</P>
! {2 U# A/ l/ Q( s- n<P>    UnlockPlayerData( pPlayerData );
6 Y: T3 @1 Z2 O    m_PlayerDataListLock.Leave();- i1 x, I7 s& F1 _
}</P>
! B% c. S2 w! A8 d4 ^  `. _% j( |' W: i" O" t! j; b
<P>8 x5 }! c2 G3 q7 [
//-----------------------------------------------------------------------------) u- V" d" E# z2 K- C3 r9 E
// Name: + G9 n6 s$ N7 a% K3 C
// Desc: $ w# T( R! f1 z0 s) C9 u, @
//-----------------------------------------------------------------------------
- S& H- G5 S( ~( M1 Xvoid CMazeServer::RemovePlayerDataFromCell( PlayerData* pPlayerData )
3 l+ D) U, m  h3 J8 J$ ]' p{; D0 c) L6 ]* a# {/ {8 l
    // Lock the player5 Y' }6 ]3 @& I& {
    LockPlayerData( pPlayerData );</P>6 J+ i* Q8 r  I
<P>    // Lock the cell the player is in
% B5 I: Q% T9 Q' f    ServerCell* pCell;1 K' P1 J1 j+ G: P! |' K
    if( pPlayerData-&gt;wCellX == 0xffff )" X1 ?4 Z2 U$ X6 n7 ~! Y
    {, }' g* r" W1 B4 H- [5 M
        m_OffMapLock.Enter();
0 Q" k# O1 l, u) w* I        pCell = &amp;m_OffMapCell;
' @5 l  n- ?; L% v" x- ~) e    }. s( ]# B; l" Y+ i3 h! d
    else
7 u+ {3 P# O. A! ?* k1 B, Q2 ?    {
: [& s; y/ K  X: {4 Z% U3 ?        LockCell( pPlayerData-&gt;wCellX, pPlayerData-&gt;wCellY );; ?0 ~" r: ?  r5 ]$ R$ s" B* c; O
        pCell = &amp;m_Cells[pPlayerData-&gt;wCellY][pPlayerData-&gt;wCellX];4 v+ p7 j9 l5 t9 A- f% A+ v
    }</P>
( B4 q; U( O+ }& ?" \; ~<P>    // Remove it from the cell
1 K; a9 n* D) t1 f    PlayerData* pPt = pCell-&gt;pFirstPlayerData;+ ?! T# V0 X- o  P) _
    PlayerData* pPrev = NULL;1 S) {; N' Y: a5 j% t
    while ( pPt )+ h7 [. X" s% ~4 I) N, M
    {; o. ~2 P. [6 f: L2 \3 y/ D
        if( pPt == pPlayerData )
( d0 X4 C; A& J        {
6 V# N! u9 |% U1 Q$ G; ?. x& ^            if( pPrev )
6 ~. v. e2 \% k' }8 J7 n/ V+ v+ n! p                pPrev-&gt;pNextInCell = pPlayerData-&gt;pNextInCell;
0 g6 V# m2 h; G5 o            else1 n; u  ~5 ^6 e  K. ^
                pCell-&gt;pFirstPlayerData = pPlayerData-&gt;pNextInCell;</P>
6 U/ ^+ j& k4 V( Q<P>            pPlayerData-&gt;pNextInCell = NULL;
/ i1 L$ o6 {" ~6 {* A9 n. C1 u) J            break;
7 ^/ T* H- k& i, {# z: I        }
# q/ L3 p( Q% T; ^        pPrev = pPt;2 X: x0 S  T7 Y' W0 g/ y5 {; T
        pPt = pPt-&gt;pNextInCell;
* Y- `, m& D; t    }</P>
$ i1 d0 J3 Z- ]/ m) G, I<P>    // Unlock the cell1 @' Q( W0 l" B, Y# O1 h( F; ?
    if( pPlayerData-&gt;wCellX == 0xffff ): Q4 V3 _6 w" i  d7 d# t" |& z( ~
        m_OffMapLock.Leave();/ d( B, k9 i( d% Z" l
    else
' i" p5 v. Y# \* I, J+ O6 s; S        UnlockCell( pPlayerData-&gt;wCellX, pPlayerData-&gt;wCellY );</P>
6 C! C. |  H' A9 s$ t<P>    // Unlock the player
- u6 `1 ?; q6 n    UnlockPlayerData( pPlayerData );
: L! ~* u: m- Z}</P>2 Z$ k% i. _' N6 m  y

. O- A& q5 z7 {' N<P>
: y1 g7 J2 l5 r: K2 ^0 N//-----------------------------------------------------------------------------
- ]+ P, u+ {; G3 m# I// Name:
' l! H' V4 [. H// Desc:
% {' i; P  c3 W. `) W* p; V' t" A6 d//-----------------------------------------------------------------------------' l2 k: n5 S) U' n' \  z( A4 Q1 A
void CMazeServer::UnsafeRemovePlayerDataFromCell( PlayerData* pPlayerData )  |2 N- [3 A5 p: ~
{( ?# p' r5 S) [9 S% N
    ServerCell* pCell = GetCell( pPlayerData );( b8 h3 E* ~' n4 N$ g# m5 H
    PlayerData* pPt  = pCell-&gt;pFirstPlayerData;
6 n  P% \, E/ @    PlayerData* pPrev = NULL;5 f& q6 X, j& N7 B: ~7 h
    while ( pPt )' H1 [* |: R7 B3 c
    {9 {2 S/ s8 |0 P  j( h) S  I
        if( pPt == pPlayerData )
/ ~5 F; ?5 E" z        {
6 H( a1 V- a+ d3 a# Q, ^$ F            if( pPrev )! N* l( j) Z9 r# d  a
                pPrev-&gt;pNextInCell = pPlayerData-&gt;pNextInCell;
. c$ H8 ~2 P+ j            else# Y3 |# A) l8 v- I. \! t- g
                pCell-&gt;pFirstPlayerData = pPlayerData-&gt;pNextInCell;
. t: U9 ^8 b' p- H, K. f            pPlayerData-&gt;pNextInCell = NULL;
7 a! [( ?9 M6 g) g! Y' e; p- s            break;
" k& j9 G$ m8 q, `' R        }
3 M/ X) K3 i" E+ Y, s2 B        pPrev = pPt;
" n3 [0 g- n$ T: s4 X4 Q        pPt = pPt-&gt;pNextInCell;
) o/ {6 P& {. m2 X: B. a& x8 e    }# B$ w1 f  a8 ?! m- @
}</P>1 Q( o) B( f1 J- R1 [. v; _2 ~7 `

$ _; ]; q! j) |$ M' b4 b! q<P>( R; t; e8 b# |! p9 B  T5 V
//-----------------------------------------------------------------------------
3 x8 x7 y7 O; E6 P/ L! C8 S// Name:
" n' G3 s& S! m+ q) z% y# E// Desc:
% y' @2 r# S- a8 L+ }//-----------------------------------------------------------------------------
, A8 ?  w) }; w  fvoid CMazeServer::UnsafeAddPlayerDataToCell( PlayerData* pPlayerData )2 \5 {+ O0 C, J* A. |
{
! f! x! B! ?9 v& [  _& a; O1 W    ServerCell* pCell   = GetCell( pPlayerData );
) }7 n; {7 m5 ^+ t6 R- `+ e+ w    pPlayerData-&gt;pNextInCell = pCell-&gt;pFirstPlayerData;
/ r( R1 g) e8 f9 @; h8 r9 o    pCell-&gt;pFirstPlayerData = pPlayerData;$ J2 N& c/ B' e1 d* W
}</P>+ H5 L! a. X* @- O# d. C  `, b

: h  W; d8 T, e+ b9 S5 c4 y% }* P<P>$ [+ Z9 j/ q! d5 s7 @
//-----------------------------------------------------------------------------
0 h/ n, d4 V, ]8 O& g  D0 v// Name:
$ o# T4 h: `' [7 A// Desc:
! \5 e/ v6 f/ [9 z# Z/ ]; j0 L//-----------------------------------------------------------------------------
2 [; K7 s3 @* t, ovoid CMazeServer::HandleClientPosPacket( DWORD dwFrom, ClientPosPacket* pClientPosPack )
% @1 h) @& T% b( {: v( g{
7 M0 k+ s4 ~. I; S8 D+ B    // Grab player for this client and lock it  \& j! W# q) ^9 V# c7 f
    PlayerData* pFromPlayer = GetPlayerDataForID( dwFrom );- D/ X4 |1 W3 u9 h# ^+ v
    if( pFromPlayer == NULL )- |9 i1 P5 g- g* x  G) s# b' ?
    {6 v; ?# b3 p* j% i( s
        if( m_dwLogLevel &gt; 1 )/ v" ~3 i5 I+ ]- U
            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Could not find data structure for this player"), pFromPlayer-&gt;NetID );
; }7 }  K* ?2 c1 c        return;
) u- T8 M! I5 Q. E/ D3 G    }</P>, l( O/ j" r" z+ H% p: g. K! n
<P>    LockPlayerData( pFromPlayer );</P>
& B6 O( }$ k' L<P>    if( FALSE == pFromPlayer-&gt;bAllow )
" R) H3 d2 J9 m# f' m    {
7 W6 _0 e/ Z5 z8 p) U( d, L        if( m_dwLogLevel &gt; 0 )3 I% Y9 C% m3 n2 V
            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Got position packet from bad client.  Rejecting client"), pFromPlayer-&gt;NetID );</P>
6 j$ b2 z, S6 K2 {3 z) T* k- [<P>        m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );
1 ]' ]- I" m  u7 Y2 x# N0 G        UnlockPlayerData( pFromPlayer );6 x' c/ Y* d1 m9 L
        return;
7 n  ?" B9 i) G! |    }</P>
% T/ G4 M- z! [<P>    // Compute the cell the player should be in now
* o7 r- J" E4 D    DWORD newcellx = int(pClientPosPack-&gt;fX);% j+ D$ b/ g$ b
    DWORD newcelly = int(pClientPosPack-&gt;fY);+ q# e2 D8 v$ X6 t1 o5 U0 h, h
    DWORD oldcellx = pFromPlayer-&gt;wCellX;
- F9 p) C9 c; y# o8 A% a, I5 |6 i    DWORD oldcelly = pFromPlayer-&gt;wCellY;</P>; v. a" U9 J. s( |* S( n% e
<P>    // Have we moved cell?
5 l; h% A% B5 q* m7 Q& G  y    if( newcellx != oldcellx || newcelly != oldcelly )" q& @# z, Y1 h$ S' U
    {( k+ _8 X9 [( s. w5 c1 r
        // Yes, so lock the pair of cells in question9 S# K4 j+ [. Y$ o$ k
        LockCellPair( oldcellx, oldcelly, newcellx, newcelly );</P>) ^2 J% C/ W5 l  r  a2 p) b
<P>        // Remove from old cell and add to new cell0 C/ d  |& Y6 K1 W. F
        UnsafeRemovePlayerDataFromCell( pFromPlayer );( B+ j7 @2 N) ^
        pFromPlayer-&gt;wCellX = WORD(newcellx); pFromPlayer-&gt;wCellY = WORD(newcelly);! Q: L$ @( a" J8 f5 r
        UnsafeAddPlayerDataToCell( pFromPlayer );</P>
9 q: a! X% d: H; r& C6 K# O<P>        // Unlock cells8 R9 M2 o8 l+ _3 @# j
        UnlockCellPair( oldcellx, oldcelly, newcellx, newcelly );
" ~/ C$ T5 D; k# l! w7 }    }</P>
- ]  C- ^; C; J! ^4 P+ O<P>    // Update player position! |  U; @" j  ^3 u1 S
    pFromPlayer-&gt;fPosX      = pClientPosPack-&gt;fX;0 I& ?+ Q( e* F2 Q  @5 S
    pFromPlayer-&gt;fPosY      = pClientPosPack-&gt;fY;
$ w/ r3 O1 S; k1 |8 \6 U2 j    pFromPlayer-&gt;aCameraYaw = pClientPosPack-&gt;aCameraYaw;</P>+ M& O. {# F  }, n! |+ P0 T
<P>    // Allocate space to build the reply packet, and fill in header
" D: [. j9 U: y4 Y) b    DWORD dwAllocSize;. s7 P2 K7 A3 ?  r! }; b/ R
    ServerAckPacket* pSvrAckPack = NULL;</P>
/ \* H: Y, X# x" a5 R<P>    // Begin by allocating a buffer sized according to
: e1 C6 |' B% S9 l! p4 w' ?    // the current number of nearby players + 4.  This will give
* w% `" ]# s% D# d* D8 |    // a little room for more players to come 'near' without resize
# }9 }+ e% `* `  A. G# e% m* \    // the buffer.! _# ]' m( m. ^/ _: H
    DWORD dwMaxPlayerStatePackets = pFromPlayer-&gt;dwNumNearbyPlayers + 4;</P>! @6 d) w9 a/ ?6 f* f5 z$ A- K
<P>    dwAllocSize = sizeof(ServerAckPacket) + dwMaxPlayerStatePackets*sizeof(PlayerStatePacket);( m* O: z" U  J( m3 j/ H' K
    pSvrAckPack = (ServerAckPacket*) realloc( pSvrAckPack, dwAllocSize );
" u1 T8 y1 k3 k' p7 e1 u5 G& d* ]7 r    if( NULL == pSvrAckPack )- ^0 r" I2 k; b3 `
    {# u0 _0 z" r' L( V5 B5 g" U
        // Out of mem.  Cleanup and return: }* a( z2 N! T
        UnlockPlayerData( pFromPlayer );
( a' Z6 E+ ~: b0 J; |+ a        return;       + K! ~. P: u5 Q: M4 x  G. F
    }$ ~+ c; b: P/ ?* J' z+ C- w
    ZeroMemory( pSvrAckPack, dwAllocSize );</P>
# Z" k$ N; j. `6 w<P>    *pSvrAckPack = ServerAckPacket(m_dwPlayerCount);
& Y' a* O0 D* L5 e" c7 y, D    pSvrAckPack-&gt;wPlayerStatePacketCount = 0;
9 K3 r' q( q$ k6 y4 M& c8 D    PlayerStatePacket* pChunk = (PlayerStatePacket*)(pSvrAckPack+1);</P>
; ~- R, v* D' O7 E' l<P>    // Compute range of cells we're going to scan for players to send
; ^: E( M! x: m: I! n' V0 J    DWORD minx = (newcellx &gt; 7) ? (newcellx - 7) : 0;- {% S9 s8 H- O. a* o) @
    DWORD miny = (newcelly &gt; 7) ? (newcelly - 7) : 0;
- a) W+ B4 S. h5 b, \    DWORD maxx = (newcellx+7 &gt;= m_dwWidth) ? m_dwWidth-1 : newcellx+7;( E5 z* Y6 s1 ~4 r: T* Z5 _$ h
    DWORD maxy = (newcelly+7 &gt;= m_dwHeight) ? m_dwHeight-1 : newcelly+7;</P>
( T; R' P# w; j- P$ V( Z<P>    // Lock that range of cells% r) g( j. n, }+ ^) K
    LockRange( minx, miny, maxx, maxy );</P>3 o3 e! V0 B2 `- s: P8 ~
<P>    // Scan through the cells, tagging player data onto the end of
/ X8 f1 e) L" @% f    // our pSvrAckPacket until we run out of room' J' Z2 {+ d5 J$ B
    for( DWORD y = miny; y &lt;= maxy; y++ )7 l5 s) e; R8 H, T
    {
4 q$ H9 s: h4 c% W) [2 V' Y" x: o& U        for( DWORD x = minx; x &lt;= maxx; x++ )0 @9 l6 ~) d+ j( }/ {
        {% S: }8 @: i: c2 f5 i$ ^
            PlayerData* pCurPlayerData = m_Cells[y][x].pFirstPlayerData;
- J' T2 e0 @1 S" w$ B0 X            while ( pCurPlayerData )  n8 `& }" B  T. x) `- E
            {* Y" d8 [+ j; P% f" d( Q4 x( I& W
                if( pCurPlayerData != pFromPlayer )4 d, g% E  I* b- y  {6 F% s
                {) t5 k" v! T+ Z2 z
                    if( pSvrAckPack-&gt;wPlayerStatePacketCount &gt;= dwMaxPlayerStatePackets )
% y0 e4 [2 k7 H+ C) o- i                    {7 C7 t& d; Q  A1 S, {
                        // Make sure pChunk is where we think it is
) z& y8 S) x% D1 j                        assert( (BYTE*) pChunk == (BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket)) );</P>
( W* _0 e) U9 @1 z0 v<P>                        // There are more than just 4 new nearby players, so resize the ' O* G" L7 V1 e
                        // buffer pSvrAckPack to allow 16 more PlayerStatePacket's.# j/ P7 S8 `. y4 V( z, l
                        dwMaxPlayerStatePackets += 16;
; L( K- x; X$ F# w2 D& N/ y                        dwAllocSize = sizeof(ServerAckPacket) + dwMaxPlayerStatePackets*sizeof(PlayerStatePacket);% E+ w. E+ j% V/ ]- ]- s2 ]
                        ServerAckPacket* pNewSvrAckPack = NULL;
2 N  b' N& ]2 ]( I  W+ X& ~; S- a                        pNewSvrAckPack = (ServerAckPacket*) realloc( pSvrAckPack, dwAllocSize );
7 A+ d3 A* P; k' E8 K& e7 j8 a! h                        if( NULL == pNewSvrAckPack )
8 ~% X% B7 c1 {                        {/ [9 i8 y1 G; q
                            // Out of mem.  Cleanup and return
" A( d9 C3 K$ w& R                            free( pSvrAckPack );) l% f+ d  h5 \9 h
                            UnlockRange( minx, miny, maxx, maxy );. c7 }: H* l% Z
                            UnlockPlayerData( pFromPlayer );
3 u$ X* j: q* X+ O, ~                            return;      
: _! p, W6 g  s- y4 u0 }) v                        }</P>
8 w3 ^1 S2 d4 G, S2 ]<P>                        pSvrAckPack = pNewSvrAckPack;
* k% K/ Y  A2 s3 x4 m5 g& W                        pChunk = (PlayerStatePacket*) ((BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket) ) );</P>8 c4 G4 v  t, I# m3 |
<P>                        // Make sure pChunk is still where its supposed to be
6 p0 i, Y# `3 i                        assert( (BYTE*) pChunk == (BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket)) );' @! Q: Z& i* w) W7 S7 j5 f4 y
                    }</P>! g6 P, R+ g0 [0 }9 b4 V0 C( ?" V
<P>                    pChunk-&gt;dwID       = pCurPlayerData-&gt;dwID;
0 M; U% j- u* N4 k$ U                    pChunk-&gt;fX         = pCurPlayerData-&gt;fPosX;; ?' P6 v" e; [2 ]3 g
                    pChunk-&gt;fY         = pCurPlayerData-&gt;fPosY;
$ W" ^# J) p+ P' c                    pChunk-&gt;aCameraYaw = pCurPlayerData-&gt;aCameraYaw;
: K- A# R( p. _) k+ I                    pChunk++;
6 D  V  l) b7 i                    pSvrAckPack-&gt;wPlayerStatePacketCount++;
' U+ T1 c) b0 R                }
9 L3 v* E8 w( e- m* X                pCurPlayerData = pCurPlayerData-&gt;pNextInCell;
2 |/ P; j' B4 ?; @            }, z6 f0 P7 t" m" c$ ]9 y- n
        }
% N6 A2 c* ]7 f: ]  ?    }</P>
4 ~, M. q, `% s2 }<P>    // Update the dwNumNearbyPlayers for this player1 s4 }' S, O) ^" F2 N" D) C; |
    pFromPlayer-&gt;dwNumNearbyPlayers = pSvrAckPack-&gt;wPlayerStatePacketCount;</P>2 D2 h# `- |, s4 G; ?
<P>    // Unlock range of cells
, B; u: a) P2 P9 H) Y. `" u    UnlockRange( minx, miny, maxx, maxy );</P>" `3 z' H  M& G2 b( ]) v6 Z1 ~
<P>    if( m_dwLogLevel &gt; 2 )
& q. C4 Z$ p8 \    {! p, S; P4 V: W; V) h5 E7 d% K
        ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Position is (%0.2f,%0.2f)"), pFromPlayer-&gt;NetID, pFromPlayer-&gt;fPosX, pFromPlayer-&gt;fPosY );6 E  |7 l# s5 q1 ?( O
    }
. ?4 D. K6 h$ ?  X3 T+ Q' |    else if( m_dwLogLevel == 2 )
! _* s6 {8 I- K    {! E: n' G* |) A; G& r) ~/ u
        FLOAT fTime = DXUtil_Timer( TIMER_GETAPPTIME );
9 T8 V$ S" a0 T9 _/ ]- D        if( fTime - pFromPlayer-&gt;fLastDisplayTime &gt; 60.0f )  u9 j' L( j4 D. u
        {* a3 o+ q9 N3 p# y' K8 Q* r- X
            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Position is (%0.2f,%0.2f)"), pFromPlayer-&gt;NetID, pFromPlayer-&gt;fPosX, pFromPlayer-&gt;fPosY );
7 \$ J9 R9 I# x# o( e/ k: J7 |            pFromPlayer-&gt;fLastDisplayTime = fTime;; @, \  m% o9 m( @3 d+ Y
        }
* ~+ _  L5 `4 ~    }</P>3 g4 v- q- I  v# j- f* T2 l
<P>    // Unlock the playerdata! f/ e: L" W$ }+ v$ I1 W
    UnlockPlayerData( pFromPlayer );</P>
0 o! i5 X# }2 x  K3 ]7 D<P>    // Send acknowledgement back to client, including list of nearby players
' p( y" j& J4 L9 k$ i, K4 i4 i8 P    DWORD acksize = sizeof(ServerAckPacket) + (pSvrAckPack-&gt;wPlayerStatePacketCount * sizeof(PlayerStatePacket));
  _1 f9 |$ J$ z" l+ E7 D 9 i/ E) y0 R- \1 C2 w
    // Pack the buffer with dummy data.
+ F4 g. F1 }7 a9 U# Y    if(m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex] &gt; 0)8 V& p$ W  [% C0 w
    {
; V" a! n. N# }' T  T( r) r3 J        DWORD   dwBufferSize = acksize + m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex];
. y+ z9 Y1 ]# ]1 d! p        VOID*   pTempBuffer = 0;</P>" i7 @: ?: I* `! }* T) T0 K
<P>        pTempBuffer = malloc(dwBufferSize);
& U0 Z* p; f9 h        if( NULL == pTempBuffer )! @! n; E7 I" ^1 i- R% P
        {  ^( a# N3 r- y' O# D( Q7 H- I
            //Out of memory/ r6 |/ t" b. W0 U. ~+ b
            DXTRACE_ERR_NOMSGBOX( TEXT("System out of Memory!"), E_OUTOFMEMORY );5 h% L* t7 Y% ]- B: B! K8 Z' o
            free( pSvrAckPack );" q* a+ i, V9 F4 L9 M
            return;
& T' k7 n0 f/ Z. z        }</P>9 L% @9 W) N6 _5 j/ h6 @
<P>        FillMemory(pTempBuffer, dwBufferSize, 'Z');% o# ?" I% a% \" {- S/ w0 X' i
        memcpy(pTempBuffer, pSvrAckPack, acksize);</P>! \% W3 m4 X! b; |' D0 q1 i+ M
<P>        SendPacket( dwFrom, pTempBuffer, dwBufferSize, FALSE, m_dwServerTimeout );
# Q5 g8 l# f  [    / s& d" Y' ]* h3 U9 ^
        free(pTempBuffer);
$ Q( C6 R* B  w4 Q( p+ Z    }   2 `7 a, p& s0 t$ k: U
    else  C6 f( o6 ^, m" \' \3 a  y# e
    {
" A6 h. v' Q, ~1 D. w( X: H. T8 Q        SendPacket( dwFrom, pSvrAckPack, acksize, FALSE, m_dwServerTimeout );) s1 p8 G) U+ ^% F: `+ \0 ]3 D
    }</P>
8 i2 x0 e4 t/ p* w/ Y' D<P>    free( pSvrAckPack );</P># m) V7 p: }" U+ {
<P>}</P>* K; Z" @: W  H, t! N$ e
& P* U8 D7 u  K: I+ N# e
<P>/ N/ s0 a  I. T4 @
//-----------------------------------------------------------------------------1 y; @: h! ^! n$ M' b& W0 C
// Name:
! T% ~9 Z% w5 n% P2 r' W: F6 h// Desc: ' S2 Q* c5 a9 V4 z, ]3 S7 p6 e
//-----------------------------------------------------------------------------9 Y5 i* i; J6 s9 W% O
void CMazeServer::HandleClientVersionPacket( DWORD dwFrom, ClientVersionPacket* pClientVersionPack )
  C! W  S5 ]! ?; t- n7 s! ^{
& |' G" \6 h7 u: e: W    // Grab playerdata for this client and lock it7 w* Z+ J5 Y: W! h/ G5 c& ^* a
    PlayerData* pPlayerData = GetPlayerDataForID( dwFrom );
  M9 u5 h9 C6 j4 G5 P! i* b5 T& r& f    if( pPlayerData == NULL )$ J2 g7 z$ ?9 Y( g4 X7 {
        return;* y2 g% H6 ]0 z
    LockPlayerData( pPlayerData );</P>
( S8 o2 u. F- x" P( x8 i<P>    // Record the version number
( K$ X/ V9 p( h% Q- V    pPlayerData-&gt;dwVersion = pClientVersionPack-&gt;dwVersion;</P>
* g3 G. X, h: Y; p) }- }<P>    if( m_bLocalLoopback )/ B0 M7 t1 W4 d. E& s
        pPlayerData-&gt;bAllow = TRUE;  v, n- m& i, u7 y! P" e
    else8 v$ d- H( E+ R; u5 X
        pPlayerData-&gt;bAllow = IsClientVersionSupported( pClientVersionPack-&gt;dwVersion );</P>" J$ V+ f# t+ K/ y. p9 l2 ~
<P>    if( m_dwLogLevel &gt; 0 ); N4 P; F( Y2 @, C
        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>. r0 A% a& X2 z2 T* ^' d6 A$ Y7 T
<P>    if( FALSE == pPlayerData-&gt;bAllow ), D' R  {& `4 |, l. ]- o! i/ ~
    {6 d+ Z, v' z7 Q1 O7 c( R
        if( m_dwLogLevel &gt; 0 )3 ~8 U+ r& ^* {7 f4 R7 U
            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Rejecting client"), pPlayerData-&gt;NetID );</P>+ b! Z$ o, {7 p# ?$ L7 v5 J
<P>        m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );, n# d+ L) Q+ A8 a1 i# F
        UnlockPlayerData( pPlayerData );
% j! Y- v) ~( Q$ F  f$ _        return;
6 Y* g6 l5 B' Q1 J! D. w    }</P>) q3 w0 u8 X) |- d: ?* ?
<P>    // Unlock the playerdata& A6 c: `) {" o* E. t6 {5 P& A2 L: M
    UnlockPlayerData( pPlayerData );</P>
; N7 c  u+ u4 H9 W; M; B<P>    // Send acknowledgement to client that the client was either accepted or rejected. K1 d% a; x6 C2 d$ _3 C. P
    ServerAckVersionPacket packet( pPlayerData-&gt;bAllow, dwFrom );
5 f* {9 d/ i6 t6 h    SendPacket( dwFrom, &amp;packet, sizeof(packet), TRUE, 0 );
  ~5 Y) |: f  W8 E8 J}</P>
/ K9 }# J' S# M6 z) |4 I: C$ {* Q' B  R; ^2 z0 i, G9 V7 K2 k
<P>2 a  z9 ~1 K" f4 \/ j) L" f
//-----------------------------------------------------------------------------1 c" u7 _: D2 V/ p
// Name: & ^. d# W# {" W& X; W
// Desc:
9 I/ p; E5 h1 d7 R' C6 s//-----------------------------------------------------------------------------5 n8 X" r+ Z0 y) a' T
BOOL CMazeServer::IsClientVersionSupported( DWORD dwClientVersion )
+ v& i3 [: A/ i{; r8 m/ v6 }6 v( ], ~& H
    switch( dwClientVersion )
/ G7 `5 w) i9 d6 _  y1 R    {
' ~* N6 i5 W) Z9 t$ n$ b; e0 |# A: r        case 107: // only v107 is supported
7 ]+ A* J- A6 I            return TRUE;
/ _$ G. E3 f( O. X        default:5 Z3 T8 n) m6 U, }" c6 R
            return FALSE;
/ y  ?! S$ k& B    }- @% X7 \# G' }4 h
}</P>
5 u4 Y) Z' c% @4 l5 p
1 E; U* u1 |/ d- f3 E1 u<P>: j( b  w, M4 f; K) ^% O
//-----------------------------------------------------------------------------5 i5 y* t! M9 ^: d( a
// Name:   J4 n* I9 H% u3 W
// Desc: ( R4 k0 V9 H" `1 c, U
//-----------------------------------------------------------------------------
+ m7 a! I6 g8 o; x8 d7 f" G/ |void CMazeServer::HandleUnknownPacket( DWORD dwFrom, ClientPacket* pClientPack, DWORD size )
9 o( T: v# U' f. L2 _. C) q+ A{" t3 T4 a% H% o1 ^4 L
    if( m_dwLogLevel &gt; 1 )/ N8 ^+ p- i4 C- s
        ConsolePrintf( SLINE_LOG, TEXT("ERROR! Unknown %d byte packet from player %0.8x"), size, dwFrom );</P>; Q2 X8 Y+ h+ x# o6 S# \* r1 ?6 a
<P>    m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );# B$ v# ]9 J9 i' ]0 V! C
}</P>  ]4 V! F3 Q# R7 |

* \# \( }, _: ]' M# z0 k# X<P>  e; H& `/ q, M$ z
//-----------------------------------------------------------------------------4 B3 N( T5 ^& O8 n
// Name: 2 Z* p( P$ G5 q8 w0 ~. q6 R3 k
// Desc:
7 e7 c, c. j' i//-----------------------------------------------------------------------------
$ e8 b$ [' h" `# n1 ]: h1 zDWORD   CMazeServer::IDHash( DWORD id )
/ J/ z2 m  h+ W% w; y{" y' x- H, h1 c. F
    DWORD   hash = ((id) + (id&gt;&gt;8) + (id&gt;&gt;16) + (id&gt;&gt;24)) &amp; (NUM_ID_HASH_BUCKETS-1);; f4 T( W. I( b+ n. C- d
    return hash;
* }) q5 f7 `/ ]/ {7 h4 V}</P>) q- M/ k+ S( k

, X. P/ |& Q+ \' T<P>
; m4 }* [% N2 c4 L/ Q% Y+ ^//-----------------------------------------------------------------------------% s. t& B0 l) L% _
// Name:
. |5 [" _9 U9 y. c3 C0 v3 s. B4 P// Desc: " e: _; T! v! I" {
//-----------------------------------------------------------------------------
) Y: v/ c6 ~" c6 @void CMazeServer::RemovePlayerDataID( PlayerData* pPlayerData )4 @% I' F. k$ O! g6 }+ I% ~* y
{
3 J' a6 H1 c" O' T) l    // Hash the ID to a bucket number
; g& e1 Q( L" {) Z    DWORD   bucket = IDHash( pPlayerData-&gt;NetID );</P>
: h# j) b9 y' V9 [7 y* x<P>    // Lock that hash bucket7 H5 r8 C" J' l, {% h, q& o" ~0 v
    const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;5 F- t7 R3 \0 ]2 @$ |4 h7 L
    m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>
; ~7 c- D0 K8 f. }<P>    // Loop though players in bucket until we find the right one0 Z& |, o, M: E% Z  K7 F$ C, x
    PlayerData* pPt = m_pstIDHashBucket[bucket];
4 ~% W( N& X8 O1 c2 x* ?    PlayerData* pPrev = NULL;
! Y, ~0 i+ c, j: K    while( pPt )
! d8 P7 ]% S$ e: F4 L- m    {
$ C  [3 O- W( Y        if( pPt == pPlayerData )
+ j6 P4 M  M$ |            break;- ]2 l* u5 r6 o* e
        pPrev = pPt;
- w1 t5 o+ H' F        pPt = pPt-&gt;pNextInIDHashBucket;
0 t! j* M; T4 _" o; g8 v; U! E    }</P>: v/ L: I# k; ~+ I
<P>    if( pPt )
! s7 e) \1 i) f) o) b- \- b. h! `9 Z    {3 u8 W& j( _) k5 I* W
        if( pPrev )4 f" G3 ]' O7 `
            pPrev-&gt;pNextInIDHashBucket = pPt-&gt;pNextInIDHashBucket;7 @8 l2 W7 U) A4 s  t6 k/ h1 V" [$ |
        else
4 r8 A; f2 [. |9 N            m_pstIDHashBucket[bucket] = pPt-&gt;pNextInIDHashBucket;
: q3 [/ Z/ T2 u0 [" e        pPt-&gt;pNextInIDHashBucket = NULL;8 |8 q" g% u& \$ `/ Z8 N. ~. I* q0 ^
    }</P>! j6 e, U7 Y0 L+ w
<P>    // Unlock the hash bucket. Q/ y0 c9 ]0 O' n
    m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();7 T8 Q6 e. m1 Q' s, S' Q: o0 ?
}</P>: S& `9 L' f. h' V2 N% {

! y9 N1 j& ~/ R  J<P>, I. e  l! ?+ h) X! s0 @9 r
//-----------------------------------------------------------------------------
. q" F( I7 R$ k# U8 J// Name: + [% [% S/ T% I0 \) T
// Desc:
9 T; L& K) K9 }- M- q//-----------------------------------------------------------------------------3 {$ u# W0 b) k! H- _
void CMazeServer::SetPlayerDataForID( DWORD id, PlayerData* pPlayerData )
1 r6 g* A' h* i, l{
, Z1 n9 ?$ m" K6 h0 n    // Make sure this player isn't added twice to the m_pstIDHashBucket[]
0 i3 `3 t! c0 j    // otherwise there will be a circular reference
1 }& y; s: e2 P0 E8 x0 \) a    PlayerData* pSearch = GetPlayerDataForID( id );
4 e7 O# \, H& z- X7 f! J* v; D    if( pSearch != NULL )8 r: o. Z, a3 Y3 [# ^7 f
        return;</P>
: q. e7 }% W3 t- \; i<P>    // Hash the ID to a bucket number
4 ~7 f9 b# g; H' n" e; V    DWORD   bucket = IDHash( id );</P>
, o" \  h, ?5 \" s2 t0 r<P>    // Lock that hash bucket
! z4 e' z' ^# l, u2 |3 o    const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;
# [/ G3 [4 b/ M2 Q    m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>( A1 m% t% q9 n* L2 Y  Y( H1 N/ H
<P>    // Add player onto hash bucket chain
  g* n$ J9 B6 U! z+ O    pPlayerData-&gt;pNextInIDHashBucket = m_pstIDHashBucket[bucket];9 r- u4 i2 b6 t! s0 [" x
    m_pstIDHashBucket[bucket] = pPlayerData;</P>& x: j7 @  i) ?6 [, p; \
<P>    // Store net id in player
0 }& L5 U) K% t- F) C8 o1 j! Q    pPlayerData-&gt;NetID = id;</P>8 R, U" {$ z+ K7 Z' Q6 Q9 ]7 I
<P>    // Unlock the hash bucket8 }) }+ O0 T8 p
    m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();
* m5 Y' A) ^9 T! E( j' t* `, s}</P>
' T$ O9 W" l3 ^6 r+ q/ G- V% b& b0 T0 R8 G" Q
<P>% B0 B( r" A. V2 {8 Y- A
//-----------------------------------------------------------------------------( [) y$ I& c, l* M! S" @! T5 [
// Name:
) i# ^: y! X, u1 V5 f  U' R# c2 F// Desc: ; t9 X1 N1 I$ t! k9 z
//-----------------------------------------------------------------------------! F- s8 l( h* B: \* X" q0 l- b
PlayerData* CMazeServer::GetPlayerDataForID( DWORD id )
% t* N% U$ d3 \. R+ o6 D) r4 O; U$ i9 }  o{
, Z4 y# s/ G( o% V( u, _    // Hash the ID to a bucket number3 y. N- U4 B; F
    DWORD   bucket = IDHash( id );</P>
6 v: B# s# U1 ^# W<P>    // Lock that hash bucket* V! q" s3 f: H" S1 G) {
    const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;& c/ O7 R5 y; @2 `3 j9 l4 C
    m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>/ A8 A+ Y5 i  y, F0 b7 \( `
<P>    // Loop though players in bucket until we find the right one
( A& X" o& j) @- b    PlayerData* pPlayerData = m_pstIDHashBucket[bucket];+ f: l; D4 W; t" u0 W8 k
    while ( pPlayerData )& u+ \) u2 Q( T1 Q9 t
    {
# I2 a. C7 o: m/ b) ?, _# Q        if( pPlayerData-&gt;NetID == id )
; w7 E8 [& J  [7 Y9 M% Z. W            break;8 J- G; s: T3 U0 ]6 _
        pPlayerData = pPlayerData-&gt;pNextInIDHashBucket;- w$ G, ]! o7 |) Q
    }</P>
5 ]. z0 d6 z- j<P>    // Unlock the hash bucket* Z9 i+ k/ ]. k- s7 j( T* ^. y9 @
    m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();</P>" J- g; O3 p. W. x  d( }
<P>    // Return the player we found (will be NULL if we couldn't find it)
, o2 l2 O: V/ b7 G( w    return pPlayerData;
( _5 v0 h+ E' E! }* {( K}</P>
  a; z: ^! T: r5 Z8 [7 x
7 f2 U7 V( Q1 x7 ^" N<P>
! J; o, x# ]0 U//-----------------------------------------------------------------------------0 B1 v! `2 r- W3 ^1 j  B
// Name:
4 F8 x8 l4 |  M$ w) N4 }5 [1 Q, w' _// Desc: calls DisplayConnectionInfo for each connection in a round-robin manner
2 N2 p" _# s3 _# t5 [* Z# J! n//-----------------------------------------------------------------------------
( O( Q1 ~- q( x3 ]/ Jvoid CMazeServer:isplayNextConnectionInfo()
. @5 h$ o6 {" e& o9 F$ @{& J1 f& h4 ?5 ^2 K( O: G( v
    if( m_pNet )- Y+ r$ @! P, l2 L: y0 |
    {
" G  @  _. x! j  f, |' L( q        // Find the player that was displayed the longest time ago, and display it." q1 N! H4 S4 R5 z) k
        FLOAT fCurTime = DXUtil_Timer( TIMER_GETAPPTIME );
7 Z+ \: k% X" k& B3 z" A# D        PlayerData* pOldestPlayerData = NULL;
. P7 P. Q' |7 c3 _0 L* j$ k* W* L/ {        FLOAT fOldestTime = 0.0f;</P>
5 o/ y- F& m# F% Y3 @<P>        m_PlayerDataListLock.Enter();</P>
0 @  E- g- Q" F; a' Q6 Y<P>        PlayerData* pPlayerData = m_pFirstActivePlayerData;7 I1 u$ N0 y+ K" Z
        while ( pPlayerData )
* j2 ~+ F: W* w& D        {
1 z& {% [% _3 j% |7 I) n! _. {7 Q  s            if( fCurTime - pPlayerData-&gt;fLastCITime &gt; fOldestTime )
7 {+ h  n: Q: t) U+ F            {  j. N- l9 C8 U5 a' J- T1 P
                fOldestTime  = fCurTime - pPlayerData-&gt;fLastCITime;
- G0 d3 N( D  q: Y- j! _% D                pOldestPlayerData = pPlayerData;! n9 b# b9 c1 D% l
            }</P>5 {) X- ~1 ?9 Y; X; M
<P>            pPlayerData = pPlayerData-&gt;pNext;
: G+ }1 n" }& P6 L- ~% d& ?        }</P>
& p8 Z- R$ p& v+ M<P>        // Display the player with the oldest CI field, and update its CI field.
% l7 J$ R6 p2 |        if( pOldestPlayerData )  f" |) m% ?# e* J0 R/ }" J# R& h, Y
        {
* _# }! e9 D) y  m$ \3 f' F8 `            ConsolePrintf( SLINE_LOG, TEXT("Displaying connection info for next player") );3 @% n  I5 O4 c9 O5 B
            DisplayConnectionInfo( pOldestPlayerData-&gt;NetID );. K1 w9 f7 G4 S  A/ Q4 B
            pOldestPlayerData-&gt;fLastCITime = fCurTime;5 s- P7 D6 P) U1 }- u+ e
        }$ H0 [* I- p4 K4 D7 f1 q# p/ q
        else. O: D7 q) }! }1 H9 W8 y
        {; H+ e( d8 A& n* |; @
            ConsolePrintf( SLINE_LOG, TEXT("No players found") );+ d6 u/ v# p4 N9 c
        }</P>
  N- ~* i! a, r+ x4 |7 P<P>        m_PlayerDataListLock.Leave();
! |% [# E! h' e+ v    }
' d# Z) R" p$ G$ _* x3 b" H2 n}</P>
; ^' o% ]6 A- x1 T4 K$ d8 o2 e9 p) _: Y2 X# R
<P>- I# V  w0 |% _0 y3 G0 i
//-----------------------------------------------------------------------------# r1 F+ t+ r1 {" C
// Name:
( i5 h3 Y$ \2 {8 r! I/ a. u7 t// Desc: 5 x$ X- f+ p  t; k
//-----------------------------------------------------------------------------
$ B( T/ n+ c. Avoid CMazeServer:rintStats()5 s/ ~8 I( h$ K2 ?* X
{
* N6 t* h7 [8 F0 n    ConsolePrintf( SLINE_LOG, TEXT("Thread count: Active=%d Avg=%.2f Max=%d"), ( y7 h6 P7 r0 z
                                    m_wActiveThreadCount, m_fAvgThreadCount, m_wMaxThreadCount );
8 n! t, ]  a, L. i# X) `    ConsolePrintf( SLINE_LOG, TEXT("Thread Time: Avg=%.4f Max=%.4f(s)"),
+ m) _( S) X+ {5 D& ^, g2 o% K2 P                                    m_fAvgThreadTime, m_fMaxThreadTime );! ~- O# Q- x/ F+ g) s
    ConsolePrintf( SLINE_LOG, TEXT("Players online (not including server player): %d"), m_dwPlayerCount );
, n/ ~9 d7 a: o; @1 C; A$ z8 _; @    ConsolePrintf( SLINE_LOG, TEXT("Peak player count: %d"), m_dwPeakPlayerCount );# N2 V5 O* b. k- A: {: W
}</P>
1 K, m0 q" d- X9 u0 ^, t" W! K2 m7 Z% w/ x( `, b" ~0 E, A8 _
<P>  |  y7 R! j: x8 P2 R! x5 q
//-----------------------------------------------------------------------------
$ F& ^1 g9 J; |0 J& l6 y// Name:
% q- Y; E( E; a# v$ g: |' o// Desc:
+ [% s& }; j/ y' j  ~& q//-----------------------------------------------------------------------------2 n; @. Q1 U9 A1 n# L- @+ }$ F
void CMazeServer:isplayConnectionInfo( DWORD dwID )
( ^$ z2 W" ]  B9 ~/ d{
( E" I% B1 Z# o5 r/ `    TCHAR strInfo[5000];' H5 x, w. D. W0 ?2 ?* f
    TCHAR* strEndOfLine;
: D3 }5 U3 L5 p    TCHAR* strStartOfLine;</P>
; p) [7 [3 u( W; n# Q<P>    // Query the IOutboudNet for info about the connection to this user1 J) v* N1 W- h/ }7 `5 }
    m_pNet-&gt;GetConnectionInfo( dwID, strInfo );</P>  c3 [# I& m# h+ |& S: q8 l; _, C
<P>    ConsolePrintf( SLINE_LOG, TEXT("Displaying connection info for %0.8x"), dwID );
. o  @$ ~5 x# M    ConsolePrintf( SLINE_LOG, TEXT("(Key: G=Guaranteed NG=Non-Guaranteed B=Bytes P=Packets)") );</P>
9 n; }( I8 G. Z9 r, ~7 w<P>    // Display each line seperately
# ?# ^  E- N% C4 ?$ f; J    strStartOfLine = strInfo;
3 n% Y" `. X! V) q    while( TRUE )
9 ^- A+ U7 u6 G6 ^5 W1 s9 J    {# a5 {5 p9 j' X9 g0 P" k
        strEndOfLine = _tcschr( strStartOfLine, '\n' );8 u0 Q; X! r) n7 j2 ~+ ?
        if( strEndOfLine == NULL )
: }1 |: ^3 b7 Z" B$ q2 |            break;</P>6 M* O+ b( w0 n
<P>        *strEndOfLine = 0;
; y: a: n# @* T        ConsolePrintf( SLINE_LOG, strStartOfLine );2 A( f, [( u- N4 X+ K/ o6 G( \
        strStartOfLine = strEndOfLine + 1;( n* E% \8 w. x* k3 n+ i. n6 e
    }
# b' W, f& H3 n" M% N}</P>! G4 l# t+ |# _' y, R; [

8 l2 f) Y# ~0 _2 Q4 K1 S. w<P>/ T5 ^2 {2 O0 @! t2 }
//-----------------------------------------------------------------------------5 y4 q2 k6 N6 x$ G
// Name:
  O$ [4 ?( w4 R  b3 f& ^// Desc:
& b% F; r+ G0 H- o/ }//-----------------------------------------------------------------------------
8 ^) r) {. J" X4 W/ q6 XHRESULT CMazeServer::SendPacket( DWORD to, void* pData, 5 ~9 O$ h% h" {) M% S9 B0 G2 G
                                 DWORD size, BOOL reliable, DWORD dwTimeout )0 U' @% Z5 z4 [1 Z$ z
{5 q5 Y0 ^' U) [: P+ }9 X
    // Chance of forcing any packet to be delivered reliably, d# @. Y: u$ f5 o8 C# d4 v
    if( m_Rand.Get( 100 ) &lt; m_dwServerReliableRate )* ]- B$ e: }3 X
        reliable = TRUE;</P>
( J9 \3 D# B* A" ]( k+ ^, ^) X<P>    return m_pNet-&gt;SendPacket( to, pData, size, reliable, dwTimeout );, M  j1 v$ k7 U
}</P>
1 V1 f( t/ ^" x
5 d2 R. ?2 |+ n* R; o/ E<P>
$ E0 C  X' A! R//-----------------------------------------------------------------------------$ i3 w& E" a8 g: j4 x: K& Z
// Name: 0 _; r. x& j/ ?& O
// Desc: 2 M9 T, P7 f4 t) N& R/ Y
//-----------------------------------------------------------------------------# _, J2 m$ j  X/ X" N" ~, E8 t
void CMazeServer::SendConfigPacketToAll( ServerConfigPacket* pPacket )
0 ^5 E) y* @0 m2 m& \{: r$ h& [9 \6 S5 q1 A
    // If we're up and running, then send this new information to all clients- F2 Q6 u% Y, M- F5 W, X* i
    if( m_pNet )( z  Z6 C8 _  B- i2 s7 Q8 M
    {
& ]+ ^4 i, e: w* ]        //Use the AllPlayers ID2 F, }" t1 Z' V( v, ]3 G- C
        SendPacket( DPNID_ALL_PLAYERS_GROUP, pPacket, sizeof(ServerConfigPacket), TRUE, 0 );
5 e% n0 f4 {* b, F2 G6 V    }
1 w5 t9 Y, V5 D) s}</P>
3 w$ p) w% z, z* F# X6 q( l. O9 l5 g6 o7 @8 T- U0 ?# X+ I
<P>' V  ?% U# {: y1 ]7 D- y7 }
//-----------------------------------------------------------------------------  R/ c" D/ h: h4 c
// Name:
' c; e- U7 c6 M, U; \// Desc: 3 N5 A6 N4 Q% x8 B, ~: w: {
//-----------------------------------------------------------------------------
% ]  F2 ]- o( ]% ?7 J: V6 J1 jvoid CMazeServer::SetClientReliableRate( DWORD percent )
$ d; d( i# ]6 o6 Z! F{' i$ |+ j8 j) t
    // Update client config, and build packet containing that data7 n* L- F0 y5 j1 K" q& L
    m_ClientNetConfigLock.Enter();
7 N3 ?$ r6 ]9 U7 P6 |    m_ClientNetConfig.ubReliableRate = BYTE(percent);" B9 C* }4 b( K7 W2 r- h
    ServerConfigPacket packet( m_ClientNetConfig );; q0 }4 T: v) W: @( I1 E; F4 z
    m_ClientNetConfigLock.Leave();</P>' A' K) N1 m% |" o6 q
<P>    SendConfigPacketToAll( &amp;packet );
+ k" w: _4 Z. {- h6 |}</P>
; B/ r5 m" Q0 t9 B3 l
6 J2 b1 e+ v# ^( _. P" w<P>+ J! N- h( E6 i, x
//-----------------------------------------------------------------------------0 s0 V) R$ e- E
// Name: * u$ P! E$ W3 P
// Desc: $ c  O" O# N9 x, Z( p: U3 r7 e
//-----------------------------------------------------------------------------
* F9 h8 |3 L1 wvoid CMazeServer::SetClientUpdateRate( DWORD rate )
# ^) F: U+ I( V& g% z8 R% D' O+ X{
' B& B$ ^! J; Q. k' f( ^& V8 o* o    // Update client config, and build packet containing that data
, P# a! P, P7 a- M' f+ K    m_ClientNetConfigLock.Enter();6 X9 \. w! ?) k! Q0 T& Z1 ~
    m_ClientNetConfig.wUpdateRate = WORD(rate);3 q& {% B8 t6 n9 W' I6 _
    ServerConfigPacket  packet( m_ClientNetConfig );
2 J" y4 H) I$ m' T- i8 l# A0 R    m_ClientNetConfigLock.Leave();</P>
8 r0 }  }9 B8 I8 D" a. H<P>    SendConfigPacketToAll( &amp;packet );
- ~7 _% f* }9 R. U1 L}</P>( Y$ l9 e# n. e' j% q, z' c+ L

1 [1 c! S5 P+ T7 c+ O% P<P>9 Q. ~. N4 F! n+ N( P
//-----------------------------------------------------------------------------
( i- K; l& `' T, P$ F; e" m+ e// Name: 8 @  J; n5 z7 ]- H1 i- v! w
// Desc:
1 p; `& V5 Y( u, x5 i: d& s5 ~9 N//-----------------------------------------------------------------------------: J# v1 p6 L. \% ~' V) G4 w. D
void CMazeServer::SetClientTimeout( DWORD timeout )( d) Y# h. N2 @7 h
{
% q) u! I' H- z5 G# Y5 V    // Update client config, and build packet containing that data! [4 L  ?2 g& t' f. ^6 W# B" ~
    m_ClientNetConfigLock.Enter();
3 X' J! `- A* z, |5 U: l! Y- r    m_ClientNetConfig.wTimeout = WORD(timeout);
( k# ]& h' c; X. |" i    ServerConfigPacket  packet( m_ClientNetConfig );
, W: h8 C& [2 Z, K    m_ClientNetConfigLock.Leave();</P>/ a2 V6 W3 z# i! D
<P>    SendConfigPacketToAll( &amp;packet );
1 D0 {: Z4 l3 \}</P>
- V3 _# y1 M5 j7 w/ f& D* H2 h# f: ^% @/ P
<P>' ^2 `. n, R  o4 Z  v& _( l5 R/ o" g
//-----------------------------------------------------------------------------9 ?* ]' h7 P( e: u4 h* G6 k# B
// Name: 1 L9 B% q9 @# b7 E
// Desc:   |7 A3 |) e6 \3 ]0 s$ f. ~
//-----------------------------------------------------------------------------9 L2 `! D! n1 k  r9 J4 t
void CMazeServer::SetClientPackSize( DWORD size )2 i: s9 j5 s# J  k( @
{8 Q4 k" x; s3 e4 v
    // Update client config, and build packet containing that data
  i& d) h- }0 A, ~1 F% X* W. u    m_ClientNetConfigLock.Enter();
2 n2 h) H, N; x  H( @) v   
1 L* |  G2 @/ K/ F    m_ClientNetConfig.ubClientPackIndex++; //Increase index and verify location in array.
$ G1 I- c7 c5 u+ l' V    if(m_ClientNetConfig.ubClientPackIndex &gt;= PACK_ARRAY_SIZE)   2 \9 E) E6 f$ V, H" ?# q
        m_ClientNetConfig.ubClientPackIndex = 0;</P>
5 n) J' l! @" Q7 r<P>    m_ClientNetConfig.wClientPackSizeArray[m_ClientNetConfig.ubClientPackIndex] = WORD(size);% U* K4 M' e' @! b) {
    ServerConfigPacket packet( m_ClientNetConfig );; h% z( j, k9 |1 {( N
    m_ClientNetConfigLock.Leave();</P>: f. ~. C- h8 @, ]  }' ]  e1 S: z
<P>    SendConfigPacketToAll( &amp;packet );+ d2 H2 b; D- j" m
}</P>
2 s6 H0 j1 B% V5 Z# [0 [
0 b8 s0 t2 p, \% D<P>
' w3 J$ Z# @' _0 y4 {/ L2 h//-----------------------------------------------------------------------------
, G% V- J+ P& M# ?8 b// Name: - l) c/ V; \* f* p% {" {
// Desc: 3 z4 j7 j) ]9 m4 u
//-----------------------------------------------------------------------------
/ h) U3 n# s/ i. R  Uvoid CMazeServer::SetServerPackSize( DWORD size )
- A+ k& ?& b" t; R1 h+ `5 y9 ^{
* C( d5 {7 K* I' `    // Update client config, and build packet containing that data# s5 b5 d# e" `0 [# b' e
    m_ClientNetConfigLock.Enter();
4 s6 T6 _: ?5 ~1 L. ^   
' F; f: w5 V/ b6 F$ O    m_ClientNetConfig.ubServerPackIndex++; //Increase index and verify location in array.
  K. v0 C; c: O* }. @- c    if(m_ClientNetConfig.ubServerPackIndex &gt;= PACK_ARRAY_SIZE)   9 D* O$ Q1 _: Z& a0 y) I& X( r
        m_ClientNetConfig.ubServerPackIndex = 0;</P>
- k3 H- A7 M* C+ k- K% h<P>    m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex] = WORD(size);$ t" [# U# \: G7 G- F# W  m* A
    ServerConfigPacket packet( m_ClientNetConfig );2 [0 `/ i3 v1 L6 i+ {& H: E
    m_ClientNetConfigLock.Leave();</P>
/ X: x/ _' ^& m' \% h, N5 ~<P>    SendConfigPacketToAll( &amp;packet );$ N9 M. p) B5 f7 f' A" C
}</P>
8 C7 h4 L# @) `. ?* f& E<P>. q$ D1 H; v  @1 M- R% i
//------------------------------------------------------------------------------ E* M( E+ f: \$ W: c* N
// Name:
/ ?% F! O. A' H7 p// Desc:
# M" k! S; W  x: {* u6 J9 ~//-----------------------------------------------------------------------------
- o5 u  W# o, avoid CMazeServer::SetClientThreadWait( DWORD dwThreadWait )
3 ?, _6 Z7 t: W; h8 @0 x" q( O{0 e" S. [) {' I0 e
    // Update client config, and build packet containing that data1 X5 [8 `5 N" R8 m
    m_ClientNetConfigLock.Enter();
2 P9 U& u+ k4 o* ?   
7 r! ]  X% L3 y' O0 B6 H7 b    m_ClientNetConfig.dwThreadWait = dwThreadWait;$ `3 B6 W8 Y3 [2 E) a; M3 H
    ServerConfigPacket packet( m_ClientNetConfig );
3 U* t9 h) A4 h! C8 {    m_ClientNetConfigLock.Leave();</P>
6 T) E! {5 F- ^' S7 W/ b& [1 y<P>    SendConfigPacketToAll( &amp;packet );+ @; h8 e; }6 P& o/ K# x( @
}</P></DIV>




欢迎光临 数学建模社区-数学中国 (http://www.madio.net/) Powered by Discuz! X2.5