数学建模社区-数学中国

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

作者: ilikenba    时间: 2005-1-31 11:52
标题: [分享]MazeServer源码示例
<DIV class=HtmlCode>
$ h6 ^% w5 `" L( Z) P7 P& {* b<>// File: mazeserver.cpp" ^; S4 {9 S$ h6 s, i9 U' n
//( v9 L8 l/ {. o( s
// Desc: see main.cpp
* n' ~: K& m! Y& S//
6 B: q8 U7 x" I0 Q8 I; ?// Copyright (c) 1999-2001 Microsoft Corp. All rights reserved.
! N) T# \+ Z: z/ @//-----------------------------------------------------------------------------3 T$ T' W# E2 q& y: A# f
#define STRICT6 C" V+ e; O0 y$ W6 ?  |
#define D3D_OVERLOADS' a7 x6 S$ ]5 w4 b7 Y( Z, X7 ?& C
#include &lt;windows.h&gt;, \) r1 z$ F: b2 j6 e
#include &lt;d3dx.h&gt;
, ~+ B% O2 R- |4 f: k+ U' \0 A7 G6 [#include &lt;stdio.h&gt;9 {8 s$ G  `  t6 L) B: a
#include &lt;math.h&gt;
' b# Q7 @! X; a& l/ r) x2 l#include &lt;mmsystem.h&gt;
9 P5 W1 E0 b7 g#include &lt;dplay8.h&gt;
% o( t  w# ~( E3 n% H$ H#include &lt;dpaddr.h&gt;
- ]7 s& q9 L9 |9 x#include &lt;dxerr8.h&gt;% z# h5 }3 \& }' v# }
#include "DXUtil.h"
& K4 g( E9 k7 @# P, A4 y#include "MazeServer.h"
, y( C) X" L) _7 Q5 n1 p. U3 t#include "ackets.h"
: X2 ~; r3 p' V/ S/ h#include "Maze.h"( ]. ^" ~! K4 l- {4 a2 ]4 r
#include &lt;malloc.h&gt;
/ B" ?* [7 g$ ^/ J#include &lt;tchar.h&gt;</P>4 n) B% ]2 L+ a, U6 r- @2 b

! J9 R2 L. w2 d) D; K4 Y<>//-----------------------------------------------------------------------------3 F  ^- a$ H% O1 e4 s; i8 t
// Name: . U" w( x, }/ I9 y( M' Y( p) u
// Desc: , m) m7 ~) l4 p0 W% ^9 D* n" {
//-----------------------------------------------------------------------------6 w8 T+ s9 i* Q2 p
CMazeServer::CMazeServer()1 m$ J* |0 M7 p: u- V, @
{& K+ c" n/ r+ O/ t1 [) g
    m_dwPlayerCount         = 0;
. R1 N. p9 l8 G# S9 B2 ?5 p   
: r0 K( `, d1 l) O3 _4 U. b3 `    m_wActiveThreadCount   = 0;) g: \8 x4 v; j7 ]9 u$ H" p
    m_wMaxThreadCount      = 0;
' \/ }% l4 e" p+ y; w% N    m_fAvgThreadCount      = 0;# W2 H) S2 _  O! L2 L% w
    m_fAvgThreadTime       = 0;
( W! K2 f0 ^6 X* O3 h* d* y. ]: V    m_fMaxThreadTime       = 0;</P>
. d5 S5 {" k. G; ]<>    m_dwServerReliableRate  = 15;! _* v) s* l' ~5 ^
    m_dwServerTimeout       = 150;! Z- k5 L" f3 z
    m_dwLogLevel            = 2;; t9 R7 w% ~( E1 O
    m_pMaze                 = NULL;</P>
! y% [4 a" p& p+ h% q7 N<>    m_ClientNetConfig.ubReliableRate = 15;, }3 H1 U9 P/ X
    m_ClientNetConfig.wUpdateRate    = 150;
2 s! H+ t2 f9 m/ |" V9 J$ F6 k    m_ClientNetConfig.wTimeout       = 150;</P>
9 b7 r& E1 p' @* O% ?! N: g& A<>    m_ClientNetConfig.dwThreadWait = 0;</P>
! v- ?2 q( o7 ~' @' @! z0 r( E7 |<>    m_ClientNetConfig.ubClientPackIndex = 0;
: Q. l$ v. l. v/ r) b  z& _    m_ClientNetConfig.ubServerPackIndex = 0;0 z4 H* i; H: E+ B& ^' v- d" d
    for(WORD x = 0; x &lt; PACK_ARRAY_SIZE; x++)
$ W/ @! k2 j& P2 x    {, w1 l3 L5 a8 N& @; u
        m_ClientNetConfig.wClientPackSizeArray[x] = 0;
# C2 }+ i& v4 W0 ~9 M        m_ClientNetConfig.wServerPackSizeArray[x] = 0;/ O& k4 \0 W  \; A. K( e
    }" ]( ~& d: v8 o4 l, K
}</P>' J- c; K5 [. ]
5 g' s5 Z# t$ s  ]0 J- T$ {
<>
, z4 T$ I2 \8 p/ y" ?3 a//-----------------------------------------------------------------------------
- `; k( O% a+ a2 a" p// Name: 7 p% L+ ~6 h* M( I7 Q$ A" u
// Desc:
9 ]& n6 T' Y1 a: e7 A1 y( p//-----------------------------------------------------------------------------
( B2 r& ~( O! a% L" T" y3 W/ zHRESULT CMazeServer::Init( BOOL bLocalLoopback, const CMaze* pMaze )! q, S4 F) P8 G8 l
{
* q; O$ r2 O5 `    m_bLocalLoopback = bLocalLoopback;
6 }5 z6 ?) F6 f) k/ _    m_pMaze = pMaze;
4 x. B) \1 J6 d3 W2 M9 P! x    if( m_pMaze == NULL )( T8 X6 v0 i9 R2 z
        return DXTRACE_ERR( TEXT("aram"), E_FAIL );</P>( F1 L6 m- r$ [, A! x. a
<>    // Grab height and width of maze
9 M/ z  R- S$ d/ _8 r    m_dwWidth = m_pMaze-&gt;GetWidth();
) @: S7 C3 _! m% W7 ~2 X+ \2 A; V    m_dwHeight = m_pMaze-&gt;GetHeight();</P>
" c9 Y- O3 Q. {* p5 r' U<>    m_ClientNetConfig.dwMazeWidth  = m_dwWidth;) A+ E& w4 R" N. e( J$ U. J
    m_ClientNetConfig.dwMazeHeight = m_dwHeight;</P>! G" @2 e! ~" `; B9 @
<>    // Validate size. Must be a power-of-2 times LOCK_GRID_SIZE. Compute the shifts.
! g: E: l4 F2 F- A8 O    if( m_dwWidth &gt; SERVER_MAX_WIDTH || m_dwHeight &gt; SERVER_MAX_HEIGHT )( R0 |4 j: h! \  ~3 k: }
        return DXTRACE_ERR( TEXT("Maze height and width need to be less than 128"), E_INVALIDARG );$ ]/ Y) Z) n! e9 O
    if( (m_dwWidth % LOCK_GRID_SIZE) != 0 || (m_dwHeight % LOCK_GRID_SIZE) != 0 )
2 W  v" {+ l# f3 W. \' R* _9 f        return DXTRACE_ERR( TEXT("Maze height and width need to be divisable by 16"), E_INVALIDARG );</P>6 f. f5 q/ G  p2 y" P% U% }
<>    DWORD scale = m_dwWidth / LOCK_GRID_SIZE;# R# K) `2 x0 y& f8 O! s
    m_dwMazeXShift = 0;  `  F4 C# |/ M: K
    while ( (scale &gt;&gt;= 1) )
' l  {' H3 Z! B8 s: S+ V& G        m_dwMazeXShift++;</P>9 C2 L# p2 k" |( Z
<>    scale = m_dwHeight / LOCK_GRID_SIZE;
0 F! R8 k0 T3 }7 L/ ^* c1 Z$ z    m_dwMazeYShift = 0;7 n0 U7 p$ A0 z, Q/ o
    while ( (scale &gt;&gt;= 1) )
" o8 B8 N; R5 k* b        m_dwMazeYShift++;</P>
& L0 _  o) Z/ ~<>    if( ((DWORD(LOCK_GRID_SIZE) &lt;&lt; m_dwMazeXShift) != m_dwWidth) ||" m$ [- Q3 @* [) Y- p
        ((DWORD(LOCK_GRID_SIZE) &lt;&lt; m_dwMazeYShift) != m_dwHeight) ): p8 U/ r7 |; ^2 p
        return DXTRACE_ERR( TEXT("Maze height and width need to be power of 2"), E_INVALIDARG );</P>0 ^& @% q4 R7 ^" m8 N5 p+ c  Q
<>    // Initialise the player list2 @7 L. A1 r9 |. P& h+ E8 W. d
    ZeroMemory( m_PlayerDatas, sizeof(m_PlayerDatas) );
7 M, G' |1 q4 d% i  F5 f    m_pFirstActivePlayerData = NULL;
+ p8 O, [, M: J7 E5 v0 X    m_pFirstFreePlayerData = m_PlayerDatas;
. Y' S- h) {. Y" n, N4 ]    for( DWORD i = 1; i &lt; MAX_PLAYER_OBJECTS-1; i++ )
0 o& k% T7 x$ a    {/ I2 ?9 r; Y( _
        m_PlayerDatas.pNext = &amp;m_PlayerDatas[i+1];7 t1 G. F1 ^" d3 D2 Q
        m_PlayerDatas.pPrevious = &amp;m_PlayerDatas[i-1];
+ y! [* ]" j  Z9 I/ ~3 S. j/ @5 K    }</P>
+ o, o% c( Q2 O( ?7 w4 E6 ^<>    m_PlayerDatas[0].pNext = &amp;m_PlayerDatas[1];
7 W4 ~) ?. C, s    m_PlayerDatas[MAX_PLAYER_OBJECTS-1].pPrevious = &amp;m_PlayerDatas[MAX_PLAYER_OBJECTS-2];  F- s7 k2 a2 G8 W# a: c: @
    m_dwActivePlayerDataCount = 0;
* B% ]) g4 Z4 o$ B    m_dwPlayerDataUniqueValue = 0;</P>7 _* g7 _; G' z6 {2 Y% g* p# f/ H
<>    // Initialise the cells
0 A+ D2 i8 _( |$ m    ZeroMemory( m_Cells, sizeof(m_Cells) );
: Z3 u3 P9 H' |    ZeroMemory( &amp;m_OffMapCell, sizeof(m_OffMapCell) );</P>
- w' I; \3 d* l0 I0 I<>    return S_OK;
2 j" X5 M( D  v) [& i3 g. @}</P>" U) k8 E1 J$ m3 v* _* C
1 Y5 j" ]9 t2 g
<>5 ]' [8 V' T; I+ z; G& S- p2 _
//-----------------------------------------------------------------------------
* V* [+ [. I9 _- i// Name:
; F% ^  W9 A9 U/ u5 Z! Z// Desc: 7 b0 H" B. F# d* g5 }! u
//-----------------------------------------------------------------------------
# u$ X2 [  g7 R& j7 y& o5 [void CMazeServer::Shutdown()
0 \8 {( E. Y$ o' Y  N- Y9 r{
' H/ ^7 W  {5 z4 M* w- X& N}</P>
3 v  m$ k. U' t! b& Q/ d6 k# U/ X& h/ _* j+ q- Z6 Z8 t
<>
7 K9 ?% i' |5 ?; \/ _( t* ]//-----------------------------------------------------------------------------) S6 ?5 B( N) ?4 C
// Name: $ |: x1 L0 w+ U+ `2 E, B, H
// Desc: ; p& a5 I/ B$ _- \2 S
//-----------------------------------------------------------------------------
, K. n7 L+ c, x9 r% d* s& K$ Dvoid CMazeServer:ockRange( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )
* o/ s! k0 Q7 x" X, C6 o$ j" B1 p3 H& @{5 C9 E# u) D% F, q8 {- b( L2 A
    m_LockGrid.LockRange( x1&gt;&gt;m_dwMazeXShift, y1&gt;&gt;m_dwMazeYShift ,2 O4 n& `2 L4 R  V% Q. X
                          x2&gt;&gt;m_dwMazeXShift, y2&gt;&gt;m_dwMazeYShift );
8 i6 m8 @- j6 J5 D}</P>
2 x' ^+ p( j8 N1 G
' h0 x& v8 L( U# E8 s2 ?# h: e, @1 b<>
$ a: c; @7 Z' s//-----------------------------------------------------------------------------/ l  o0 _+ O" R2 }! e
// Name: 6 K: L  H/ y; V# Y! E' v
// Desc: 2 G+ s' h) B+ V
//-----------------------------------------------------------------------------( H/ i' q% W% j
void CMazeServer::UnlockRange( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )
1 m, x7 b: j' P) _& W. r{
- L" X% k- E( ?% d    m_LockGrid.UnlockRange( x1&gt;&gt;m_dwMazeXShift, y1&gt;&gt;m_dwMazeYShift ,
6 W& d1 v4 b8 [: J4 o/ r                            x2&gt;&gt;m_dwMazeXShift, y2&gt;&gt;m_dwMazeYShift );
/ |# U) y) N1 a8 _1 F7 |}</P>
3 s4 o7 u: h8 T$ a  R. K$ _) W
! n0 K# Y9 L0 m1 A. m& p3 P2 Q<>- C# U1 u  m* R+ }1 b5 W6 z# Y
//-----------------------------------------------------------------------------: C) [0 o( |' d6 [0 e
// Name:
% u. k0 _3 J# k/ z+ @, d// Desc:
# L; N- K5 x9 ]- y- A- ]3 a//-----------------------------------------------------------------------------0 F) \8 ~) Z0 }. ]
void CMazeServer:ockCell( DWORD x, DWORD y )
5 g4 H9 g# l0 X. `$ a) R0 q{
) F5 r, B7 s3 H) j    if( x == 0xffff )
* k# `5 _. ]- `* U, A- C        m_OffMapLock.Enter();
2 E* c9 g8 _6 f4 V7 q    else
" P) ?2 Q& R9 K5 o, |3 [% G        m_LockGrid.LockCell(x&gt;&gt;m_dwMazeXShift,y&gt;&gt;m_dwMazeYShift);# F, m' u! N% h$ m- X8 j
}</P>; C/ @$ g' _( e) Q4 I2 m; j

8 ]( c1 ]% @9 t% W# s<>
% e8 C9 g$ x, N7 ~) r4 t- D//-----------------------------------------------------------------------------
$ ~  j8 T, Z; e// Name: ' F& b" a- H& R* r6 g8 w
// Desc:
4 @2 t' F, k. U7 R7 Y//-----------------------------------------------------------------------------
0 S* K7 F1 m3 q* p. ]* u  ivoid CMazeServer::UnlockCell( DWORD x, DWORD y )! `2 v3 Y9 B0 P- z
{! v/ x2 z/ h8 s4 S) M2 A
    if( x == 0xffff )
) r) J% S' N2 J$ ]; e" j9 o        m_OffMapLock.Leave();* R9 R! V/ O1 `4 j" S8 U  U! {  ^
    else
9 `) ~' l4 T! K        m_LockGrid.UnlockCell(x&gt;&gt;m_dwMazeXShift,y&gt;&gt;m_dwMazeYShift);
, u, s: Z$ O/ U# a}</P>4 r! h" ^9 D6 R5 T1 \4 c( c, y  o
8 K) E9 K7 Q% u  D& Y+ L+ O
<>/ }( t; b+ @1 q/ K# Y
//-----------------------------------------------------------------------------
- d. K7 @5 G- f/ ~/ L& Y// Name: : y/ g# q3 ?: K" }" E3 \  W
// Desc:
- {# R! }; h9 D- S//-----------------------------------------------------------------------------
! E' I- H( z9 R" C) w% wvoid CMazeServer:ockCellPair( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )+ c% w1 E$ f3 r  Z! B% j+ ^5 R8 F! p& K
{
+ o* [$ Y( p  [$ |. }5 T    if( x1 == x2 &amp;&amp; y1 == y2 )
& [( f- T. A5 ]$ @    {
8 {* J6 S% |( e+ A+ x: [8 c/ I        if( x1 != 0xffff &amp;&amp; y2 != 0xffff )* G3 |5 M! \  z& y8 A; f
            LockCell( x1, y1 );: j2 e7 O8 r  j2 p7 f
        else  g8 [& X6 P% o/ T8 r& \0 l
            m_OffMapLock.Enter();</P>+ D0 n1 M6 d) O" G* S4 \! h
<>        return;
0 d; g' R, s% v    }</P>
  f: d& Y9 a! \<>    DWORD x1shift = x1&gt;&gt;m_dwMazeXShift;2 B5 V9 ?' X# ?6 i* v" W# E
    DWORD x2shift = x2&gt;&gt;m_dwMazeXShift;
7 m$ @$ z4 Z) t4 G0 \+ @0 y    DWORD y1shift = y1&gt;&gt;m_dwMazeYShift;
, i0 I( ]5 ?; ]( W/ O# |7 O% o    DWORD y2shift = y2&gt;&gt;m_dwMazeYShift;</P>7 C0 H2 e+ m" q2 L1 q
<>    if( x1 == 0xffff ), J) \6 J! d9 f2 m5 ~
    {: d5 j5 {+ Z- w% N1 W3 p' ]
        m_OffMapLock.Enter();
' M0 @2 {$ _& ~" P3 R( X        m_LockGrid.LockCell(x2shift,y2shift);4 B) o5 U2 n1 \9 d, K) w) j* H
    }" y, M& O+ _  O0 E; _7 ^
    else if( x2 == 0xffff )
# V  s- k2 `- u8 C9 ^9 j    {1 C# b0 @3 G7 }" F: @
        m_OffMapLock.Enter();8 ?: ]0 n* {: Z- t) n6 X3 R
        m_LockGrid.LockCell(x1shift,y1shift);" q9 B, p6 B# W2 v! z4 Y5 I, x
    }
3 ]. d8 W0 a, i- v, [: @( v    else % Q  R1 r( h, j1 y; [+ h$ m4 ?
    {
  g7 T! r$ \# n' Y; j        m_LockGrid.LockCellPair(x1shift,y1shift,x2shift,y2shift);
% m% c, ~$ p  t* y9 F$ Y    }$ O6 R" T" a% f/ j* L3 O" j
}</P>! r* O: R' Y8 J7 e& O
6 ^$ J% j" }0 O2 ~; G9 l9 R: j
<>
, w& H  n% K+ U! x0 d0 A//-----------------------------------------------------------------------------7 [, V; X0 I7 r+ r9 s- Y( b0 `
// Name:
; M/ q$ S' A+ r& ~, N) {- N// Desc: & Y2 Q! M4 n; O
//-----------------------------------------------------------------------------
9 K. v; V9 B, C, \, ^void CMazeServer::UnlockCellPair( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )
3 ~7 Z, v8 p: \4 m0 P# [9 M% L0 z+ u{: r6 D- e* ?5 a. g
    if( x1 == x2 &amp;&amp; y1 == y2 )
8 M7 o; k8 J3 e/ b. @    {8 w' d; S1 u6 W( N; T) z
        if( x1 != 0xffff &amp;&amp; y2 != 0xffff )
$ @( |1 [+ X0 k0 w1 K: D            UnlockCell( x1, y1 );
, n/ m# O- ~4 Q- k! [4 Z9 @        else
9 {; g  z, L- u( ^1 `' d. B5 {$ J3 ^            m_OffMapLock.Leave();</P>1 s0 f9 u- k3 t/ _
<>        return;* _# I2 n$ ^5 F2 m& K, |; U
    }</P>
5 g# T# U, T7 x0 A/ V  I<P>    DWORD x1shift = x1&gt;&gt;m_dwMazeXShift;( z% _" x1 [5 {7 |( Z) a0 J
    DWORD x2shift = x2&gt;&gt;m_dwMazeXShift;$ K2 A1 q0 S$ B& Q
    DWORD y1shift = y1&gt;&gt;m_dwMazeYShift;, d  K0 c- b, X' L4 Y7 a0 g
    DWORD y2shift = y2&gt;&gt;m_dwMazeYShift;</P>4 r; k# J2 @8 k% G6 s# J
<P>    if( x1 == 0xffff )) P) K+ B, ^% u/ _& c1 I' T  p
    {# O( \$ N. @- T& K: j, i9 [4 k$ w
        m_LockGrid.UnlockCell(x2shift,y2shift);
/ l+ v' j# J+ A! W$ z4 }        m_OffMapLock.Leave();8 m& P) Z% F  O, N4 e
    }
# N5 O- \9 o1 v' i) u" r" I    else if( x2 == 0xffff )( K4 ?5 p1 C/ l+ [. v$ ~. I% R
    {
+ d; A# I5 t2 W# h9 R  L        m_LockGrid.UnlockCell(x1shift,y1shift);
0 [- X7 P! n! w# Z& z        m_OffMapLock.Leave();
( f  z+ U' g2 @& n& W    }
' Q7 a3 f* S# ]& |" ]    else . ?# Z- t5 P" ~, f5 y& a
    {
6 ~2 k* a9 O4 p! z. C        m_LockGrid.UnlockCellPair(x1shift,y1shift,x2shift,y2shift);
: W" M  [3 |7 y5 G4 ^. [+ I5 e' Q/ p    }
9 H6 ]3 {" _9 m2 S}</P>
2 Z- d6 V2 N; t2 ~% V% ~; m3 [) E2 }  c/ H* G4 A+ D
<P>
: |0 k0 e" T, T. M3 G//-----------------------------------------------------------------------------; k* q, s6 Z# H: X' I# l# I
// Name:
/ ~6 }2 \/ f& U) n. R# Q  P// Desc: " K- `8 G6 H( F! p( Z& C5 l- e
//-----------------------------------------------------------------------------
) {. A# s9 k" Hvoid CMazeServer::OnAddConnection( DWORD id )' N, X6 w( R2 }
{
2 s! U1 z& i4 a2 b    m_AddRemoveLock.Enter();</P>
; B: X: {  }1 o/ f0 ^5 {<P>    // Increment our count of players
: F% M) [% b) _    m_dwPlayerCount++;
5 e+ N( T. _; `( u! \    if( m_dwLogLevel &gt; 0 )
8 c/ `$ z, E% s, {4 \- h    {2 R- z" Y& I: D1 M/ K2 i
        ConsolePrintf( SLINE_LOG, TEXT("Adding player DPNID %0.8x"), id );
# \/ O' [" Q; ]; t& i        ConsolePrintf( SLINE_LOG, TEXT("Players connected = %d"), m_dwPlayerCount );
1 Y, r6 t' w" `" t( F    }</P>
2 `. u- T! m  R<P>    if( m_dwPlayerCount &gt; m_dwPeakPlayerCount )6 b6 P' A+ b  L& ~. H* ]  g% K
        m_dwPeakPlayerCount = m_dwPlayerCount;</P>
7 t- S" g0 ]& j$ K0 E* T; l<P>    // Create a player for this client4 H6 S0 Z5 n  [, F: U% H
    PlayerData* pPlayerData = CreatePlayerData();
. N! n* ?; s4 _/ R  c9 @" K$ W& m    if( pPlayerData == NULL )
% I1 Y* `2 v2 j$ e    {: @* L1 e  K$ Z5 K' m5 u
        ConsolePrintf( SLINE_LOG, TEXT("ERROR! Unable to create new PlayerData for client!") );
/ ?1 M3 m( S2 B* h, i; K; r        DXTRACE_ERR( TEXT("CreatePlayerData"), E_FAIL );
% o$ H* b8 G0 T8 T$ r+ r        m_AddRemoveLock.Leave();
' }# h! G2 H- c0 _3 r        return;
) {5 L3 d4 U# {; @4 j4 C    }</P>/ V) N( w  W; s1 t& V9 K
<P>    // Store that pointer as local player data: ]; H" ^7 _* e$ R% ]2 u9 T0 Q
    SetPlayerDataForID( id, pPlayerData );</P>
8 i( B* C$ w+ z' Y! k( C8 z<P>    // Grab net config into to send to client; D6 Y, h! q; d
    m_ClientNetConfigLock.Enter();
4 W' C) F4 e# Z/ F1 |    ServerConfigPacket packet( m_ClientNetConfig );
! U# A( L9 g( [6 G; Q2 d- t    m_ClientNetConfigLock.Leave();</P>; [/ _$ I" g8 z% r- R2 a7 |/ P
<P>    // Send it
! p( }: ~! Z5 h; c/ q8 z' r    SendPacket( id, &amp;packet, sizeof(packet), TRUE, 0 );</P>- Q0 K: S+ G' Q. S
<P>    m_AddRemoveLock.Leave();1 i. U. R! B0 `" V+ v/ J1 ^
}</P>! E% F% X" u* A* {6 y# m
$ _. g4 C3 S/ |
<P>: H5 ~. E9 P" T5 X
//-----------------------------------------------------------------------------( `! L' F) h9 |) e# r
// Name:
7 u. q2 E5 e- [: C7 @( R9 B// Desc: - w# h3 A2 [- d5 w+ w) @
//-----------------------------------------------------------------------------; \2 m1 K' f' y0 c! S; N# H+ @
void CMazeServer::OnRemoveConnection( DWORD id ): m; b+ t% Y) b& ]* o4 B
{
+ Y% ^& A7 C' G; H    m_AddRemoveLock.Enter();</P>
. W. P) y& ]  Z6 o  H& e<P>    // Decrement count of players& i& Y1 T" u6 C* K! ?4 r
    m_dwPlayerCount--;</P>0 B$ J' U. j  X3 P: l
<P>    if( m_dwLogLevel &gt; 0 )
! V% Q# L& O, L; z    {! O6 I' R+ P5 ^
        ConsolePrintf( SLINE_LOG, TEXT("Removing player DPNID %0.8x"), id );
! z% R% @' O6 X        ConsolePrintf( SLINE_LOG, TEXT("Players connected = %d"), m_dwPlayerCount );
2 ]* H) u# h) u2 p1 I" t0 e    }</P>
4 s) Y8 |' p2 R- Z0 W2 p6 U<P>    // Find playerdata for this client( u4 M1 Z- b1 _* n2 F% d' _! O
    PlayerData* pPlayerData = GetPlayerDataForID( id );
' n5 V& s4 R2 f/ u    if( pPlayerData != NULL )! {, X$ S1 ], }) {+ L
    {7 i6 d$ A0 a. O1 b
        // Destroy it
, J! k* v, J5 i; ?! k% U        RemovePlayerDataID( pPlayerData );
2 n7 `/ ^9 R( g' p+ x8 m1 V8 V/ T        DestroyPlayerData( pPlayerData );/ \! h; m% s0 s0 x( U
    }</P>
3 C; g: C7 b5 X. `5 \4 E<P>    m_AddRemoveLock.Leave();
+ C! `0 Q7 o; n}</P>
8 n+ y" v" L( I9 F4 X2 ^+ S. D" j7 b3 `" a' d( b. `7 T
<P>! i: p5 ~. P6 `! {1 r) P2 a" E! A
//-----------------------------------------------------------------------------
5 ?: P& ?$ n8 P( O0 T// Name:
" G  q6 e7 |4 Q// Desc:
  Q3 A+ g" f; J  q8 v- V  P2 D! b//-----------------------------------------------------------------------------
' n& W: C0 h( }" D9 b+ JHRESULT CMazeServer::OnPacket( DWORD dwFrom, void* pData, DWORD size )& W; x1 m! `1 R- Y5 b$ Q# i4 Y
{
) |, J# \& p$ ~1 e" A    BOOL fFoundSize = FALSE;</P>
; \" @# W* C7 ?5 c, }9 m<P>    // Increment the number of thread we have in this process.& W% K! V; X6 V$ Z
    m_csThreadCountLock.Enter();</P>
7 G6 ^+ e$ Q8 K: Z' S) c<P>    //Get the start time of when we entered the message handler.! O8 M- }- C' V
    FLOAT   fStartTime = DXUtil_Timer( TIMER_GETAPPTIME );</P>" f& |1 d# _; n0 j
<P>    m_wActiveThreadCount++;9 c6 X/ ~5 h8 f. L$ {& ~- e
    if(m_wActiveThreadCount &gt; m_wMaxThreadCount)7 L6 Q5 F9 J1 X4 ^2 V, @6 p0 ?0 q" ]
        m_wMaxThreadCount = m_wActiveThreadCount;; D; \7 G1 U% F; K+ t2 O) ?% v
    ! s- X; P0 S  S$ v/ c- S
    // Calculate and average.+ C9 |3 ~. g! t. r3 k5 T" q
    FLOAT fdiff = m_wActiveThreadCount - m_fAvgThreadCount;
, S% y7 A* g# ^5 U6 \* o    m_fAvgThreadCount += fdiff/32;! L- ]. C/ a) b& E. K% _
    : v9 L9 r6 S4 w
    m_csThreadCountLock.Leave();</P>
5 ^, G2 v) p6 N0 E<P>
* `  X& b: \3 `$ }3 b    ClientPacket* pClientPack = (ClientPacket*)pData;
5 Z  C5 W0 _0 Y9 J) _# b8 H    switch( pClientPack-&gt;wType ), n- Q7 J* R  S: a
    {6 B0 H( T2 u9 d2 z( y6 q
        case PACKETTYPE_CLIENT_POS:- V, |0 Y& z/ [' i, d& C2 t( Y
            + ~# v. j- |  q" w" W
            // Check to see if the packet has a valid size. Including
, g5 T  m' s& v            // the custom pack size.3 \1 G4 i# h1 n) @' d2 H
            if( size &lt; sizeof(ClientPosPacket))1 i% q5 x2 ^/ u" p" T
                fFoundSize = FALSE;
$ G  ~: x" I. d  u            else if( ! IsValidPackSize(size - sizeof(ClientPosPacket)))7 [1 o1 Q/ |2 _; z# U# p- P
                fFoundSize = FALSE;
5 \) k0 C: [# t7 d( ]$ `* g            else  ]2 K6 m2 T% [6 G( A7 C3 ^: O
                fFoundSize = TRUE;</P>, x. o) K: g$ w
<P>            // If valid sized packet, handle the position.* P6 i) C! T7 m6 X
            if(fFoundSize)
# U2 m+ Z' f9 l% p& Z( F                HandleClientPosPacket( dwFrom, (ClientPosPacket*)pClientPack );, C5 R) V# B6 I. l% Y* ~9 z
            else5 }  f- G" V! r% {- L
                m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );</P>( d  \. a1 F+ Q" [' Y, _4 T
<P>            break;</P>
/ t9 e( ?% n4 G6 k6 N# |: w<P>        case PACKETTYPE_CLIENT_VERSION:
4 P, m8 t2 _/ J' i1 F            if( size == sizeof(ClientVersionPacket) )
1 Q  ?$ E- \1 b" }8 ?; _: Y. D                HandleClientVersionPacket( dwFrom, (ClientVersionPacket*)pClientPack );1 ^" Y4 G) {. S) V* G
            else
; b; ^: [; s  w0 O% H                m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );- i/ W: ^6 b* P# d7 @
            break;</P>
5 f0 }- I1 z9 z: f8 w7 d+ H<P>        case PACKETTYPE_SERVER_CONFIG:</P>. n' x2 C0 u! x% x( ^
<P>            // Server config packet sent to all users (including server). Just ignore and continue.</P>
/ J- A6 H' l0 t2 C( N<P>            break;9 j4 v. P! E* W# r' {8 Q, t) o
        default:% m4 J8 ^, @8 ^1 ~/ M! P2 U. w( h
            HandleUnknownPacket( dwFrom, pClientPack, size );
, `% ~! Q/ p. A. `8 Z( p! S  e            break;
6 X" _/ Z# S3 c7 H/ Y- ^, ]& {3 E    }</P>
) Z  m0 x: ]$ m& d% h5 ]7 k<P>    //If the user wants to hold the thread, Sleep for given amount of time.
, ~3 V# ?  q; W    if ( m_dwServerThreadWait &gt; 0 )! f. O" D4 ]; l! ]
    {2 B9 h& t' g; U" V! e. Y
        Sleep( m_dwServerThreadWait );
# Z+ v: k5 m+ T    }& o/ h, D1 }# r( m6 n
   
$ ]1 U2 L& b, I* p    // Retrieve thread data for this process.( ?' p1 S& g! n7 J
    m_csThreadCountLock.Enter();</P>
) @2 x( z# j4 B# w* @9 L7 s<P>    m_wActiveThreadCount--;</P>) a8 ~* u! }8 X7 \- m3 _% z/ k
<P>    FLOAT fDiffTime = (DXUtil_Timer( TIMER_GETAPPTIME ) - fStartTime) - m_fAvgThreadTime;
# L' I7 c8 P0 o0 ~: ~    m_fAvgThreadTime += fDiffTime/32;</P>
5 B7 o! r$ G1 ~2 V5 a- i4 j% N- ?<P>    //Get the Max time in the thread.$ W  u8 w6 B" D! h: q2 d
    if ( fDiffTime &gt; m_fMaxThreadTime )
" c# b2 w' [/ |; q2 x% g2 v    {) H1 p2 i2 {, J5 h) F
        m_fMaxThreadTime = fDiffTime;; G5 ~6 \" Q/ u  |9 D  v7 u5 L
    }</P>
( z7 H# ?1 r9 o" Z6 q) K. ^/ T<P>    m_csThreadCountLock.Leave();</P>+ ?6 i; N( B$ c
<P>    return S_OK;+ d2 L: i& |& }2 B$ l
}</P>
) Y' D, ^. u5 m: C$ H6 O: r. K' @  J6 B1 m9 F
<P>//-----------------------------------------------------------------------------
+ a" ~4 y  {3 h4 d5 o0 F! ?1 P// Name:
1 f  H. f6 X  j3 K5 k* y- a1 u3 B// Desc:
3 {$ ^( X( T( W, a( i" Q//-----------------------------------------------------------------------------
) [( m# k: v* H+ ]6 ~: W( Z+ hBOOL CMazeServer::IsValidPackSize( DWORD dwSize )
8 U% X8 @- E( Y& O7 s& i- N0 f{: v- N" _% O2 o& ~. U$ w2 d$ F
    BOOL fFoundSize = FALSE;" e1 a, x) b: p  c
    BYTE ubPackLocation = m_ClientNetConfig.ubClientPackIndex;7 _; U6 O% I5 r/ n8 F& u
   
+ j0 N+ v; `& c2 d8 G    // Check through the array of valid pack sizes.6 U( B1 C6 o+ _% v: S; T9 A& v
    if(dwSize != m_ClientNetConfig.wClientPackSizeArray[ubPackLocation])
) x7 _8 J: U" m    {# e! S' e% F- q
        for( --ubPackLocation; ubPackLocation != m_ClientNetConfig.ubClientPackIndex; ubPackLocation--)* C' Y' @1 G; s$ z: w4 j6 `/ _7 b
        {
& G2 I% Z, p+ K+ F0 I            if(dwSize == m_ClientNetConfig.wClientPackSizeArray[ubPackLocation])
( e9 w# o: [0 @+ P# d6 b            {
% ?1 J0 p$ Z+ q- H% i2 |  p2 w+ T8 \                // Found valid size in the array.  l- F) ~# M3 x
                fFoundSize = TRUE;# N2 }( _4 ~9 e$ n0 k; v& N
                break;3 ?4 q6 w+ ^& B/ z9 e* }/ \
            }
8 Q- N+ h3 t1 T& \4 }- W  k! A0 \            if(ubPackLocation &gt;= PACK_ARRAY_SIZE)  ubPackLocation = PACK_ARRAY_SIZE;  //Wrap the array./ S! i1 {1 @9 P  V3 ]( r3 e
        }* g- t+ H1 H. C: q, h
    }
, T4 t% {; o) X9 ?0 S* D    else1 E  u5 M& A8 E! s$ F
    {
' f% ]1 c! y* h5 I! F: w1 J2 V% g        fFoundSize = TRUE;# X7 x7 i% f6 u8 I6 `: P( A9 f6 p+ I# R
    }</P>6 X' u% B; Q# @: x9 l
<P>    return fFoundSize;
- A5 b4 I) A) Z7 J}</P>' ]/ ]+ g. m% s/ |
<P>, H) l7 y5 P) I3 M) m9 ~7 U4 I; W( B
//-----------------------------------------------------------------------------4 Z0 j9 L) S- z* {# P  \
// Name:
7 [+ M: G/ p3 h2 G' B) u// Desc: 7 g3 R# e* A9 U* k
//-----------------------------------------------------------------------------
$ [4 J) b# ]3 pvoid CMazeServer::OnSessionLost( DWORD dwReason )
2 ~7 q. c/ Q: B! ?{# T- F8 }0 C, p0 o) R/ H
    ConsolePrintf( SLINE_LOG, TEXT("ERROR! Session was lost") );
* W; r2 G- }  A& u; R: u5 D; k1 C}</P>
) Y+ ^/ i( A- r! T( F1 V2 N/ l* }3 V# K, R, p+ @/ E# u
<P>
; G" U2 T  e% g. Z+ H0 l: g//-----------------------------------------------------------------------------/ v8 q3 l9 n1 N1 L. g
// Name:
5 F) t- u8 r2 r% v% p% N// Desc: / `! ]2 n8 f# V
//-----------------------------------------------------------------------------) f( l) W. |( N3 s( D
PlayerData* CMazeServer::CreatePlayerData()
/ v* s. ]8 n: C; n! n{
5 j& Y5 O, f% ?    m_PlayerDataListLock.Enter();</P>, u) a. c2 i5 n3 H' [
<P>    // Grab first free player in the list0 e2 W8 z9 e4 h  O
    PlayerData* pPlayerData = m_pFirstFreePlayerData;</P>0 D( [0 |" Q% E/ V" Q" s9 ]( v3 D
<P>    if( pPlayerData )
$ s8 b6 W/ K5 S    {* C) }7 f9 Z. C9 r0 D. l/ E+ D5 D
        LockPlayerData( pPlayerData );</P>- _2 j' F3 o; S5 _3 v
<P>        // Got one, so remove it from the free list
% s9 L; `4 h, r  V! e        if( pPlayerData-&gt;pPrevious )* m! H, k9 `" `! N
            pPlayerData-&gt;pPrevious-&gt;pNext = pPlayerData-&gt;pNext;
( s: D+ D% P# K) X& m9 l1 v        if( pPlayerData-&gt;pNext )6 E# `9 U3 {& |
            pPlayerData-&gt;pNext-&gt;pPrevious = pPlayerData-&gt;pPrevious;
$ H; z  J7 x+ p( h        m_pFirstFreePlayerData = pPlayerData-&gt;pNext;</P>
' L. j* q% q% J/ `: {<P>        // Add it to the active list$ `- H: g& O+ b* _$ `
        if( m_pFirstActivePlayerData )/ m1 V9 @5 \; c0 T0 e
            m_pFirstActivePlayerData-&gt;pPrevious = pPlayerData;/ \1 {6 O0 `6 I) F* i
        pPlayerData-&gt;pNext = m_pFirstActivePlayerData;3 [( S' W( v5 Z! U( ]1 I
        pPlayerData-&gt;pPrevious = NULL;/ m& H. f) Z% t
        m_pFirstActivePlayerData = pPlayerData;</P>
+ x+ V, T8 U4 v, z<P>        // Update count of players
+ ?/ i" g4 g& ]) ]. O7 U' `4 K        m_dwActivePlayerDataCount++;</P>0 {) u4 ^' n! R
<P>        // Generate the ID for this player
8 d% i, d! e5 a  n3 R        m_dwPlayerDataUniqueValue++;
8 P( p. p( B; d+ E5 _        pPlayerData-&gt;dwID = (DWORD) ((pPlayerData-m_PlayerDatas)|(m_dwPlayerDataUniqueValue&lt;&lt;PLAYER_OBJECT_SLOT_BITS));</P>
# n  L" U& E/ u<P>        pPlayerData-&gt;pNextInIDHashBucket = NULL;8 F7 g5 j9 O; R* p8 J
        pPlayerData-&gt;NetID = 0;
4 N  G7 l  B4 g4 a        pPlayerData-&gt;dwNumNearbyPlayers = 0;</P>7 Z4 q0 f1 I2 O( o
<P>        // Insert into the "off-map" cell1 _' s; |2 P0 ?7 S! A8 K
        pPlayerData-&gt;fPosX = pPlayerData-&gt;fPosY = -1;8 f/ ^5 c* \& \, x" M& S+ a
        pPlayerData-&gt;wCellX = pPlayerData-&gt;wCellY = 0xffff;
) V7 Q0 w0 e+ x. ?        m_OffMapLock.Enter();
8 X* \/ K8 H' V        pPlayerData-&gt;pNextInCell = m_OffMapCell.pFirstPlayerData;* e9 @; L  P4 \$ `% W
        m_OffMapCell.pFirstPlayerData = pPlayerData;
3 @' N4 y) A) c        m_OffMapLock.Leave();</P>
6 T* e1 ^8 `# c( U: k: h<P>        // Mark as active1 b3 H8 n/ O9 H) Y# O
        pPlayerData-&gt;bActive = TRUE;</P>' D% `/ Z$ ]' R9 v/ \5 p7 c
<P>        UnlockPlayerData( pPlayerData );2 v* \" y6 C- K% x2 M* o8 \' r
    }</P>- `# z+ ^  n! d- u& j* D8 ?! R
<P>    m_PlayerDataListLock.Leave();</P>
; A0 F9 H! D  Z( _: T# S<P>    return pPlayerData;
2 g) g$ a' G1 o) }( X}</P>" M: @+ N; I8 u5 ^0 n% q, z
) {, a; ~% p1 `
<P>* D( y7 W* m' r$ P( W/ B
//-----------------------------------------------------------------------------
) A% o# Q/ M4 v3 U// Name: ) s6 _" ^( D- q1 O2 L
// Desc:
$ w/ i' x1 L9 ]7 Z- @1 C7 G/ a//-----------------------------------------------------------------------------
7 w; p9 W4 b. C( v$ Rvoid CMazeServer:estroyPlayerData( PlayerData* pPlayerData )
2 O" i9 S: @" R2 [{
- \6 h% [9 _5 q4 w4 ]4 ^    m_PlayerDataListLock.Enter();% m* q. D* |- {4 a6 h' y1 Q
    LockPlayerData( pPlayerData );</P>
- I7 ]/ J6 ]+ X+ _! g0 {1 h<P>    // Remove the player from its cell6 _% b. t2 }: m& v8 @5 _
    RemovePlayerDataFromCell( pPlayerData );</P>
) v" K; a* N. J2 a+ W# Q<P>    // Mark as inactive3 T  L/ s# C, E
    pPlayerData-&gt;bActive = FALSE;</P>
- E* [+ U/ K* y$ w<P>    // Remove player from active list
" K  A+ \0 }" D8 ?$ O    if( pPlayerData-&gt;pPrevious )- l& J/ R9 N) o* B, N7 i
        pPlayerData-&gt;pPrevious-&gt;pNext = pPlayerData-&gt;pNext;( E) F7 M1 h! a  ?  j! j
    if( pPlayerData-&gt;pNext )8 W  ?( \% \5 |5 b- G* l
        pPlayerData-&gt;pNext-&gt;pPrevious = pPlayerData-&gt;pPrevious;</P>
) U$ [8 u# U5 r/ z+ `<P>    if( m_pFirstActivePlayerData == pPlayerData )
# P/ Z2 X+ I/ b) B( f        m_pFirstActivePlayerData = pPlayerData-&gt;pNext;</P>
4 _# b5 g. N  n& R+ m<P>    // Add it to the free list9 h# C7 b) N* ?# h! x
    if( m_pFirstFreePlayerData )
( C# ]6 j/ j" g! F- D5 m        m_pFirstFreePlayerData-&gt;pPrevious = pPlayerData;5 \4 n) g$ m+ S" O8 x% z9 b+ V4 t
    pPlayerData-&gt;pNext = m_pFirstFreePlayerData;+ c* {, N% v4 O
    pPlayerData-&gt;pPrevious = NULL;
* t/ k7 G* |& _8 e    m_pFirstFreePlayerData = pPlayerData;</P>+ f- |3 R! _: t. J/ t4 Z# x
<P>    // Update count of players1 W* z3 a/ I8 B' Z
    m_dwActivePlayerDataCount--;</P>
" }3 f. Q; G1 I5 ?4 X- I% L' g<P>    UnlockPlayerData( pPlayerData );
, ?+ X5 E  d4 ]8 J' z    m_PlayerDataListLock.Leave();5 W9 N! H8 E' _: b0 F& J% `6 c! p2 {
}</P>
9 C- p! h* D4 C3 f, [# j: J* I, ]) P* N3 w6 ^. Z3 h9 I- g
<P>
( Y  a9 r% f, n' K% {+ K8 W. }" X% N//-----------------------------------------------------------------------------8 O, h8 ~+ S7 ]/ O6 e& ^* d
// Name: 1 p7 U; d" w9 P" Z. B' o/ l
// Desc: ! L! ?+ ]- P7 O2 ]
//-----------------------------------------------------------------------------
" ]  B1 G& N, B8 a9 A# Z  Bvoid CMazeServer::RemovePlayerDataFromCell( PlayerData* pPlayerData )( n$ H/ a6 H3 {5 y  T
{; @, c  G$ j$ y% l$ E
    // Lock the player
1 @' I9 X; b  U5 _4 N% `1 S    LockPlayerData( pPlayerData );</P>& ^( D: O) x$ U& }4 ^; k2 S* [1 L$ a" a9 r
<P>    // Lock the cell the player is in% i: Y: {: r- j3 r, b$ h% C( c" u
    ServerCell* pCell;
1 G: i* H, M9 i$ Q    if( pPlayerData-&gt;wCellX == 0xffff )+ G4 Z  r- b9 }$ f3 h
    {
4 a; x2 q; x/ K+ [" e        m_OffMapLock.Enter();! E$ a; x0 u" |0 M8 g+ t
        pCell = &amp;m_OffMapCell;5 X0 u) x6 n/ `% h) @9 j4 l
    }
7 Q9 @6 n# N- O% z7 a    else* S- ]& t8 m4 {/ m$ M. f& t: n
    {
/ [2 _( {6 {" p! n        LockCell( pPlayerData-&gt;wCellX, pPlayerData-&gt;wCellY );8 k# j7 n( x3 ]; Y9 ]3 q2 y9 H
        pCell = &amp;m_Cells[pPlayerData-&gt;wCellY][pPlayerData-&gt;wCellX];
7 n, W+ }  b* i3 E    }</P>
7 h3 V% @7 z0 \( |4 b: l<P>    // Remove it from the cell
; H0 o( K( y) f% F* u2 q+ F! d    PlayerData* pPt = pCell-&gt;pFirstPlayerData;
  o9 E5 r: z7 ?# |0 u5 L/ d' X    PlayerData* pPrev = NULL;( \$ \$ n! H8 l1 A9 w3 K7 |4 ^8 e* c
    while ( pPt )5 s# {# e' E; T; U
    {
# e5 M, y9 D, C6 L        if( pPt == pPlayerData )
( C, g) R7 z+ D+ i: F  X        {
! e9 I2 b& V/ E( E5 A- S+ W" V            if( pPrev ): B# B+ \- {$ r9 x  M7 X7 ]3 _
                pPrev-&gt;pNextInCell = pPlayerData-&gt;pNextInCell;
' E9 T4 v0 b6 D/ R" A4 R            else9 @6 b3 h' L5 F
                pCell-&gt;pFirstPlayerData = pPlayerData-&gt;pNextInCell;</P>
: N6 p1 w. V0 D$ o2 C<P>            pPlayerData-&gt;pNextInCell = NULL;# k7 D: C7 e3 l9 O# M
            break;
8 }7 n8 x% g9 w; I$ {4 a$ O  G        }7 \* G: N1 Y+ K4 y1 g, `/ ^# Z& G
        pPrev = pPt;, ?, F4 a$ O2 [$ e& Y
        pPt = pPt-&gt;pNextInCell;+ P. K. Q3 M& ?- w/ j) q) b0 d
    }</P>; _0 n! O0 C7 b& A' o; D* B1 a
<P>    // Unlock the cell
0 m  n0 j# b* Y( _    if( pPlayerData-&gt;wCellX == 0xffff )
9 o! S- X9 L1 `9 M$ K% B        m_OffMapLock.Leave();$ x, S9 d$ g8 V+ X
    else
# l/ W- ~  T* f- ^        UnlockCell( pPlayerData-&gt;wCellX, pPlayerData-&gt;wCellY );</P>" j5 n; e. Q2 o" J+ p6 E  g9 ?0 j
<P>    // Unlock the player7 V" i! q8 W; l; D, b
    UnlockPlayerData( pPlayerData );( ]7 c9 S5 ~+ Z
}</P>
* ?4 k# l% I* s6 z+ C+ V  v4 _( ?
: C# F. u- [$ G( {& x. z<P>
6 z( c: v% U6 S* J# j% p5 y. l//-----------------------------------------------------------------------------7 Y9 g5 ^* ]7 z2 I3 Z
// Name: : s3 g( d/ u! f8 j9 t6 J
// Desc: % G! l! e, W9 b! C, T) I
//-----------------------------------------------------------------------------* N2 V$ w+ Z6 S
void CMazeServer::UnsafeRemovePlayerDataFromCell( PlayerData* pPlayerData )
7 k4 g% N) M* ?) v$ Q{1 f5 O5 \5 x5 }# W
    ServerCell* pCell = GetCell( pPlayerData );3 @: G1 t& J1 I% j- \
    PlayerData* pPt  = pCell-&gt;pFirstPlayerData;1 N5 r8 P! O$ j" `$ C/ Y. |7 ]( R3 b5 N
    PlayerData* pPrev = NULL;
. ]6 C3 s$ ~% l2 t2 t/ h5 @, C- n    while ( pPt )$ J( n$ ]% g2 A9 C* }' p
    {2 N% f( s  q- K& }8 j) E. b
        if( pPt == pPlayerData ); h" N5 N( o2 m4 c
        {- r5 Z/ t5 u! p/ y- r
            if( pPrev )) n, y. E# U$ p, c' T
                pPrev-&gt;pNextInCell = pPlayerData-&gt;pNextInCell;; }% `9 B# i& K8 \% h
            else! S' D0 e( D& j
                pCell-&gt;pFirstPlayerData = pPlayerData-&gt;pNextInCell;0 L5 [# a9 W0 f% z
            pPlayerData-&gt;pNextInCell = NULL;
! k! Q: H" }) t3 T4 c9 B3 b3 `            break;5 J$ m$ s9 U" _: J7 G4 C1 r4 X# m/ t: o
        }% U/ H- [7 z; o. {% f" g0 R( Y
        pPrev = pPt;6 O2 t# I$ W8 W' R$ o
        pPt = pPt-&gt;pNextInCell;
: k& N( z" N3 d! d% Q9 t' l    }
1 a2 _2 v. E; V}</P>5 }4 G" d' P2 }6 s6 F

/ y+ I0 y1 o* C<P>
* A1 _0 p5 L6 x/ I1 T' H//-----------------------------------------------------------------------------7 l, O- `; I  k/ ~! N4 E, k
// Name: & d; f$ m! E6 G1 P
// Desc: 4 P" j1 V: ~9 U) z6 [2 D4 ?6 ]
//-----------------------------------------------------------------------------
  z, y: o/ h+ A, {void CMazeServer::UnsafeAddPlayerDataToCell( PlayerData* pPlayerData )
8 g9 J" j+ M9 E0 j( s; Y% m' _' B{# j1 Q$ }9 h+ I$ @8 x3 L* I
    ServerCell* pCell   = GetCell( pPlayerData );! j: H/ E' M; T1 R. |9 \! [. @, v
    pPlayerData-&gt;pNextInCell = pCell-&gt;pFirstPlayerData;+ V6 y1 m+ }) Q
    pCell-&gt;pFirstPlayerData = pPlayerData;
) ?- g+ a( b# v6 Q6 G}</P># A& w, q4 @4 R9 u8 U' I

( o# b5 D% C3 w! s, i) u% ]% R<P>+ Q4 u0 F  u8 B& `# C
//-----------------------------------------------------------------------------) r* I% E. G7 ]4 ?
// Name: 9 U  e4 Y" S1 g$ d% z' R
// Desc: # A; ~4 X( Y9 w# F8 j
//-----------------------------------------------------------------------------3 P* O8 c6 N" d$ q; o( D% @
void CMazeServer::HandleClientPosPacket( DWORD dwFrom, ClientPosPacket* pClientPosPack )
6 z6 z$ i2 _  Z# ~{
3 F# X% ]: @* o& M0 g0 N    // Grab player for this client and lock it2 h5 A7 S6 R" z$ e' c/ e  h
    PlayerData* pFromPlayer = GetPlayerDataForID( dwFrom );
+ O  B3 Q* |' \* |5 t5 b    if( pFromPlayer == NULL )
& B" |! Y$ v$ d, n' ^7 N/ R9 `    {* G( m8 D& [. k
        if( m_dwLogLevel &gt; 1 )! @% U7 F6 x1 P* C; @- z4 ^! j2 ?
            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Could not find data structure for this player"), pFromPlayer-&gt;NetID );
5 X5 q# D0 n( ?0 ]0 f        return;
, z; O) s( u" u+ K& J& h    }</P>4 L& h1 C. D% F, K' c$ H
<P>    LockPlayerData( pFromPlayer );</P>
8 [$ @4 q5 P: e$ B, J<P>    if( FALSE == pFromPlayer-&gt;bAllow )" v6 y7 t- e% N; R$ D
    {
, j' L& u+ P+ h, u% I& C        if( m_dwLogLevel &gt; 0 )5 n# h3 _- [1 d+ |8 M
            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Got position packet from bad client.  Rejecting client"), pFromPlayer-&gt;NetID );</P>0 ^7 {2 V! _( T: }% P3 O
<P>        m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );
. n0 ]  V. ?- C8 y        UnlockPlayerData( pFromPlayer );
& g7 l% O5 F( H        return;
( ?! y4 o6 o& y0 e, \. \' Y' v& w    }</P>
5 r; Y3 e1 C0 W; x3 K3 I<P>    // Compute the cell the player should be in now
* T' X. C. U  X& j    DWORD newcellx = int(pClientPosPack-&gt;fX);
  N. ~3 \* t9 j/ V* S    DWORD newcelly = int(pClientPosPack-&gt;fY);
9 `3 I1 k2 h8 G& \( G) z$ M5 Y    DWORD oldcellx = pFromPlayer-&gt;wCellX;* p) q" R. F( V9 O& n) i4 O
    DWORD oldcelly = pFromPlayer-&gt;wCellY;</P>6 }. b( R) D+ G
<P>    // Have we moved cell?
: q, w5 Q8 b* V; \( u; u    if( newcellx != oldcellx || newcelly != oldcelly )" H5 W1 u+ `& a, k
    {
# U: h% B$ t* ^8 w4 c5 @        // Yes, so lock the pair of cells in question# L1 b# {* o2 w' y: X. A
        LockCellPair( oldcellx, oldcelly, newcellx, newcelly );</P>
1 ]8 ~& E3 b& ?% J) Z( G  r<P>        // Remove from old cell and add to new cell
$ {9 L- l: C! i$ M- c! P$ v        UnsafeRemovePlayerDataFromCell( pFromPlayer );6 r+ i) O/ g- d1 a+ X( i
        pFromPlayer-&gt;wCellX = WORD(newcellx); pFromPlayer-&gt;wCellY = WORD(newcelly);' B  Z8 R9 y' m$ I$ J# X
        UnsafeAddPlayerDataToCell( pFromPlayer );</P>
- t+ p2 B" C. e4 L  K$ s% I<P>        // Unlock cells8 c+ }8 R6 i, [8 m0 m3 [3 r  \1 L
        UnlockCellPair( oldcellx, oldcelly, newcellx, newcelly );/ G$ O( J% I0 r
    }</P>
) o. l; z  X9 T, I<P>    // Update player position4 c* |$ X$ s! g; R- P
    pFromPlayer-&gt;fPosX      = pClientPosPack-&gt;fX;
2 [8 F- H( Z2 h) k* T    pFromPlayer-&gt;fPosY      = pClientPosPack-&gt;fY;
+ L% f3 A8 r4 B) t) w3 ?8 [* }    pFromPlayer-&gt;aCameraYaw = pClientPosPack-&gt;aCameraYaw;</P>
3 N, Z0 e- g7 y2 M<P>    // Allocate space to build the reply packet, and fill in header
2 S0 H6 a6 }* g# }! ?# ]    DWORD dwAllocSize;
4 u4 ]% C- \  R, t, h1 Y    ServerAckPacket* pSvrAckPack = NULL;</P>( ?! M9 K9 {. o; B( q/ K/ h- E
<P>    // Begin by allocating a buffer sized according to
) Y3 d4 Q- U0 ]2 M" L    // the current number of nearby players + 4.  This will give 9 a) _7 \8 i! D+ Q" H( z0 p
    // a little room for more players to come 'near' without resize" L, y8 w9 [& y+ P# B! _# d
    // the buffer.2 g; k. h, M  `
    DWORD dwMaxPlayerStatePackets = pFromPlayer-&gt;dwNumNearbyPlayers + 4;</P>9 W, O) R* W, S* @) g+ S1 b
<P>    dwAllocSize = sizeof(ServerAckPacket) + dwMaxPlayerStatePackets*sizeof(PlayerStatePacket);
: K: u' t' V( i  X0 C$ B! A    pSvrAckPack = (ServerAckPacket*) realloc( pSvrAckPack, dwAllocSize );
3 E+ k4 z! P; O6 p& V9 g    if( NULL == pSvrAckPack )
6 a6 }4 z" l: Y9 D2 a    {
+ n; E4 s  _  o& i9 n( D3 b- P: Y        // Out of mem.  Cleanup and return! _- V% J+ @5 ~$ P; r! n
        UnlockPlayerData( pFromPlayer );
/ A% H* T9 j% t  n; ~8 F        return;      
: ~7 J) C! f$ C6 Y4 n' R    }
9 Q+ h% ]' y* L; Y- C7 ?; x6 M) ?    ZeroMemory( pSvrAckPack, dwAllocSize );</P>
# C* n# y4 Q8 S! y; Y7 t7 J5 N) @<P>    *pSvrAckPack = ServerAckPacket(m_dwPlayerCount);
+ {. L* F4 R$ N" o    pSvrAckPack-&gt;wPlayerStatePacketCount = 0;% S2 z  e+ W5 R( w; @, N, v
    PlayerStatePacket* pChunk = (PlayerStatePacket*)(pSvrAckPack+1);</P>
2 E5 u  e/ A3 C) ]* j<P>    // Compute range of cells we're going to scan for players to send6 O% `/ }) B: Q8 T" V% {
    DWORD minx = (newcellx &gt; 7) ? (newcellx - 7) : 0;
* N. S2 q0 D" m* ~4 j    DWORD miny = (newcelly &gt; 7) ? (newcelly - 7) : 0;- {- h: C! y# x/ w2 X, l; }' \
    DWORD maxx = (newcellx+7 &gt;= m_dwWidth) ? m_dwWidth-1 : newcellx+7;0 f, E  ]! E9 L3 f5 i
    DWORD maxy = (newcelly+7 &gt;= m_dwHeight) ? m_dwHeight-1 : newcelly+7;</P>( y( }" Z+ b+ t) K/ G
<P>    // Lock that range of cells# l( u) s4 ?; O8 _0 ^9 k' ~
    LockRange( minx, miny, maxx, maxy );</P>
) G. f: E( M" a9 l: I- q<P>    // Scan through the cells, tagging player data onto the end of! c$ ]/ e8 M9 w8 o1 H
    // our pSvrAckPacket until we run out of room
! M7 Z; A9 p* h4 w+ O  m    for( DWORD y = miny; y &lt;= maxy; y++ )$ U2 I; k) r: @( j& X, M9 s
    {
6 W1 B/ u9 }1 m$ H        for( DWORD x = minx; x &lt;= maxx; x++ )( K6 j" A* F6 }
        {
7 A2 ~, J& |) C            PlayerData* pCurPlayerData = m_Cells[y][x].pFirstPlayerData;# I) ^6 D( c" z/ ]
            while ( pCurPlayerData )
7 N* F7 j4 r1 Q8 G4 x8 ^            {- J0 w5 S: ]5 @( A/ ]* }. p9 ^
                if( pCurPlayerData != pFromPlayer )
  w. \: v1 E' u4 }- Y                {, G. N, S1 X. \/ X
                    if( pSvrAckPack-&gt;wPlayerStatePacketCount &gt;= dwMaxPlayerStatePackets )
3 g  P) @3 o2 P2 L8 F0 g. f0 u" G4 I                    {, W- A" ]) M0 Z- d3 f( `
                        // Make sure pChunk is where we think it is; T$ x  a  F/ j: t3 Z8 Z6 y
                        assert( (BYTE*) pChunk == (BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket)) );</P>; W; t% y# [- E0 e. E4 W" e
<P>                        // There are more than just 4 new nearby players, so resize the * _. l1 R  z  e+ W
                        // buffer pSvrAckPack to allow 16 more PlayerStatePacket's./ Y! U- c/ n, l9 M6 L$ D
                        dwMaxPlayerStatePackets += 16;
+ c! Q( j+ `  i& ~+ N7 D  m( b8 R                        dwAllocSize = sizeof(ServerAckPacket) + dwMaxPlayerStatePackets*sizeof(PlayerStatePacket);) h6 c( o% X2 z, \9 w7 c( Y$ C
                        ServerAckPacket* pNewSvrAckPack = NULL;
9 c$ B2 j( x, ^4 I  K                        pNewSvrAckPack = (ServerAckPacket*) realloc( pSvrAckPack, dwAllocSize );+ V) x; V; s9 y/ ]' S
                        if( NULL == pNewSvrAckPack )) Y$ A: I: G  Q; C$ P
                        {
- t7 S/ M8 @: {: l/ v                            // Out of mem.  Cleanup and return
1 G+ Y( F  S; v* [                            free( pSvrAckPack );' h7 Q# R6 h- l, |; @' \$ x- D; i
                            UnlockRange( minx, miny, maxx, maxy );
# @$ V! L) q. \" O- y3 W  X. V0 A: [                            UnlockPlayerData( pFromPlayer );2 ]' a" q$ \6 g' p
                            return;       # c% }5 @- _# K
                        }</P>( ^/ R" y. f* y: J' t* V* j1 y
<P>                        pSvrAckPack = pNewSvrAckPack;* C) z5 r! ~2 C* d6 h. V
                        pChunk = (PlayerStatePacket*) ((BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket) ) );</P>
! r: H$ G# I( e<P>                        // Make sure pChunk is still where its supposed to be. H) P8 q4 m7 T2 P4 Y" V# ~4 d0 a
                        assert( (BYTE*) pChunk == (BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket)) );" T( B% C+ R$ y
                    }</P>
: ?7 o% x# U+ i! f! a" m2 c<P>                    pChunk-&gt;dwID       = pCurPlayerData-&gt;dwID;
. X' j$ \; X# P! ^' S2 f# a                    pChunk-&gt;fX         = pCurPlayerData-&gt;fPosX;
9 r5 Q; v* ]9 J4 r                    pChunk-&gt;fY         = pCurPlayerData-&gt;fPosY;
& f$ ~3 a  x# [; T$ v7 s+ G' @: l6 u/ T                    pChunk-&gt;aCameraYaw = pCurPlayerData-&gt;aCameraYaw;, m2 X& B" L( Q
                    pChunk++;
# D0 [! d2 V- n2 {                    pSvrAckPack-&gt;wPlayerStatePacketCount++;
0 ^3 W$ T  e/ _/ S; G+ h                }
# ~: a; ]3 _% R5 ~( X' @1 B                pCurPlayerData = pCurPlayerData-&gt;pNextInCell;
" x4 h% V# N, E* f2 w. _1 _            }
" `6 x2 X  \0 w' o        }
# F/ z7 N; F. g    }</P>
% g) G1 O% N/ t& ?<P>    // Update the dwNumNearbyPlayers for this player1 P1 }' k6 k$ y* }8 ^6 O5 j5 W
    pFromPlayer-&gt;dwNumNearbyPlayers = pSvrAckPack-&gt;wPlayerStatePacketCount;</P>
8 `1 i( t2 B; }' w<P>    // Unlock range of cells
; J" h$ \! k% {6 r    UnlockRange( minx, miny, maxx, maxy );</P>8 Q$ c( z9 |' q0 y6 y2 r/ ~
<P>    if( m_dwLogLevel &gt; 2 )2 k4 b# @) u, u2 Z1 \2 X; V/ E
    {
+ k, P9 y* r$ @  S. v& f        ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Position is (%0.2f,%0.2f)"), pFromPlayer-&gt;NetID, pFromPlayer-&gt;fPosX, pFromPlayer-&gt;fPosY );
# j8 H/ {# b5 F* Q    }/ r' [3 v9 U. L; Q$ s2 t8 I- y
    else if( m_dwLogLevel == 2 ); K2 q! i* p2 B: t7 X
    {: i/ P8 r% H4 u! v: V" d1 C3 Y
        FLOAT fTime = DXUtil_Timer( TIMER_GETAPPTIME );
& P/ r/ U6 X, o2 ~        if( fTime - pFromPlayer-&gt;fLastDisplayTime &gt; 60.0f )
' n5 m) k1 X- n" A4 {        {* B* }. l' O5 I( g: j
            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Position is (%0.2f,%0.2f)"), pFromPlayer-&gt;NetID, pFromPlayer-&gt;fPosX, pFromPlayer-&gt;fPosY );" i. o% Q0 R8 _7 m1 n
            pFromPlayer-&gt;fLastDisplayTime = fTime;
6 X# F) z% v0 }% s# N' U( S, P( A        }% J; [+ d) n+ \$ J5 Q8 P
    }</P>
9 Z- T; L1 t, `5 i! W<P>    // Unlock the playerdata
" e5 m" C& C/ A+ m7 V. m5 l    UnlockPlayerData( pFromPlayer );</P>
/ f  a  F5 l8 z  g<P>    // Send acknowledgement back to client, including list of nearby players
" a8 \. y$ G6 M    DWORD acksize = sizeof(ServerAckPacket) + (pSvrAckPack-&gt;wPlayerStatePacketCount * sizeof(PlayerStatePacket));5 O2 O& s$ N8 q- G! A( Q
; h0 E+ Q/ U, a1 d
    // Pack the buffer with dummy data.
3 h/ b) Q: x$ R3 g4 T* Q- p, J    if(m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex] &gt; 0)
; J/ V' C$ ^, Y" \- c1 F" `9 o    {
. S, x/ P& w- G5 v+ y        DWORD   dwBufferSize = acksize + m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex];
; O' c" M& a+ v+ g) G        VOID*   pTempBuffer = 0;</P>; k$ y! k2 H% y) i7 _# a
<P>        pTempBuffer = malloc(dwBufferSize);, a4 E+ s/ w+ Y% E2 W7 b3 N/ L( [' q
        if( NULL == pTempBuffer )
5 u) R/ j. a6 f$ c) j8 Q/ O% K        {" f  t% T5 ?) m& x
            //Out of memory
4 e+ X9 O/ f4 U( |            DXTRACE_ERR_NOMSGBOX( TEXT("System out of Memory!"), E_OUTOFMEMORY );
0 N& g) D9 U+ Z            free( pSvrAckPack );
0 I; M3 _! P7 g0 |, M            return;# A1 W3 d1 \; w
        }</P>$ r9 Z! z* R' c" c
<P>        FillMemory(pTempBuffer, dwBufferSize, 'Z');
% g  W9 D9 w, f* R; ~        memcpy(pTempBuffer, pSvrAckPack, acksize);</P>* c  h0 s/ Q/ a: [  z
<P>        SendPacket( dwFrom, pTempBuffer, dwBufferSize, FALSE, m_dwServerTimeout );: x# |( \: b# h
    % v, I( c, `* d
        free(pTempBuffer);
! `+ {; Z+ ?! @6 x% V: `7 t    }   
1 S& H9 V6 ]5 j% E/ Q. q: ]5 \    else/ q% V' ?$ s* I& {
    {0 |' p! u- h$ a' [7 y
        SendPacket( dwFrom, pSvrAckPack, acksize, FALSE, m_dwServerTimeout );
8 B/ z7 S2 ]  u    }</P>
9 Y/ c% |$ R: U6 t) n' Y; g: k- p<P>    free( pSvrAckPack );</P>
& O& d* d+ `  \2 x& S# ?# N( ?: f<P>}</P>
* |5 u5 G% s+ p4 }# t$ N% g6 x# L7 A- \# j; K" a6 `+ {2 u  z
<P>
' N7 d, ]& c. g* {0 t7 w//-----------------------------------------------------------------------------
7 M) i- Q3 V; X0 ^// Name: + G- ?: L& K' q% f+ Y
// Desc: % `' e# ~/ Y. ?5 G
//-----------------------------------------------------------------------------
, [6 @6 v6 A+ H4 l" q) y# e6 E8 Tvoid CMazeServer::HandleClientVersionPacket( DWORD dwFrom, ClientVersionPacket* pClientVersionPack ): T2 C! q4 X. d" k  \8 v" Y$ Y' v
{
/ \6 D6 @; @: ^& Y  U    // Grab playerdata for this client and lock it, S1 r% R- ~+ X2 y/ q; A. V; c
    PlayerData* pPlayerData = GetPlayerDataForID( dwFrom );
$ S( t) I2 a1 u& F+ {/ v: B9 m; \' O7 I    if( pPlayerData == NULL )
; A8 J- I) u+ p! `6 s: s2 ]        return;9 K4 v4 z0 G: J
    LockPlayerData( pPlayerData );</P>
+ x; V0 N( g( G' M, l7 j" b8 {<P>    // Record the version number : w, ]' l# D9 ]6 [$ M; M
    pPlayerData-&gt;dwVersion = pClientVersionPack-&gt;dwVersion;</P>
# m" N! t; F5 q9 I  U& @* {/ j  `<P>    if( m_bLocalLoopback )5 ]+ w# U$ M. I& u
        pPlayerData-&gt;bAllow = TRUE;6 z) ?& n, O6 p9 w7 Y. `: H$ \# O
    else0 Z4 Q8 M% r, R$ P1 }+ B# C6 s
        pPlayerData-&gt;bAllow = IsClientVersionSupported( pClientVersionPack-&gt;dwVersion );</P>
0 O3 b- z. X) n- |' _! X<P>    if( m_dwLogLevel &gt; 0 )
, w* ]9 K: d; ^5 q, w/ {        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>
% E7 ^# q2 M( d+ D% m0 Y- z( R3 `  O' B<P>    if( FALSE == pPlayerData-&gt;bAllow )
- E  Z4 T  z8 |* n9 d- |1 G/ {7 X    {
& C( s! [( e& O( Y, i. H9 I7 @        if( m_dwLogLevel &gt; 0 )
4 E: j: r: Q- |5 T0 ?" R            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Rejecting client"), pPlayerData-&gt;NetID );</P>
# O( @- y) a& i: H<P>        m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );  s& G" R) F" K/ s
        UnlockPlayerData( pPlayerData );+ i; n0 [+ l0 x- V3 H# L
        return;
; C( x1 Y1 [$ v' D+ Y+ \    }</P>
: G2 b* K: [- ?  f2 n<P>    // Unlock the playerdata8 d# v# e1 m3 V6 X+ J9 l
    UnlockPlayerData( pPlayerData );</P>1 o& M: P8 R, @  U
<P>    // Send acknowledgement to client that the client was either accepted or rejected
) r% i+ Z* K! d. G! Y3 }' @9 p% q    ServerAckVersionPacket packet( pPlayerData-&gt;bAllow, dwFrom );
+ A/ x/ D0 s+ \/ Y3 ^    SendPacket( dwFrom, &amp;packet, sizeof(packet), TRUE, 0 );
  a' D. q4 n. g5 U0 _, m8 a% K* s}</P>
9 t( P+ v. D( u1 N1 s4 d5 q; T; j* y0 B
<P>/ ]/ v; C# M" h, ?! [' n) v
//-----------------------------------------------------------------------------9 O5 T3 h9 u7 ^7 u  x0 y% G
// Name:
( u' s7 w  C% L' Y* E! L' x// Desc:
* I1 p" y+ D2 V//-----------------------------------------------------------------------------0 ^5 F3 x( o% Z, S# m# u
BOOL CMazeServer::IsClientVersionSupported( DWORD dwClientVersion )
: T& u, R4 C7 U4 A; l{
' o5 W% R) A) C5 D    switch( dwClientVersion )& q! Y4 \. N) n& X
    {
) Z( H9 K- ]& S        case 107: // only v107 is supported) j$ R8 ?: V) k1 U/ K
            return TRUE;
; V/ N& R1 y/ _! \' X        default:
4 O/ U% c7 m6 P: Z* ?) [9 I6 Y            return FALSE;  Y' @( x1 M5 ?  J" ]) L5 \5 |. ^
    }
2 D7 x5 ?' s1 `3 @, `}</P>9 M" h, q4 u) ?- @
- n/ e' ^/ f6 `; f4 X+ w
<P>
) s4 a7 a0 m9 B5 m6 w//-----------------------------------------------------------------------------4 W; `: T# h# k& b% B
// Name:
5 y# n$ X9 j- |+ q- i- M// Desc:
! O9 k( \) y1 T& ]3 P//-----------------------------------------------------------------------------
1 V$ U+ h3 a; k+ Xvoid CMazeServer::HandleUnknownPacket( DWORD dwFrom, ClientPacket* pClientPack, DWORD size )
! m1 C' P7 h+ O; K8 g{
* `: G! t' i$ j3 `$ e$ [  ?6 i& O1 i) d    if( m_dwLogLevel &gt; 1 )! I, B! O7 G, G5 `' G0 c: R1 f
        ConsolePrintf( SLINE_LOG, TEXT("ERROR! Unknown %d byte packet from player %0.8x"), size, dwFrom );</P>2 {) v( R4 N: {& R% H- U( R2 T# L+ `, m
<P>    m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );
7 _* Q4 w  ~7 @$ W' H: Z* T! A}</P>; m2 ?, X5 Y7 _" V! P0 ]5 C8 h* N- M

, E  A) o2 K/ G) O9 _5 d<P>
" p- s2 d" E6 v' U! j) {. Y+ U//-----------------------------------------------------------------------------
' t" Y. I" U$ d7 ]2 w// Name:
) A6 o/ q1 B7 {: ?// Desc: 9 D% q+ Q% K( H3 g. q
//-----------------------------------------------------------------------------* U1 u) b4 M, [# B2 |0 z4 {
DWORD   CMazeServer::IDHash( DWORD id )# M+ ?- N$ Y' i" I$ `: x) F' t
{
9 x! c# J5 X3 c# ^    DWORD   hash = ((id) + (id&gt;&gt;8) + (id&gt;&gt;16) + (id&gt;&gt;24)) &amp; (NUM_ID_HASH_BUCKETS-1);( ~8 I# j. N; D4 P
    return hash;+ w- X4 z3 a6 r: t- G! S$ d
}</P>" O: p7 W' t% y4 \

3 K6 O  G4 Z) q2 S8 s2 c<P>
# K' I; H% _" D* \+ {$ V9 [//-----------------------------------------------------------------------------
$ S3 L* j* h# A0 r8 O( r5 v// Name: " B- ^0 O& t" _; J+ J4 k% I4 p
// Desc:
! c) n9 O7 N0 i) h* v$ v& n, X* z1 q//-----------------------------------------------------------------------------$ C2 j+ I) V! M8 c. U
void CMazeServer::RemovePlayerDataID( PlayerData* pPlayerData )
; K0 A- W1 `- K' S' ^( [{
1 D4 M3 }  C3 l" v9 m2 o: V    // Hash the ID to a bucket number
& @$ p9 s3 i6 v1 D) L    DWORD   bucket = IDHash( pPlayerData-&gt;NetID );</P>1 P; R! ^1 V' k8 x9 o1 K4 @$ V
<P>    // Lock that hash bucket) v! D4 v; s) A- @& A
    const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;
8 v3 Z! J& I# X& l2 j, Y    m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>8 ]" d# q5 d# W$ Y7 w% a; N9 h# M
<P>    // Loop though players in bucket until we find the right one$ T4 x2 D9 \9 \! h1 }7 M1 q
    PlayerData* pPt = m_pstIDHashBucket[bucket];  l6 r( [7 Q& P4 B! S" q
    PlayerData* pPrev = NULL;6 i' v# X( P5 o5 [, F
    while( pPt )
4 {: t6 j: m6 ]* J- M    {
2 C; @  Z3 G0 n( q% r3 l" c( L! F        if( pPt == pPlayerData )
" R3 e6 G5 o# |& T5 c            break;4 B( H) ]$ W1 {. O& F+ G( T$ K
        pPrev = pPt;6 v4 H9 B4 d  F5 O# n8 S9 Q" w6 `
        pPt = pPt-&gt;pNextInIDHashBucket;
. T, H3 \) z; K    }</P>! ?. S" s( C6 B
<P>    if( pPt )
( |' h2 c9 _# Y$ T: z8 z/ A    {
# T, m0 `% N. s        if( pPrev )8 }- R1 X  O: ]# g' w1 P* {
            pPrev-&gt;pNextInIDHashBucket = pPt-&gt;pNextInIDHashBucket;8 W5 {! @8 w7 Z7 b& t
        else
" K- e2 }' D; T7 E            m_pstIDHashBucket[bucket] = pPt-&gt;pNextInIDHashBucket;( }; T6 N0 f7 d' n' P2 K2 p# R  F
        pPt-&gt;pNextInIDHashBucket = NULL;
; N0 [7 M: R! ~    }</P>" I3 b' i- x6 \/ X& Z( \6 J
<P>    // Unlock the hash bucket
5 U0 S4 Y5 }  _+ q8 G    m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();  [* N( r7 z+ k  C* z) S  v
}</P>
2 j$ W" K! ^; [* e
0 I: B) c2 K% I# C+ O. i. P<P>
1 ]2 o  O6 n( Y1 d+ E//-----------------------------------------------------------------------------5 _1 ^- b" K) F: t4 ?
// Name:
* x6 p; D  k; e' g// Desc:
  i1 N' H( g  ?( K6 g' ~( m3 ~//-----------------------------------------------------------------------------# [! t: W( y3 ]1 Y
void CMazeServer::SetPlayerDataForID( DWORD id, PlayerData* pPlayerData )
. I$ f. c$ A# L# c. T4 |{
  S2 }  x3 X4 N% I1 V& v! {    // Make sure this player isn't added twice to the m_pstIDHashBucket[]
, l+ C0 Z8 J+ A8 L; K1 j7 r* ~    // otherwise there will be a circular reference
' b9 ], _3 Y2 p* z' q7 |' V    PlayerData* pSearch = GetPlayerDataForID( id );
0 f) |6 {' r3 R    if( pSearch != NULL )
* J6 Y9 J" u: a% Q! l" J        return;</P>2 i0 x) e7 |0 t! ?
<P>    // Hash the ID to a bucket number
7 e& x7 q6 O/ {5 o& H* |    DWORD   bucket = IDHash( id );</P>
1 Q  \4 [. s, N! ~  }<P>    // Lock that hash bucket/ b6 F& d* B3 w2 c
    const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;
( J- j, F$ [- k) O% v9 g7 ~    m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>  U% v% c7 f: y/ x4 y0 V
<P>    // Add player onto hash bucket chain
; P  u6 c0 u4 V$ P7 V8 G    pPlayerData-&gt;pNextInIDHashBucket = m_pstIDHashBucket[bucket];
9 s2 O) H( x6 s: [( n4 j    m_pstIDHashBucket[bucket] = pPlayerData;</P>4 p% y! {7 L! F$ T7 E+ y
<P>    // Store net id in player8 o; m" N3 M& ^7 B% N
    pPlayerData-&gt;NetID = id;</P>
& O' F1 k9 E3 P. \* o<P>    // Unlock the hash bucket2 K' Y( p1 t6 K0 K3 p
    m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();6 n! u4 y. w0 o& _9 O: a& g2 ~
}</P>
  B! S/ \; ~6 h! ~0 g" h
" |- }- D  }9 g$ a0 k2 W; t' M: i- F9 F<P>6 C6 K6 S, Z8 H5 G
//-----------------------------------------------------------------------------
8 C: G. G; O  M8 G! O// Name:
' _2 B% P+ M4 p. t+ c// Desc:
- _! c- M4 u$ Z8 R8 F//-----------------------------------------------------------------------------
8 Z0 J: o* f9 {" E2 q& BPlayerData* CMazeServer::GetPlayerDataForID( DWORD id )
! P0 _2 y% O5 ^% u9 Z9 P2 @{4 F0 u8 J% z$ R7 i
    // Hash the ID to a bucket number
. p9 }& J4 r% N; U& n8 ?* C    DWORD   bucket = IDHash( id );</P>: `9 t' I- h5 S1 p7 j
<P>    // Lock that hash bucket+ i+ y( X- W. y! B# C# @( P
    const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;
$ {# `. T+ D! @1 T: R    m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>4 @/ I$ w& P3 s/ R' Z# `
<P>    // Loop though players in bucket until we find the right one% n7 r" G3 A$ V1 m, P% Y! r
    PlayerData* pPlayerData = m_pstIDHashBucket[bucket];
# h& J* _7 _0 r; q/ f% Z# H3 O- F    while ( pPlayerData )
4 c1 L$ G) W* ^, _    {1 A# s3 e1 L9 d2 y- x
        if( pPlayerData-&gt;NetID == id )
$ L- @: l( [" P3 G: S+ k' q            break;# d! F* n- O  ?4 Q
        pPlayerData = pPlayerData-&gt;pNextInIDHashBucket;
: X4 r5 b3 r% q5 K& Y# w$ J4 ]    }</P># {. `  L* f6 q8 I& o/ x
<P>    // Unlock the hash bucket
. |2 P& r% u. ^0 E4 Y    m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();</P>8 K' ~5 \& f- {' |* Z0 B
<P>    // Return the player we found (will be NULL if we couldn't find it)
: n- R8 T5 D! C, S; t/ u3 ?    return pPlayerData;
% c) N$ X9 p; J' k- f5 o}</P>1 N* |5 z  f8 i% j3 _

( I+ H* H: u2 P( f" O2 S( }+ Y<P>
6 Q3 X6 e4 k5 _8 p8 O' Z//-----------------------------------------------------------------------------7 c- f" z5 T  G/ Q) Q( ^, w" _
// Name:
* S7 Z# V) ~2 w/ z  C// Desc: calls DisplayConnectionInfo for each connection in a round-robin manner
/ w4 S' W5 L/ \" R( R8 t9 m//-----------------------------------------------------------------------------
* J1 S1 m; ^. K4 C) D& B( |void CMazeServer:isplayNextConnectionInfo()
: x, U& W/ i' u" _1 f& T7 b# d) d{: E/ u5 F0 ]  B* |6 L
    if( m_pNet )9 ^1 b$ l6 X- Y
    {
' M, V% q8 N4 U* A4 `0 C5 l        // Find the player that was displayed the longest time ago, and display it.. r! D% X! r1 N6 V" ^$ t5 R
        FLOAT fCurTime = DXUtil_Timer( TIMER_GETAPPTIME );
* K) U5 ?: o9 f5 r8 A        PlayerData* pOldestPlayerData = NULL;
1 U9 A% C2 _" ~) G3 d* E        FLOAT fOldestTime = 0.0f;</P>
7 M1 C: X6 x! e5 E) y8 A3 W8 [3 s<P>        m_PlayerDataListLock.Enter();</P>
% G3 g0 G* I8 a5 i<P>        PlayerData* pPlayerData = m_pFirstActivePlayerData;
- d$ H" J' [$ W" k        while ( pPlayerData )
& R. @/ P# [7 c! Z( s: w! u' M. v        {
8 G' W& I7 X( S9 R8 R: K            if( fCurTime - pPlayerData-&gt;fLastCITime &gt; fOldestTime )+ R- a* x  _  E+ ^4 X: j! D' h
            {/ ?# q) i: W0 v
                fOldestTime  = fCurTime - pPlayerData-&gt;fLastCITime;9 @& v2 j$ v8 D
                pOldestPlayerData = pPlayerData;4 k, i6 s3 Q/ e8 o7 [* O
            }</P>6 G# k% E4 e  ~; n
<P>            pPlayerData = pPlayerData-&gt;pNext;& X1 X; S1 K% N0 S! Z; y- e" y/ o
        }</P>
, Z: r6 [) Q$ n8 Q# c<P>        // Display the player with the oldest CI field, and update its CI field.% J4 z3 {- ^( o- [# H
        if( pOldestPlayerData )
# _  Y+ T7 i( _6 c* B; H        {
: r! o# e  s! r  c4 ?6 v: {            ConsolePrintf( SLINE_LOG, TEXT("Displaying connection info for next player") );
( [4 `/ E% a( M' ]' ~            DisplayConnectionInfo( pOldestPlayerData-&gt;NetID );& a1 A& Y& z) K
            pOldestPlayerData-&gt;fLastCITime = fCurTime;. Q9 v. v3 X8 q# e! ]2 k6 W5 C1 s
        }# j0 m* l5 ~& n) J! f
        else
/ L# }- g, b3 V" D9 `        {  v" C( y. }0 z) X! J
            ConsolePrintf( SLINE_LOG, TEXT("No players found") );
+ q( o; j5 i( i& |        }</P>2 Z9 ?" R6 h! w; o6 `
<P>        m_PlayerDataListLock.Leave();
/ _, E( Q* n" D, T8 `$ w& G! n. o    }1 p! c& `/ Q2 ]) {" {9 H8 }( v
}</P>% O/ t: H1 u. b( Z5 ^0 }- Y" S  T
) h6 L/ E) h8 Z2 J% U: J  U
<P>$ [7 N. g* l" R, h. Z
//-----------------------------------------------------------------------------
, P3 e2 U* N9 j// Name: 8 r4 ^4 r: u4 \2 h- a! l1 A7 ?
// Desc:
7 B% r! h: i: ~; s8 T//-----------------------------------------------------------------------------/ z& D' F  b4 t- A
void CMazeServer:rintStats()! P8 S$ G, P# r; h
{
9 ^9 {2 Z* h4 Y* Z& N' i+ E( s& y$ J- l    ConsolePrintf( SLINE_LOG, TEXT("Thread count: Active=%d Avg=%.2f Max=%d"), ; v( l" G% i+ P& g
                                    m_wActiveThreadCount, m_fAvgThreadCount, m_wMaxThreadCount );
, F: H) F' J9 ?4 q    ConsolePrintf( SLINE_LOG, TEXT("Thread Time: Avg=%.4f Max=%.4f(s)"),
! v' K$ R1 I, p7 c8 ]2 R                                    m_fAvgThreadTime, m_fMaxThreadTime );4 O; {9 h1 l, i/ k$ s" J
    ConsolePrintf( SLINE_LOG, TEXT("Players online (not including server player): %d"), m_dwPlayerCount );+ l( N, \& u: C+ L  D3 I
    ConsolePrintf( SLINE_LOG, TEXT("Peak player count: %d"), m_dwPeakPlayerCount );! l8 C0 p4 @4 {0 w
}</P>7 n# e) S2 K; D( R
$ _9 m" j. ~" X; G' L" i* K; l
<P>
7 N' r: D7 j1 O: F6 V" `//-----------------------------------------------------------------------------% c( [- N5 G+ f2 P2 C9 g
// Name: : {* I- h; P$ P2 l* E
// Desc: * w; Y7 a7 {& D0 P0 `% j
//-----------------------------------------------------------------------------
0 u/ V2 q/ _  I& q& lvoid CMazeServer:isplayConnectionInfo( DWORD dwID )  Z! j3 U$ @8 H
{2 m4 e3 |# O5 O$ a; i6 O
    TCHAR strInfo[5000];& B% E  i: ?) ?
    TCHAR* strEndOfLine;+ j7 h6 D  g- A9 D- R
    TCHAR* strStartOfLine;</P>. V( F( }$ C* l( Y
<P>    // Query the IOutboudNet for info about the connection to this user7 }5 j2 E4 v: `7 H  H* l% F
    m_pNet-&gt;GetConnectionInfo( dwID, strInfo );</P>
) E' A, G- M  S! N5 x. T5 T; a9 |" B* H<P>    ConsolePrintf( SLINE_LOG, TEXT("Displaying connection info for %0.8x"), dwID );9 E5 @4 u5 _  I
    ConsolePrintf( SLINE_LOG, TEXT("(Key: G=Guaranteed NG=Non-Guaranteed B=Bytes P=Packets)") );</P>
5 z3 W  A6 h6 t7 O<P>    // Display each line seperately/ J* W( [) y4 R( k% V
    strStartOfLine = strInfo;
* F* ]5 e& Z$ H2 t    while( TRUE )0 h( [' U- |5 B7 N9 N* B
    {
. F1 ?; _$ D/ j9 ^: `/ ?        strEndOfLine = _tcschr( strStartOfLine, '\n' );
8 B" J) S6 x* x) A1 ?" A        if( strEndOfLine == NULL )
& G& T! A/ ^6 S" u& s8 _; X            break;</P>
' V6 h7 s+ Z9 I+ ~<P>        *strEndOfLine = 0;$ k. m: H: r$ G4 R
        ConsolePrintf( SLINE_LOG, strStartOfLine );
. |% M; c0 \1 C7 c        strStartOfLine = strEndOfLine + 1;) E6 ~2 e1 O0 g! O9 @0 s
    }2 |3 }3 w( }4 [/ {, I7 N! e
}</P>
( K0 D- Q+ E% B0 X% w: i$ C1 i1 @7 M6 @" e
<P>
; i8 ~6 a! I1 B0 T( A1 {//-----------------------------------------------------------------------------
" I6 `' Y  ]. K" m: V. j// Name: - g+ l) B: {' n  v' x8 G
// Desc: " j, `3 T; {5 `9 D1 X
//-----------------------------------------------------------------------------
( O7 _, D5 D. S) H$ `HRESULT CMazeServer::SendPacket( DWORD to, void* pData,
4 R2 L% ~( Q: b# I, ?+ H7 B                                 DWORD size, BOOL reliable, DWORD dwTimeout )8 z8 x! l) L8 v. H: o2 E. h
{
6 e4 _1 b! o4 j) Y; d9 }    // Chance of forcing any packet to be delivered reliably7 ~* v( V2 h  O1 F5 c; w- R
    if( m_Rand.Get( 100 ) &lt; m_dwServerReliableRate )
: X6 \, ^5 N" `; {        reliable = TRUE;</P>
" R- K2 Q9 h5 S' a<P>    return m_pNet-&gt;SendPacket( to, pData, size, reliable, dwTimeout );
( M3 s1 Z4 f1 ]! x5 t$ K}</P>9 d  x2 y& G$ x  W+ n

$ J7 {5 _+ d6 T% y# t# ]<P>
$ `0 o0 _1 L$ V, I//-----------------------------------------------------------------------------
+ b1 b3 P4 x. K& [" w/ a// Name:
$ O! U* q1 z( w// Desc: 0 r* j% j* Y# a7 z& Q* H6 c. i
//-----------------------------------------------------------------------------) d2 {. N# _' x6 l* a
void CMazeServer::SendConfigPacketToAll( ServerConfigPacket* pPacket )
. {2 \$ _, w1 o4 z1 u; G( p% h4 C{
0 r: s& A& E/ h8 D$ a    // If we're up and running, then send this new information to all clients' p- ?- t- P+ D5 |4 J
    if( m_pNet )8 K$ U: p5 _$ {- o- h5 |8 o
    {
/ F$ q- p* f; O, S' ^3 p% [        //Use the AllPlayers ID
7 E0 b' p: K: k! t1 Z# p        SendPacket( DPNID_ALL_PLAYERS_GROUP, pPacket, sizeof(ServerConfigPacket), TRUE, 0 );
9 W2 A! D6 I3 e/ j    }
4 T# N& D0 p: e: T1 d$ ]! K6 U}</P>
! k" S1 U/ E* D: ]! r2 O/ b8 G
  Q4 W/ Z* [; W2 d<P>% F) C; }: z4 F
//-----------------------------------------------------------------------------7 k5 |; E& @0 F, t5 }
// Name: ; O  o/ O. Q* k# A! f
// Desc: " g5 }3 D- G2 T% i! K- A6 g5 v- y
//-----------------------------------------------------------------------------) X& k5 d: a$ D% G( K. t
void CMazeServer::SetClientReliableRate( DWORD percent )
1 D0 D+ \4 ^  G# t{
0 v4 ^9 B$ A, w    // Update client config, and build packet containing that data  O6 a  y2 L$ [" b: H. E6 [
    m_ClientNetConfigLock.Enter();0 A, I2 g' ]) l
    m_ClientNetConfig.ubReliableRate = BYTE(percent);2 W) j6 `: K, r4 a2 A5 ~
    ServerConfigPacket packet( m_ClientNetConfig );2 r8 y) k# b. Z- ]! m& m& F7 U
    m_ClientNetConfigLock.Leave();</P>( \  p% a9 u" V4 |( A
<P>    SendConfigPacketToAll( &amp;packet );
% ~) D) N9 o3 f# x3 Y}</P>
2 H: f: y4 R5 y
3 d7 `$ \7 F/ \: C/ k<P>
' R4 x/ l$ A) k- M3 @//-----------------------------------------------------------------------------
  |' |' \# W+ M2 h- x+ K// Name: , a' F& H( b2 y$ R# o4 U  c: F* S! f
// Desc:
2 N- V+ _9 f" U2 C3 X9 D//-----------------------------------------------------------------------------) `" T9 e/ E! C+ u0 }
void CMazeServer::SetClientUpdateRate( DWORD rate )
, M( z+ R9 H9 U; c9 h{
, Q" |# Z3 T# [( D4 n    // Update client config, and build packet containing that data
7 l5 w0 e  N/ y) o; F    m_ClientNetConfigLock.Enter();
1 |$ R5 [2 q* Z    m_ClientNetConfig.wUpdateRate = WORD(rate);
) s6 f# y  Z+ n, g3 c    ServerConfigPacket  packet( m_ClientNetConfig );4 r* Z- ~$ U  d' F8 ~
    m_ClientNetConfigLock.Leave();</P>
# h' m# D- j, y. N8 x2 u<P>    SendConfigPacketToAll( &amp;packet );
0 _4 z2 X' f5 a6 ^! b7 u0 ~3 y}</P>/ f3 R. M( F% M) d& H8 }
2 P# Q. ]$ Q: L
<P>
8 h3 N3 l/ d: ^% x  t- c) }//-----------------------------------------------------------------------------
/ U8 {3 ]8 l: ~! R1 {1 x0 X3 U// Name:
( R, k8 O( Y/ s0 G5 W% q% l5 v// Desc: % R4 x  c  H, R6 K
//-----------------------------------------------------------------------------" y: h; a- d0 N2 u4 [+ p
void CMazeServer::SetClientTimeout( DWORD timeout )
! {3 b! ^4 P1 i" y% }5 b{0 u. d% ?5 A7 h
    // Update client config, and build packet containing that data3 s8 k8 e  ]4 Z7 n  A3 T* ^
    m_ClientNetConfigLock.Enter();+ N6 W2 \& q% r0 E, Q2 l
    m_ClientNetConfig.wTimeout = WORD(timeout);
; X2 I: r$ B* Z! [& x; D8 K. e3 ]7 p    ServerConfigPacket  packet( m_ClientNetConfig );, S2 v' ~* `1 W
    m_ClientNetConfigLock.Leave();</P>( U' }" X7 s) U' c; ~
<P>    SendConfigPacketToAll( &amp;packet );
" g5 z0 x! ^# v- [}</P>7 a$ R0 ^2 ]2 o
$ l$ I/ Q+ L( M% `9 }
<P>
& v! l5 g& F* u! c//-----------------------------------------------------------------------------/ r4 w6 |( O9 Q. k: b
// Name:
6 ?/ J, Z9 `) I* `  @// Desc:
1 \  l6 @6 T* }$ g' b//-----------------------------------------------------------------------------) O: F% ~! {7 C0 G8 y% _: t
void CMazeServer::SetClientPackSize( DWORD size )
& ?( W) A# A9 R" V* K{4 b, h1 T$ z! {% T* `
    // Update client config, and build packet containing that data" `2 \) ~$ X4 [6 y
    m_ClientNetConfigLock.Enter();5 M+ ~7 u5 N2 ?+ |
    ! B. J  F) t& P3 K, q+ d- k
    m_ClientNetConfig.ubClientPackIndex++; //Increase index and verify location in array.
6 ~( z$ H+ B) ?& I9 {8 G0 N    if(m_ClientNetConfig.ubClientPackIndex &gt;= PACK_ARRAY_SIZE)   # b6 V% S& ]$ H+ l7 h
        m_ClientNetConfig.ubClientPackIndex = 0;</P>
( g/ Y5 o6 ~/ \<P>    m_ClientNetConfig.wClientPackSizeArray[m_ClientNetConfig.ubClientPackIndex] = WORD(size);4 h( t1 a' P1 T8 W6 a
    ServerConfigPacket packet( m_ClientNetConfig );- s8 x5 H9 n: i2 c1 Q
    m_ClientNetConfigLock.Leave();</P>
, o6 r: b9 b3 d; t9 C8 [<P>    SendConfigPacketToAll( &amp;packet );7 M8 @5 r: Y  X
}</P># G9 ^+ a1 K( ^" [0 f
8 }6 d# R) K! s: Z
<P>
2 Q6 R+ W- C/ O( C* P  t: E//-----------------------------------------------------------------------------
/ J0 A  Q! _8 ^3 E8 b  ^8 ^// Name: # A9 T, p* E. O6 x& x8 Y
// Desc:
# ?- X  e7 a( l1 \) ^//-----------------------------------------------------------------------------
9 @6 t: c/ F1 D# m- T: s9 i( A3 svoid CMazeServer::SetServerPackSize( DWORD size )2 z' \# _: z0 M8 q: t8 y6 N2 q% `
{
3 [& e, ]. J! w  F7 y6 ?' m5 H& w    // Update client config, and build packet containing that data
! ]- L1 D* n1 _! l) A( p& O$ T    m_ClientNetConfigLock.Enter();
+ w. [' G: f$ L: o  Q3 a   
' c/ B4 a5 a: n- B2 D" F    m_ClientNetConfig.ubServerPackIndex++; //Increase index and verify location in array.# A, H% I: C( Y) U
    if(m_ClientNetConfig.ubServerPackIndex &gt;= PACK_ARRAY_SIZE)   
0 w; Q4 H& C% m+ m: h; f        m_ClientNetConfig.ubServerPackIndex = 0;</P>1 W  @# Q# f7 O" {' S7 X& M& s; ~" o' j
<P>    m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex] = WORD(size);9 K/ w5 @( J0 C) z) W
    ServerConfigPacket packet( m_ClientNetConfig );
+ k$ w' q1 f5 s7 ~, [/ h! h6 y6 [    m_ClientNetConfigLock.Leave();</P>* V3 o% B- v) w2 |& n& V# M2 ^
<P>    SendConfigPacketToAll( &amp;packet );8 X, X  T5 y2 [) d, G0 X9 {
}</P>
1 t8 i3 c! Z/ s) [' f" ~<P>2 N. h/ I! D. U5 y1 W
//-----------------------------------------------------------------------------3 \( A8 p0 s$ `4 _4 s6 g0 y
// Name:
( y+ i- r9 t" [2 ]) e' P// Desc:
8 K" g+ L/ ~6 ?: \. R1 g//-----------------------------------------------------------------------------
3 n  Z0 C, V- T1 |$ Hvoid CMazeServer::SetClientThreadWait( DWORD dwThreadWait )
; s  i5 J' L9 r: r3 F2 y{% l! L: H. H5 X! |
    // Update client config, and build packet containing that data
% X& Q" T2 K1 B* F( b  Y; S% ^2 }    m_ClientNetConfigLock.Enter();
$ n. b3 }, @0 R" F" y    0 i3 e! D. s1 D5 [
    m_ClientNetConfig.dwThreadWait = dwThreadWait;: n  G  x0 w$ Z5 p7 [
    ServerConfigPacket packet( m_ClientNetConfig );9 b- }3 X% G& O, l  q
    m_ClientNetConfigLock.Leave();</P>; S9 v  ^7 E' x
<P>    SendConfigPacketToAll( &amp;packet );7 E+ J+ M' B; E8 q1 O5 |
}</P></DIV>




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