数学建模社区-数学中国

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

作者: ilikenba    时间: 2005-1-31 11:52
标题: [分享]MazeServer源码示例
<DIV class=HtmlCode>1 v( I8 S# D$ D8 x# }& R( J) m
<>// File: mazeserver.cpp( ]8 I% Y( r3 @$ Y; j5 L2 I; B
//
6 ~0 f& X" H' H, c7 f// Desc: see main.cpp
9 M: v) `+ E% d5 w//. b7 p1 F! J% P3 l- d) \# e
// Copyright (c) 1999-2001 Microsoft Corp. All rights reserved.& E& n) h1 d5 ~+ Z( c5 a2 l: }. F
//-----------------------------------------------------------------------------# o6 E5 P5 C5 N9 V7 @
#define STRICT
. Y- t& g- z  h#define D3D_OVERLOADS7 B: B8 R% N3 I/ l+ }1 q9 p) `
#include &lt;windows.h&gt;; t: P- z: |% G' b& I) d# q. ?
#include &lt;d3dx.h&gt;0 _# a" a. O/ x# i% i
#include &lt;stdio.h&gt;
9 z3 ?. `+ c& |& u8 r. p/ t. F9 m, w#include &lt;math.h&gt;
0 C: ]+ Y' e' V5 L#include &lt;mmsystem.h&gt;
8 {1 d/ N1 `" B#include &lt;dplay8.h&gt;
' D" k2 r0 b; k2 Z+ C: j#include &lt;dpaddr.h&gt;
4 W- B0 ]0 m) ^# t#include &lt;dxerr8.h&gt;- N  A$ _" g: U
#include "DXUtil.h"& Y) n* R7 U1 n) J
#include "MazeServer.h"
+ z$ N$ Q  D# ]: A6 I# D2 c#include "ackets.h") N. I4 _0 b$ ~6 M3 Q- o+ T
#include "Maze.h"* P. ?* L0 S! P: |& u: x8 ?
#include &lt;malloc.h&gt;
( R# U! _, g: {#include &lt;tchar.h&gt;</P># ]# c4 F4 ~, W; ?2 j/ d. N
/ O& G3 n4 _* X% [7 b) R
<>//-----------------------------------------------------------------------------
3 S8 w4 v" \- A1 Z6 ^! D// Name:
7 E) d- h% X$ n& m// Desc: ' K& l- H1 p* O& l& i  h' ^
//-----------------------------------------------------------------------------+ r/ l" ^, @% k: P
CMazeServer::CMazeServer()2 k. K6 w9 c( K4 i& o$ k
{
. D* v4 N9 g5 u2 x& x    m_dwPlayerCount         = 0;
3 I6 y. T+ n+ ?' ]   
9 v$ x( @7 s( i, b    m_wActiveThreadCount   = 0;9 r4 ~% ~: g. O  R
    m_wMaxThreadCount      = 0;
: g) b9 Q* C: F3 [/ A# K    m_fAvgThreadCount      = 0;: l7 y* [# o- C  q8 r" O0 E
    m_fAvgThreadTime       = 0;* H, f, q: s( }3 n- W; V! ~2 }
    m_fMaxThreadTime       = 0;</P>+ R7 c! g( G8 l; G7 E! x6 v  `
<>    m_dwServerReliableRate  = 15;
& ^+ R( U9 k, O    m_dwServerTimeout       = 150;
2 Z- \- P7 u7 t) O    m_dwLogLevel            = 2;
1 e9 ?. U. Z# s' Z7 N( u    m_pMaze                 = NULL;</P>
, h: q* d* ^; G<>    m_ClientNetConfig.ubReliableRate = 15;
8 K. c! w" J' q+ i' h- C7 A    m_ClientNetConfig.wUpdateRate    = 150;
- @; R2 {( M* X* x    m_ClientNetConfig.wTimeout       = 150;</P>4 R2 o( M8 Y+ c2 P9 ~8 v
<>    m_ClientNetConfig.dwThreadWait = 0;</P>
, t' b- z4 f* x2 [0 k/ ^<>    m_ClientNetConfig.ubClientPackIndex = 0;" f8 e% W2 P6 W3 X
    m_ClientNetConfig.ubServerPackIndex = 0;
, l3 B) v+ l& K5 r6 j' t    for(WORD x = 0; x &lt; PACK_ARRAY_SIZE; x++)# ]0 t5 X7 \2 n6 Q, I  @
    {
+ J  A+ k  E( V  y0 E        m_ClientNetConfig.wClientPackSizeArray[x] = 0;
# U3 L5 T8 U3 H2 s        m_ClientNetConfig.wServerPackSizeArray[x] = 0;$ b4 U3 v0 l5 w; P0 h% \: B" u* W
    }) n( x; D8 b4 t
}</P>" K, h2 H% T( ]* I% r) m* r2 P

, q( ?8 A1 ?3 d& n& v& \<>! Y# I9 b' f* W8 ?! c# s
//-----------------------------------------------------------------------------$ s# c3 M4 s0 l5 Z* u( q
// Name:
" r' }3 t0 j6 P: f: ~# R// Desc: . S! r: a' ^0 o, s( z
//-----------------------------------------------------------------------------) m2 ]+ Q, {7 f3 W# f
HRESULT CMazeServer::Init( BOOL bLocalLoopback, const CMaze* pMaze )
7 F8 |9 e9 M* m% v+ g' Z{
/ a; y  n- u1 U) O2 a    m_bLocalLoopback = bLocalLoopback;& h, U1 u' W6 }, W" ]3 y. i
    m_pMaze = pMaze;* O; j. M2 ^" \3 R1 b" C% D+ J
    if( m_pMaze == NULL )3 n+ J+ @" e  f" M$ h$ u  V8 Z
        return DXTRACE_ERR( TEXT("aram"), E_FAIL );</P>% Z: _0 v! d8 w5 E) V
<>    // Grab height and width of maze  ^6 V) \% I5 j4 r# H" Y; n' |$ u
    m_dwWidth = m_pMaze-&gt;GetWidth();
% k" Q1 y  v! m' r" Y; p- T    m_dwHeight = m_pMaze-&gt;GetHeight();</P>
' y" @3 ]& Y% L<>    m_ClientNetConfig.dwMazeWidth  = m_dwWidth;
' B# o' q3 [% U9 t    m_ClientNetConfig.dwMazeHeight = m_dwHeight;</P>
# A4 P( h3 O; n8 F6 G<>    // Validate size. Must be a power-of-2 times LOCK_GRID_SIZE. Compute the shifts.: w9 X3 V! z' Q
    if( m_dwWidth &gt; SERVER_MAX_WIDTH || m_dwHeight &gt; SERVER_MAX_HEIGHT )5 M# G' w  u% ]0 i0 d* H
        return DXTRACE_ERR( TEXT("Maze height and width need to be less than 128"), E_INVALIDARG );
$ l! F6 D, n' J  E0 z" V    if( (m_dwWidth % LOCK_GRID_SIZE) != 0 || (m_dwHeight % LOCK_GRID_SIZE) != 0 )* K2 J- [$ P0 l5 k2 q0 c* i7 \
        return DXTRACE_ERR( TEXT("Maze height and width need to be divisable by 16"), E_INVALIDARG );</P>
& B3 T: I7 |( w3 Q$ i$ ^<>    DWORD scale = m_dwWidth / LOCK_GRID_SIZE;
$ n" n; m$ F' B2 T1 ]0 I' X    m_dwMazeXShift = 0;
( N. U# e& ]! k# l4 |! o    while ( (scale &gt;&gt;= 1) )
' M( e0 a; i! }' Y6 A" `3 o        m_dwMazeXShift++;</P>- B2 V8 ]& ^) D9 z2 ^$ I# z
<>    scale = m_dwHeight / LOCK_GRID_SIZE;5 W# l& x6 \$ u) E' A) |7 P& r
    m_dwMazeYShift = 0;
) s5 m6 q, S# `- X0 t, u8 ]& c+ e    while ( (scale &gt;&gt;= 1) )
3 ?  Q/ m  b5 W3 x# D: g; i0 X" d        m_dwMazeYShift++;</P>
" G5 j* K3 s  ^: U( v7 d: l; A<>    if( ((DWORD(LOCK_GRID_SIZE) &lt;&lt; m_dwMazeXShift) != m_dwWidth) ||9 @2 G& l/ v/ u7 h' k& M: v% O
        ((DWORD(LOCK_GRID_SIZE) &lt;&lt; m_dwMazeYShift) != m_dwHeight) )
+ c. i: n0 Z9 L, X3 \. ?        return DXTRACE_ERR( TEXT("Maze height and width need to be power of 2"), E_INVALIDARG );</P>8 l6 b0 D; B5 v
<>    // Initialise the player list
8 q& s( @$ Z2 I- Y9 B    ZeroMemory( m_PlayerDatas, sizeof(m_PlayerDatas) );
) z" p% _$ L2 T5 L4 P; W    m_pFirstActivePlayerData = NULL;* A6 M3 z3 Q; m( w
    m_pFirstFreePlayerData = m_PlayerDatas;
4 G' d4 j1 G2 W    for( DWORD i = 1; i &lt; MAX_PLAYER_OBJECTS-1; i++ )! a+ q- T2 T* S* s
    {
! j# w# x" ?3 ?  ^9 B* M( q        m_PlayerDatas.pNext = &amp;m_PlayerDatas[i+1];- ^% M7 ^8 s7 m( u- X
        m_PlayerDatas.pPrevious = &amp;m_PlayerDatas[i-1];
& b5 c; q* G' p& ~9 K  f: f2 v    }</P>
) v- [% x1 N: Y<>    m_PlayerDatas[0].pNext = &amp;m_PlayerDatas[1];0 D3 Y' H+ k4 b- W+ W$ F" f) d9 W1 H
    m_PlayerDatas[MAX_PLAYER_OBJECTS-1].pPrevious = &amp;m_PlayerDatas[MAX_PLAYER_OBJECTS-2];
/ O* r, _% G0 e    m_dwActivePlayerDataCount = 0;
% w. F4 p; K7 G: M7 ~, Y    m_dwPlayerDataUniqueValue = 0;</P>
, c  b. H% L3 D! x<>    // Initialise the cells; ]5 n  `4 A- m' L" j0 J0 J
    ZeroMemory( m_Cells, sizeof(m_Cells) );
' s6 [  m5 G/ l    ZeroMemory( &amp;m_OffMapCell, sizeof(m_OffMapCell) );</P>
+ y: P; Q$ {& @1 i2 i<>    return S_OK;
. `9 e( D" I8 u, O% O2 E: r* n* V9 A}</P>
' t+ w# x, x9 K% d8 {8 U1 K3 K' |1 O: X% E
<># J# c; Z' @; r+ Z
//-----------------------------------------------------------------------------! c  p0 q3 }) M, p, O
// Name: , s3 u/ M) i( [9 i0 c. p" d) a  s; C
// Desc:
0 E* S5 E8 y/ b1 V# o//-----------------------------------------------------------------------------) @/ A9 G- o1 n  j7 Y: E* d) Y7 ?# U
void CMazeServer::Shutdown()! O" r# U2 ?" C9 I$ ?: a
{
* @, r+ U( I/ {}</P>
& f2 f. X, J( e' Z) D, h1 e/ g9 K& M) s1 H% ^4 H% b
<>' B% a; o! w! W- |! s2 t8 s3 B3 g
//-----------------------------------------------------------------------------6 Q8 p1 x( u) M; S. E2 b, L
// Name:
" a! L. {: `- }7 o; L9 u* v// Desc: 4 Y" k" o9 z' q/ T  t# n
//-----------------------------------------------------------------------------
' H. `; G5 v( ]) d- |5 Dvoid CMazeServer:ockRange( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )5 f9 e* J) o5 {# |) e
{* s+ k3 O/ Q$ G$ l: a) J
    m_LockGrid.LockRange( x1&gt;&gt;m_dwMazeXShift, y1&gt;&gt;m_dwMazeYShift ,
9 G# I6 x6 r/ a+ ]- ^                          x2&gt;&gt;m_dwMazeXShift, y2&gt;&gt;m_dwMazeYShift );; q( s3 s  K# R5 n" d
}</P>+ Z9 L# b% Q- }4 x
) x2 v0 n8 {1 T, I  i
<>) ^) J; X8 a6 V6 b
//-----------------------------------------------------------------------------' T0 C6 a$ x. ?: o; Y% G
// Name: 2 ]+ B; q& @& V, f
// Desc:
6 ]; @3 q% z8 r& m0 G1 D" p4 D4 e//------------------------------------------------------------------------------ {- J3 |2 u  Z# Z
void CMazeServer::UnlockRange( DWORD x1, DWORD y1, DWORD x2, DWORD y2 ). U1 i% i. ]3 i1 G4 l8 ]' Q
{
) C8 T" m: p+ K, I9 _4 \    m_LockGrid.UnlockRange( x1&gt;&gt;m_dwMazeXShift, y1&gt;&gt;m_dwMazeYShift ,
9 ]) d; m9 a; J0 s- o: [) }7 l- Q                            x2&gt;&gt;m_dwMazeXShift, y2&gt;&gt;m_dwMazeYShift );
" z/ a5 F# ~0 i' \2 P}</P>' ^$ [4 K9 E6 X" b

( C; y! C  I) A2 i5 Q6 M<>+ T2 ~! N2 j  o) ], q( c
//-----------------------------------------------------------------------------. X' w/ R  E- s+ W0 U& k7 x- A
// Name:
% G1 d& t/ P: \, R9 u, y// Desc: 0 S$ j1 F/ V: [( n  d# r4 E3 q
//-----------------------------------------------------------------------------
( F' H, j! W0 n; D/ i! O. \void CMazeServer:ockCell( DWORD x, DWORD y )
9 ?5 F) K. s+ Z( X7 `{3 d3 B8 d, X6 D6 C7 J3 M
    if( x == 0xffff )
' {" }7 b. ]" w6 W' S        m_OffMapLock.Enter();
  v" C1 c: z9 q% p' I    else/ |% s1 `7 q6 r
        m_LockGrid.LockCell(x&gt;&gt;m_dwMazeXShift,y&gt;&gt;m_dwMazeYShift);4 q0 b) [: R1 o' o) ]. V
}</P>
5 O; K9 I# O- K, t6 T
3 E0 X! k3 `/ p7 E- ^<>
: H! C; y$ ?0 D6 l//-----------------------------------------------------------------------------5 A+ a, l& C6 G7 I* E" G, K" I; R
// Name:
" p+ s  ?% Z7 E// Desc:
; w5 @$ _; n8 s7 J4 `5 v$ W//-----------------------------------------------------------------------------
' |# m" A( |: O/ S. R7 |void CMazeServer::UnlockCell( DWORD x, DWORD y )8 u# [3 e) e% c( P* C
{
) v4 Q) A; b- Y& X! V    if( x == 0xffff )+ J5 Q( [: h1 A$ s% N. H
        m_OffMapLock.Leave();
5 h1 f: c5 @% E; O' Y" {. I1 z    else
. {3 J6 R$ @1 Y7 s; U* @7 J        m_LockGrid.UnlockCell(x&gt;&gt;m_dwMazeXShift,y&gt;&gt;m_dwMazeYShift);
8 S3 G# M5 S( ]& V/ ?# x}</P>
6 q5 C- J# E! Z+ U1 e* G3 F" w. V: V" R9 C: ?
<>* ]/ c* \  ~8 J! c) W" a
//-----------------------------------------------------------------------------( A5 ]; f$ r6 J0 a
// Name: & V. U' ?; y' J: o8 x3 B7 \+ A" D
// Desc: ' U2 h+ v' M: b2 t
//-----------------------------------------------------------------------------$ k' ^% t0 G: u
void CMazeServer:ockCellPair( DWORD x1, DWORD y1, DWORD x2, DWORD y2 ), s- }, [! C+ W
{& O' m: X  k, \3 ?# j; C
    if( x1 == x2 &amp;&amp; y1 == y2 )8 a0 u: I4 Z; E  [7 h# `
    {4 T+ l) A, e, C
        if( x1 != 0xffff &amp;&amp; y2 != 0xffff )
% @7 C) D7 \8 e0 b& y            LockCell( x1, y1 );
  R+ q8 |8 L/ Q7 h' T        else
+ l. Q1 @% h" \! E/ K            m_OffMapLock.Enter();</P>
+ j' u) E- j4 c  t5 g: o  v<>        return;
, Z! ?& m6 W( y2 _0 l# e4 {    }</P>
% U  ^; \' m1 q% ?6 i, D<>    DWORD x1shift = x1&gt;&gt;m_dwMazeXShift;3 B' v4 m% i" d2 n+ ^# ~
    DWORD x2shift = x2&gt;&gt;m_dwMazeXShift;
3 B, p! i4 d9 P) r3 w    DWORD y1shift = y1&gt;&gt;m_dwMazeYShift;
2 i- \' g+ O  H6 p/ r1 r6 i) ?    DWORD y2shift = y2&gt;&gt;m_dwMazeYShift;</P>3 W; k( }6 E( w# v( H
<>    if( x1 == 0xffff )5 {# ~2 q0 K* i) F3 l) J2 j
    {
: E( j2 L* `! X7 M& h( E        m_OffMapLock.Enter();$ U, K2 ?& m" ~
        m_LockGrid.LockCell(x2shift,y2shift);
+ z1 }/ C/ {" [, E* ]    }
; m5 c: c, X  G$ d4 e+ r# _$ b. m+ G8 v    else if( x2 == 0xffff )% Y  Z; v9 B) r
    {5 P/ P: u1 A' x3 ~* @
        m_OffMapLock.Enter();6 J3 }% v. V: w3 C% C/ s; X7 v
        m_LockGrid.LockCell(x1shift,y1shift);
0 Q: j# h: q- @% ]4 n6 a) C0 g    }
. r( a* I( T; C5 Q    else
6 l7 r8 j! L; T2 Q' T) V6 \    {
9 T" V! S) s2 e1 J, T: r- z5 X        m_LockGrid.LockCellPair(x1shift,y1shift,x2shift,y2shift);' _0 G. h7 \$ r0 O' [; X; q& P
    }
# u! H" r1 g/ M, B2 Q0 D/ }}</P>
9 c% j6 f7 `3 B. i9 q; ^
( ~$ s  R/ b+ M8 k( R2 C* L<>
2 ~* f- [5 m6 K; |: W//-----------------------------------------------------------------------------! b- T) Z- {5 ?( w1 O6 u
// Name:
- y! r( D4 \$ t+ s. U// Desc: ) h' D8 z  h3 ?# y2 H( p$ T
//-----------------------------------------------------------------------------
* B  u1 ?7 w7 j3 Bvoid CMazeServer::UnlockCellPair( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )* `2 r" V' ^, U
{( `* W, p( j- a
    if( x1 == x2 &amp;&amp; y1 == y2 )
3 w: V; m0 l9 k    {, C1 G6 b) m7 u* V8 @2 s. k: @
        if( x1 != 0xffff &amp;&amp; y2 != 0xffff )- e/ Q/ g9 l: f2 B8 Y8 M# n9 G0 ?4 c
            UnlockCell( x1, y1 );3 R# ?) w4 J+ ]6 b9 F
        else- I- t$ m5 X8 b& u, ]" r( O
            m_OffMapLock.Leave();</P>( G8 p5 f6 s0 ?6 S2 Z6 B
<>        return;
. @8 r8 G$ P8 R+ v# A0 m' T9 X8 l! o    }</P>
- n( n% ]" B; j3 K# ]<P>    DWORD x1shift = x1&gt;&gt;m_dwMazeXShift;
* l6 ?, g( T3 A1 ~( P* i    DWORD x2shift = x2&gt;&gt;m_dwMazeXShift;
6 C# O8 o6 h! s8 }4 K' z    DWORD y1shift = y1&gt;&gt;m_dwMazeYShift;6 r9 f+ o8 V" _& r
    DWORD y2shift = y2&gt;&gt;m_dwMazeYShift;</P>+ K6 ~6 \7 M2 Q  |5 V9 k" {6 `
<P>    if( x1 == 0xffff )
8 ?% w1 ~. Z2 X9 |5 X0 j    {, d1 }! H1 W2 }7 S3 P2 T8 [
        m_LockGrid.UnlockCell(x2shift,y2shift);
4 K" ~" B$ k, d5 s9 q        m_OffMapLock.Leave();
! d& N  Y5 w) U% Y4 k5 ?5 A    }, W# t* \  A! W
    else if( x2 == 0xffff )
4 N9 E0 i, B1 h1 P" D    {/ Y3 a+ N6 M8 ~7 X
        m_LockGrid.UnlockCell(x1shift,y1shift);
% l* N( h6 K" V1 A; }        m_OffMapLock.Leave();
5 r3 t) L, B, p1 G    }
; m" M1 m/ A9 M+ S4 U+ K5 ]    else . A1 f. x7 u- |5 g
    {$ N: }' Y4 n1 |$ X# f. H2 H
        m_LockGrid.UnlockCellPair(x1shift,y1shift,x2shift,y2shift);
  p- v6 i/ ^! i( D; o9 C7 G- T. u" ~: J    }. o% T% e, o6 Y& `! E
}</P>1 E, ^- T* w5 `
0 `$ @' J8 u+ k% o7 L+ u; ~- L  q: i' Y
<P>: H$ z. V; s8 W* T4 Z7 q  q
//-----------------------------------------------------------------------------
* p+ L8 d+ z( |7 T// Name: 4 X  g3 n$ |" g4 J9 e1 t; n
// Desc:
) z. B2 I8 P3 c5 O( r//-----------------------------------------------------------------------------
; k) J! P* s: Y  Z1 Avoid CMazeServer::OnAddConnection( DWORD id )+ A: C) y! Z: U
{
' g7 {& F. @* t2 n1 m    m_AddRemoveLock.Enter();</P>
4 U5 a7 \/ \5 ?: C$ J" |  {<P>    // Increment our count of players
9 p7 w% [1 U; J2 P7 n    m_dwPlayerCount++;
* H: o# Y% }) y9 F    if( m_dwLogLevel &gt; 0 ). u1 F. _% F1 c5 {& M
    {. m0 K; q/ ?( _" t2 C' R5 l# r6 d( I
        ConsolePrintf( SLINE_LOG, TEXT("Adding player DPNID %0.8x"), id );
, m3 d; d3 v" W' B$ Z        ConsolePrintf( SLINE_LOG, TEXT("Players connected = %d"), m_dwPlayerCount );7 o" I4 f) m+ a( B
    }</P>
% a- X* [, @1 c6 d0 M- L$ p) w6 D* K<P>    if( m_dwPlayerCount &gt; m_dwPeakPlayerCount )
3 Q4 b7 x  x! P0 u. }. ^+ s        m_dwPeakPlayerCount = m_dwPlayerCount;</P>0 z* P# m; e& j! ~7 h, q- P0 b5 O2 P
<P>    // Create a player for this client3 h+ g4 |: q4 d7 Q! C0 j3 L3 s
    PlayerData* pPlayerData = CreatePlayerData();
( G0 r) |% k5 n    if( pPlayerData == NULL )4 j* K2 e* |9 |1 J  i2 W3 a7 u6 g
    {
7 q2 |4 L) n  b4 M5 E2 y* H* X2 C        ConsolePrintf( SLINE_LOG, TEXT("ERROR! Unable to create new PlayerData for client!") );6 U* a9 u% @5 P* B+ E8 U$ s' R
        DXTRACE_ERR( TEXT("CreatePlayerData"), E_FAIL );% d# t# b* E) q
        m_AddRemoveLock.Leave();( ^7 f0 Y: Z0 f5 T$ p
        return;
" l  ?5 y% }, o    }</P>- l0 @: g; B# o$ |7 f( o( S
<P>    // Store that pointer as local player data
/ Q. ]3 X8 l* ?  w9 V0 s    SetPlayerDataForID( id, pPlayerData );</P>4 Y0 D+ L% t& q4 I
<P>    // Grab net config into to send to client% q% C& H) j) A* t
    m_ClientNetConfigLock.Enter();- \& _' D: s% Q! m' ^" J
    ServerConfigPacket packet( m_ClientNetConfig );
5 E$ @1 Q. M- J) B8 Y    m_ClientNetConfigLock.Leave();</P>
% P: b- n2 n7 I0 [<P>    // Send it$ ?; e7 W1 U6 S" x
    SendPacket( id, &amp;packet, sizeof(packet), TRUE, 0 );</P>
6 U% Q' k! f1 B6 q  @) U<P>    m_AddRemoveLock.Leave();9 l: p3 \8 H, N: ~) Y
}</P>
" m" H. g9 ~) v5 o& J
/ ?+ I0 R0 g  r+ c0 g. t<P>2 S. v  G0 Y( S0 G7 `
//-----------------------------------------------------------------------------9 P' p4 U% J. M' e/ |9 j/ ^
// Name: 3 G! N( e1 y/ p8 g
// Desc: / y& Z' G* y6 @: e
//-----------------------------------------------------------------------------/ v1 y1 m! z7 D% I% W; }
void CMazeServer::OnRemoveConnection( DWORD id )7 A; U7 z4 _; r! G1 q
{% H$ v+ Z( h' T) S! w6 S. U
    m_AddRemoveLock.Enter();</P>
) e* a1 [) g3 l9 s" |5 B0 l<P>    // Decrement count of players
. [2 n7 O5 p3 V0 M( N; s; D, `$ {    m_dwPlayerCount--;</P>
$ {0 L+ m. L9 \2 U* N<P>    if( m_dwLogLevel &gt; 0 )
$ k$ A) P" A5 u. }" w6 |) Z$ b: p" `  U    {/ p1 r; \  f  R# L" b1 ]/ P2 X
        ConsolePrintf( SLINE_LOG, TEXT("Removing player DPNID %0.8x"), id );9 V. h7 m2 o8 H* |" W
        ConsolePrintf( SLINE_LOG, TEXT("Players connected = %d"), m_dwPlayerCount );" F# m, c* a* k! s
    }</P>& p# L% I* U& }% S) p9 Z
<P>    // Find playerdata for this client
  h- q/ R1 O1 z3 {    PlayerData* pPlayerData = GetPlayerDataForID( id );0 \  z4 h8 s! B- r9 E! _1 K
    if( pPlayerData != NULL )
! k: r$ H$ }9 ]* a" n8 T    {
, U* K. ]* e* g6 ^3 @" s        // Destroy it
- r: ^4 o8 g: y* ~        RemovePlayerDataID( pPlayerData );
$ W8 z+ K% d" d/ R        DestroyPlayerData( pPlayerData );
  ]& k" Z4 S/ H2 \; n! |" a    }</P>
  O  \" P: c! ?0 A, s<P>    m_AddRemoveLock.Leave();3 _' E. d: e9 T# C5 w
}</P>; r; W5 w) ?9 D
& B! w: v/ p5 E
<P>
4 T- N! }7 s5 m8 N//-----------------------------------------------------------------------------2 J& a3 u& U$ y
// Name: . S2 M8 {0 @! m: i8 F
// Desc: ! U  r, C3 z0 V! h- F
//-----------------------------------------------------------------------------
5 C9 [7 G' C: aHRESULT CMazeServer::OnPacket( DWORD dwFrom, void* pData, DWORD size )+ |2 j6 K& |9 x9 E# b
{
0 b" \: S6 [0 }& N- a    BOOL fFoundSize = FALSE;</P>7 d3 g. y/ h8 Z2 p
<P>    // Increment the number of thread we have in this process.# j- _6 d) {/ L7 G
    m_csThreadCountLock.Enter();</P>
+ v( d3 x+ \) A, o! O<P>    //Get the start time of when we entered the message handler.
: @3 G. O& o0 l) n1 g    FLOAT   fStartTime = DXUtil_Timer( TIMER_GETAPPTIME );</P>4 ~; R1 j; o& E/ k" M+ [
<P>    m_wActiveThreadCount++;; T% W1 D1 t( k( O3 E
    if(m_wActiveThreadCount &gt; m_wMaxThreadCount)1 d7 l& U9 G! e% Z+ D6 }
        m_wMaxThreadCount = m_wActiveThreadCount;
  l7 ]: A1 p, Q- T    ) _1 m' m; O0 I" p0 t6 x$ r
    // Calculate and average.
' q0 }# L) ]+ Z) j    FLOAT fdiff = m_wActiveThreadCount - m_fAvgThreadCount;
; X0 t$ D3 W5 n( ~3 k    m_fAvgThreadCount += fdiff/32;- a  b7 H. a* h& M- [% _' b0 w
   
+ w. C4 _! a$ E, h: X    m_csThreadCountLock.Leave();</P>
" q+ \' }# p) \$ I& X* T<P>
# u0 t/ c9 g9 n; H    ClientPacket* pClientPack = (ClientPacket*)pData;
- e8 y: Q: i/ u1 z    switch( pClientPack-&gt;wType )  o( \( P: Z2 I) c4 O: I6 q9 i
    {7 e* V- N' S: ~7 @, P2 A/ c
        case PACKETTYPE_CLIENT_POS:2 y/ n7 ?. v! v3 i3 C& X, m, |) @
            2 |3 q2 n* w1 [) f
            // Check to see if the packet has a valid size. Including
# s' z1 F: L% X5 j5 _" c            // the custom pack size.
4 [! L- R) M; m. e3 E! g( t( [            if( size &lt; sizeof(ClientPosPacket))7 ^3 Q4 D: h$ `4 F& [3 q
                fFoundSize = FALSE;1 U: }" t, _" _5 w- l4 v
            else if( ! IsValidPackSize(size - sizeof(ClientPosPacket)))
, A, W' c" u- d                fFoundSize = FALSE;
% T/ M, p, k5 U# Z            else
4 \' l7 V$ K7 z7 J; C                fFoundSize = TRUE;</P>0 B& |* Y: M% ?' l* A/ a
<P>            // If valid sized packet, handle the position.
+ f" @* G$ R, W* N: c) u% [8 {" u( M            if(fFoundSize)) J0 k8 {' u! `+ r) T3 ]8 n( e
                HandleClientPosPacket( dwFrom, (ClientPosPacket*)pClientPack );
, X+ E/ ]( n' E1 k% s            else
6 x1 z4 X$ \/ i! @                m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );</P>
" K. I" }. W, J2 h<P>            break;</P>0 Y# [; v4 r2 s! U! P
<P>        case PACKETTYPE_CLIENT_VERSION:
9 Z8 E( c, p6 S0 ?            if( size == sizeof(ClientVersionPacket) )8 O" r% z9 s+ j6 _
                HandleClientVersionPacket( dwFrom, (ClientVersionPacket*)pClientPack );- R3 X4 M, ]; x: f
            else1 O  ?7 l' p& K% d
                m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );
$ B5 x; K- E; ?  F3 W0 M5 {            break;</P>6 O3 a: Q6 G9 `
<P>        case PACKETTYPE_SERVER_CONFIG:</P>$ X7 B! W% |: V6 C& N' |* {& z2 s
<P>            // Server config packet sent to all users (including server). Just ignore and continue.</P>2 ?* I; p, f) T; h  a: r/ @
<P>            break;
7 |( o, R6 }$ O, U5 ^( Q        default:0 x1 w, C3 w# X
            HandleUnknownPacket( dwFrom, pClientPack, size );; n4 z; x7 p8 |0 M8 U6 N* R& o
            break;
1 l1 _: M, l+ X6 ]# u, M    }</P>+ l* W* Y! ?3 a. Y+ L/ B: v
<P>    //If the user wants to hold the thread, Sleep for given amount of time.6 H( K) I9 H# e3 k" U3 \3 Z% \
    if ( m_dwServerThreadWait &gt; 0 )
; P9 \1 P& d( q7 F1 Y: R    {& i8 d. G$ a- H; ^( W
        Sleep( m_dwServerThreadWait );
- @# [( U2 P8 J2 y5 N' s    }
9 H  Q* R. x" g$ U6 A% J$ `8 D/ Y   
8 Q3 r% N- }+ I% [+ ?    // Retrieve thread data for this process.- X( g7 h, E! i
    m_csThreadCountLock.Enter();</P>
, v1 g7 K& K! A" Z<P>    m_wActiveThreadCount--;</P>
+ O- A9 m3 ]9 X4 e3 a<P>    FLOAT fDiffTime = (DXUtil_Timer( TIMER_GETAPPTIME ) - fStartTime) - m_fAvgThreadTime;6 Y4 z% ]" _% Q
    m_fAvgThreadTime += fDiffTime/32;</P>  v# Z0 l- ]! \
<P>    //Get the Max time in the thread.& q3 H4 e' W5 c+ T5 v, ~
    if ( fDiffTime &gt; m_fMaxThreadTime )& g  F' O& |6 g3 ?: Z
    {
: i. _, O- Y- l* w        m_fMaxThreadTime = fDiffTime;
, R  B" X; M1 T* }1 W    }</P>
4 P# d. T! {0 E, z. W5 Q<P>    m_csThreadCountLock.Leave();</P>7 `0 ?2 R! f* _0 }/ U; R. {, L7 `
<P>    return S_OK;
5 }# [0 ?: R6 ]4 ]. R}</P>
( S3 c0 M. R3 [' W. M: B. C# F7 H8 d- c' y
<P>//-----------------------------------------------------------------------------, u, k9 i- ]( @/ X+ C& R. g% a
// Name: ) b: a+ Y7 m) P0 G
// Desc:
# B& j! p* K/ d# O; O//-----------------------------------------------------------------------------
. z- ^: E3 l( P. p6 h' TBOOL CMazeServer::IsValidPackSize( DWORD dwSize )
: b8 `/ y5 {$ N5 F3 q/ l6 ^{* q: R6 S7 I; V) Q* w& R
    BOOL fFoundSize = FALSE;
) y; \- Q( h! T3 I    BYTE ubPackLocation = m_ClientNetConfig.ubClientPackIndex;6 [, U$ b5 T* p/ c: A" j
    - j: t3 ]& F! t2 h
    // Check through the array of valid pack sizes.# ^, c% y8 ~7 @& s8 t3 j
    if(dwSize != m_ClientNetConfig.wClientPackSizeArray[ubPackLocation])9 k/ e% s$ t% M+ E4 x& Q1 G" v9 z
    {6 B  w: k5 a5 S8 v/ k
        for( --ubPackLocation; ubPackLocation != m_ClientNetConfig.ubClientPackIndex; ubPackLocation--)
2 z$ c1 B3 a" u2 X: K        {
: L: i4 a. @/ z! |6 l, e1 a            if(dwSize == m_ClientNetConfig.wClientPackSizeArray[ubPackLocation])* O- s( t. i; y2 |/ m4 @5 Q" ~- y
            {
: h$ Q- U% k# N6 f% f                // Found valid size in the array.
. k+ z+ l* ?' M0 F: T9 P+ k                fFoundSize = TRUE;
! e' [: g* X% Y2 [5 \/ l, [, T                break;
3 o* t1 I3 D; w- {. C6 b) y  @2 h            }' n1 r2 W6 A4 O; C) Y+ F' v$ F$ x
            if(ubPackLocation &gt;= PACK_ARRAY_SIZE)  ubPackLocation = PACK_ARRAY_SIZE;  //Wrap the array.
1 M4 z* a$ D/ i2 T8 k        }6 m& v. t2 f$ E- m, e1 w
    }
! c; w4 d1 {6 x, q    else
# E0 j6 r! \6 t1 l- n5 ^2 s2 t    {
* E% r& h. V: M        fFoundSize = TRUE;: o+ p: W) e# J# W7 @) l/ ^
    }</P>2 z( L3 J2 }! `/ q- `$ d
<P>    return fFoundSize;- ~1 m8 q+ D  G% W+ |" |
}</P>
0 o# o% y0 z5 ]<P>
/ m2 O- W! e% {" _6 x; A4 i//-----------------------------------------------------------------------------& v+ ?, T" ?! ?; }8 O* B; G
// Name:
1 I3 [* o$ r1 \* h4 ~% ?2 g// Desc:
0 V( d$ z+ g; e( D//-----------------------------------------------------------------------------& P. _5 q7 v' q9 s9 l
void CMazeServer::OnSessionLost( DWORD dwReason )
4 W* l3 s8 n/ g/ |4 o{
& L& }4 q  u! E4 x) `    ConsolePrintf( SLINE_LOG, TEXT("ERROR! Session was lost") );
- J3 i9 _& z, a0 Z' M( _}</P>
) d* ^* v7 S! T3 e9 a; e  _) G, K% u: X- g& z
<P>: m  O! m; {! L4 l. }& [  G3 M+ M
//------------------------------------------------------------------------------ I* ]( L0 o" A" m
// Name:
3 F2 W/ Y6 v, N/ k. j( ^% Y// Desc: 7 v* _2 {; O# f, G
//-----------------------------------------------------------------------------
0 o" Q! P4 O' R6 D8 CPlayerData* CMazeServer::CreatePlayerData()
" p9 c7 }7 h: F# y4 t5 |0 a{
; a# A& ]. o# }+ @% }  H    m_PlayerDataListLock.Enter();</P>
. o6 R% [# W) A0 X<P>    // Grab first free player in the list
) c( U, b: }6 j1 A! q% ]    PlayerData* pPlayerData = m_pFirstFreePlayerData;</P>$ A! k7 g4 m3 |+ h5 ?: q9 ]3 G9 A
<P>    if( pPlayerData ). _+ f! S* \5 I
    {: Q, d" S" O# P7 Z) P" i
        LockPlayerData( pPlayerData );</P>* l3 ^" A# {( E, w- {9 r: b" S4 W( h
<P>        // Got one, so remove it from the free list/ H3 W% f8 k. C6 O' O5 ?
        if( pPlayerData-&gt;pPrevious )
# i1 D* p( _9 R( K$ Z0 S- Y( L1 x/ o            pPlayerData-&gt;pPrevious-&gt;pNext = pPlayerData-&gt;pNext;
. M/ P% T) D$ B+ T% o% o( O7 k2 j        if( pPlayerData-&gt;pNext )/ A/ F- {4 D9 A9 C
            pPlayerData-&gt;pNext-&gt;pPrevious = pPlayerData-&gt;pPrevious;: O0 S# S7 Q2 f9 ^0 D
        m_pFirstFreePlayerData = pPlayerData-&gt;pNext;</P>
' P9 l* o, t0 P: t0 l* \# p4 `<P>        // Add it to the active list
/ [  L3 P% r$ x& }* Z2 U6 K4 n        if( m_pFirstActivePlayerData ); O2 M' `, m, s% h/ [# Z! ?
            m_pFirstActivePlayerData-&gt;pPrevious = pPlayerData;
; T' I9 G" @9 ^2 C" i- @        pPlayerData-&gt;pNext = m_pFirstActivePlayerData;
# Z" d& |' ?6 @2 N0 |8 X( k. z/ N        pPlayerData-&gt;pPrevious = NULL;& B* g$ `) q; Z) F% ~
        m_pFirstActivePlayerData = pPlayerData;</P>8 H$ ?3 w6 L( H
<P>        // Update count of players& G4 Y7 V  r5 c/ d: u/ C1 t; Q& w
        m_dwActivePlayerDataCount++;</P>
1 z, t' P1 g1 ^# d3 g1 R* C) i<P>        // Generate the ID for this player3 E5 b# e9 h9 \3 G( S
        m_dwPlayerDataUniqueValue++;
, y) Y  N/ n' F6 r) P' ?/ V        pPlayerData-&gt;dwID = (DWORD) ((pPlayerData-m_PlayerDatas)|(m_dwPlayerDataUniqueValue&lt;&lt;PLAYER_OBJECT_SLOT_BITS));</P>( a3 ~* U' s' F' d+ S, F6 r( @
<P>        pPlayerData-&gt;pNextInIDHashBucket = NULL;8 Q) C. q: n( b% ^( X3 S
        pPlayerData-&gt;NetID = 0;3 S- S( U% T& f
        pPlayerData-&gt;dwNumNearbyPlayers = 0;</P>
5 K) _% a  @) e) B6 F5 u2 O<P>        // Insert into the "off-map" cell
# j$ A8 w0 B' d6 @% H( |1 N% @% z        pPlayerData-&gt;fPosX = pPlayerData-&gt;fPosY = -1;
) \& _8 Z( W( q2 O. m+ S        pPlayerData-&gt;wCellX = pPlayerData-&gt;wCellY = 0xffff;# O& V. L  k- B) u6 x8 O* |
        m_OffMapLock.Enter();
$ o7 d% U4 R+ R& x4 O" f        pPlayerData-&gt;pNextInCell = m_OffMapCell.pFirstPlayerData;$ k3 S8 O. I. t; z+ H
        m_OffMapCell.pFirstPlayerData = pPlayerData;& J; I: m- B1 a6 @- D+ x) L+ k
        m_OffMapLock.Leave();</P>
/ s$ |! f! k8 }8 i5 `' ~<P>        // Mark as active0 D% B- H) t4 x
        pPlayerData-&gt;bActive = TRUE;</P>& U6 r# B/ L$ x; g: Q) i! Q" Q
<P>        UnlockPlayerData( pPlayerData );
  X, o/ L9 u% A  ?! f* ^    }</P>
, o7 ?! b% y3 m/ f8 I<P>    m_PlayerDataListLock.Leave();</P>
" \2 ], G. Q3 n9 L% h<P>    return pPlayerData;1 `0 l. K) h' W/ k! W) k5 s
}</P>7 }5 O# @" a, _2 i; p9 @) G

6 s- w: h  j1 b( v0 ]<P>5 K0 R1 _. {) g8 B  B
//-----------------------------------------------------------------------------
! T- e/ R  x4 e! G( T// Name:
( |: F- i' Z8 e7 C) ^( H' n) f$ M" c// Desc:
# I. G4 c9 C/ J4 t) n* i//-----------------------------------------------------------------------------
6 C/ I8 [# T+ W. C& Fvoid CMazeServer:estroyPlayerData( PlayerData* pPlayerData )8 G' f' m; [) j/ x
{
/ i1 b2 W: _4 m8 B3 z0 Y1 N/ B    m_PlayerDataListLock.Enter();9 z0 W8 t2 _! F4 A. m. E/ v
    LockPlayerData( pPlayerData );</P>; i) G% ~' {  J, F9 x1 w
<P>    // Remove the player from its cell- S1 O5 s2 ]# F
    RemovePlayerDataFromCell( pPlayerData );</P>
: m) I0 E* b% W& N2 d1 I; F9 \2 g<P>    // Mark as inactive
; {) M3 A$ c1 p; @" W" ~% z1 ~, }    pPlayerData-&gt;bActive = FALSE;</P>! p( u5 s+ r3 d) z5 B' m9 k/ }
<P>    // Remove player from active list
1 Y4 \2 G. J# ?; I7 z    if( pPlayerData-&gt;pPrevious )0 }/ @. |! e/ L6 b, e
        pPlayerData-&gt;pPrevious-&gt;pNext = pPlayerData-&gt;pNext;/ t: s4 V2 }: x( D: z* O! V; K
    if( pPlayerData-&gt;pNext )
6 W) n& h( ^6 v        pPlayerData-&gt;pNext-&gt;pPrevious = pPlayerData-&gt;pPrevious;</P>+ P7 m# l, D' ~5 n& v% N/ _
<P>    if( m_pFirstActivePlayerData == pPlayerData )
# A2 }5 \- `- A4 t        m_pFirstActivePlayerData = pPlayerData-&gt;pNext;</P>
5 F9 T9 S5 x4 Y<P>    // Add it to the free list
6 h* N# J. J; h  N; }* s    if( m_pFirstFreePlayerData )3 D( y( P. ?/ B# I8 @. {, T
        m_pFirstFreePlayerData-&gt;pPrevious = pPlayerData;7 r! N6 M6 [6 B$ ^9 K8 Y. c
    pPlayerData-&gt;pNext = m_pFirstFreePlayerData;
4 W) |! C% l3 U: N" Q6 D    pPlayerData-&gt;pPrevious = NULL;
! l  f! L! X- }3 k4 X+ `    m_pFirstFreePlayerData = pPlayerData;</P>* |9 t$ G2 x4 l. e! p" Z
<P>    // Update count of players* s; Q4 ^! X! z" j
    m_dwActivePlayerDataCount--;</P>1 \$ w+ ?, d. N: \- s; U6 v/ n& X1 B0 c
<P>    UnlockPlayerData( pPlayerData );8 S% n% E* F  Z- C' i% S% k
    m_PlayerDataListLock.Leave();
' Q0 e( m2 r+ C- b9 @7 @# Y) E}</P>
  e  u2 D3 ~' C* m2 @. w2 @( v! }- q- Z2 [) `& l
<P>
* x  q5 ]( G" {6 b//-----------------------------------------------------------------------------5 }3 G9 B$ z, d1 p
// Name:
: S4 W  x1 q; F6 p// Desc:
7 B2 {- n5 }' m( y//-----------------------------------------------------------------------------
$ Z- s6 x; @" F# H- N3 L! y: u# Cvoid CMazeServer::RemovePlayerDataFromCell( PlayerData* pPlayerData )
: w$ u0 z6 f  v  x# I3 _: O; N{
% |% [. l0 ?8 t9 V( Q4 @    // Lock the player
$ ]) ~2 U$ W$ A, R; o    LockPlayerData( pPlayerData );</P>& f4 c. e9 P1 |7 V
<P>    // Lock the cell the player is in
# x5 p1 c- ]4 g    ServerCell* pCell;7 @1 e, I7 f" [
    if( pPlayerData-&gt;wCellX == 0xffff )
( k  J4 L2 ?8 i1 ^* @" _. R% t    {; `, G% C& @& X1 i
        m_OffMapLock.Enter();) h" s5 T2 U0 @1 E5 `0 j: r. W3 E! V
        pCell = &amp;m_OffMapCell;! s' h$ ]; C5 k. w1 S
    }
8 Q. ^! H9 a, I9 w8 C$ R  M    else
5 {  L+ S9 m/ v# W$ U    {; g; Y4 ?5 e9 y6 J: v
        LockCell( pPlayerData-&gt;wCellX, pPlayerData-&gt;wCellY );9 v: o& Z2 W. K/ J7 m  Q6 x# `% i7 E
        pCell = &amp;m_Cells[pPlayerData-&gt;wCellY][pPlayerData-&gt;wCellX];
  }: ~+ F$ D6 D' x  R3 Q$ T; R    }</P>% {3 c& h. Q2 d; V2 e. N. v
<P>    // Remove it from the cell% k6 |: S) Z% J( ]: }* e
    PlayerData* pPt = pCell-&gt;pFirstPlayerData;: _% V2 o8 t' u1 {
    PlayerData* pPrev = NULL;
* y9 C% }. m: E( _  S$ A    while ( pPt )2 ]$ H: F- b3 g. L2 ]
    {8 b* S  T$ M' \
        if( pPt == pPlayerData )
( S+ u6 Z  K1 Q" k% y* u4 T& _        {
2 @! d; I( C' F" t2 e+ y            if( pPrev )
( ~4 ^) F- a- S$ D( |2 j$ V                pPrev-&gt;pNextInCell = pPlayerData-&gt;pNextInCell;
3 A! H( X6 I: I( t7 T6 A            else
- F7 ~& y) \7 m* C) q4 G% G                pCell-&gt;pFirstPlayerData = pPlayerData-&gt;pNextInCell;</P>( E, t( P! E5 h9 [! w
<P>            pPlayerData-&gt;pNextInCell = NULL;
1 s. S# K, D0 P8 d8 H$ C8 h+ V3 {( v            break;: y6 D& A$ {1 ^  P
        }
% B. w/ h: c% Q$ k* M        pPrev = pPt;
, a2 L  e+ }: U  {: T% d8 ~        pPt = pPt-&gt;pNextInCell;
% w- p; q! F. o" t2 p/ K/ y    }</P>6 t" b, g5 x, g  g
<P>    // Unlock the cell! J. N1 z% T  K* a# Z$ m
    if( pPlayerData-&gt;wCellX == 0xffff )2 G' i0 Z  |) O' I
        m_OffMapLock.Leave();4 m' n) ^/ o7 A% p
    else$ f& N; H; E. P# K+ p7 H, D/ P& \
        UnlockCell( pPlayerData-&gt;wCellX, pPlayerData-&gt;wCellY );</P>1 k0 |8 I" C& u' I) q# i3 f$ ~6 \
<P>    // Unlock the player7 ]  c% A* k0 B( R9 n# _3 e
    UnlockPlayerData( pPlayerData );6 Z3 g1 H# c5 N1 [/ `
}</P>' @5 E; H# a7 b

+ h' u3 w: q9 f<P>
& T+ Q% ~5 a9 ~//-----------------------------------------------------------------------------
& O+ e0 G/ A4 J. _9 ?// Name:
9 m! {3 x5 l3 d7 h// Desc:
9 E1 B5 g$ O, ?* a5 g' g( H9 n//-----------------------------------------------------------------------------( X" C: A0 r4 N/ p
void CMazeServer::UnsafeRemovePlayerDataFromCell( PlayerData* pPlayerData )
- ]: }1 r& E8 g+ ^! u" N2 Q, w{
/ K- x2 a( ~6 l7 O' q    ServerCell* pCell = GetCell( pPlayerData );
* Y" z) t3 M% {. ~& i% `    PlayerData* pPt  = pCell-&gt;pFirstPlayerData;
/ {3 `! I( A7 b; p    PlayerData* pPrev = NULL;  w; L: G: S, I# m7 X. \
    while ( pPt )8 U& |% g/ s6 x
    {
: H% Q7 h8 U6 x- |, g; ?5 z8 Q% S        if( pPt == pPlayerData ); D$ I4 }' g$ p0 w9 E2 b. v$ S
        {
! b9 L$ l; m% G, S9 s/ O. h) L9 g            if( pPrev )
) T5 @' q/ h" B: K* r3 L- n                pPrev-&gt;pNextInCell = pPlayerData-&gt;pNextInCell;0 ]  D8 D& r2 y( t/ y6 g6 [+ d; `# ]' F
            else4 @2 b4 E* N5 i. g% O6 z7 |
                pCell-&gt;pFirstPlayerData = pPlayerData-&gt;pNextInCell;% T( k4 J& V" k0 r' ]0 j: R" j4 u
            pPlayerData-&gt;pNextInCell = NULL;: K1 g9 J+ [; @
            break;" S1 `$ j* X& K1 z: S! [# F: V
        }
" ^; J9 D" Z% x% ?. f! w        pPrev = pPt;
5 \& S( m6 q0 \# S5 t        pPt = pPt-&gt;pNextInCell;
  f8 o7 X, B2 P# g7 @2 J    }
  r8 h: T$ k' I! q+ L}</P>6 a3 j8 n/ J1 e# r+ d- l5 v3 w

# @' i: }* x, Z  L6 o; A<P>
1 z$ r/ K0 y" F4 o3 y//-----------------------------------------------------------------------------/ N, o' T% ]% d: L: L" I
// Name: - r" n. Z/ l3 K  {3 E
// Desc:
( u0 F( q: p( g+ V//-----------------------------------------------------------------------------
# r0 k2 c- P3 [0 Kvoid CMazeServer::UnsafeAddPlayerDataToCell( PlayerData* pPlayerData )7 ]3 w( ]3 @1 f% {1 \
{6 S8 b4 `3 ^, e/ v& q5 g
    ServerCell* pCell   = GetCell( pPlayerData );1 U# e; ^1 t8 J: Z+ u
    pPlayerData-&gt;pNextInCell = pCell-&gt;pFirstPlayerData;* y+ t$ T4 v( N5 S) Q* g2 \7 j& p
    pCell-&gt;pFirstPlayerData = pPlayerData;
- o! C* j4 K5 q1 C+ P* W6 M+ ^}</P>& u5 L  w, ^9 f; c

6 v. J( R" m0 M% W- X, P" s* a<P>
* X2 o! M0 M  G/ U//-----------------------------------------------------------------------------5 {9 J# i, m2 U( n
// Name:
5 `$ V% k$ M1 P/ K+ g  Z+ m7 H// Desc: # ^' P3 t) a6 W- ]% o
//-----------------------------------------------------------------------------  x/ N# Z" M5 }4 z3 Z) J: h$ F
void CMazeServer::HandleClientPosPacket( DWORD dwFrom, ClientPosPacket* pClientPosPack )
8 Q2 }9 K6 B( H) ^7 W: x% P$ D5 w: S) n{6 S/ ?4 f! x4 V( [* I
    // Grab player for this client and lock it% x7 ^. W) b6 M8 N
    PlayerData* pFromPlayer = GetPlayerDataForID( dwFrom );) y, D  L) K, t! p; s& W
    if( pFromPlayer == NULL )
$ x* \$ l# k9 v% j& @; f  z( Q7 [    {8 @7 Q% ]1 X# j5 f+ x& }4 s- d0 A3 G
        if( m_dwLogLevel &gt; 1 ), w: Z, F* j' L, {/ t2 Y1 G+ T& x6 k
            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Could not find data structure for this player"), pFromPlayer-&gt;NetID );. C1 t7 K3 Z2 J" B$ l
        return;
" q8 U' X% L; T3 k3 @1 Q    }</P>
" C8 b' Z6 e0 n- W  h. {. A( ]8 z<P>    LockPlayerData( pFromPlayer );</P>$ u1 j% n0 C% h; x2 x1 x4 L
<P>    if( FALSE == pFromPlayer-&gt;bAllow )' D6 w' c/ s; A3 C  f, [* t% _0 j, h- Y
    {9 A7 i1 n( G2 B0 w
        if( m_dwLogLevel &gt; 0 )$ u) o  v9 T3 F  u
            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Got position packet from bad client.  Rejecting client"), pFromPlayer-&gt;NetID );</P>
3 m, M" r* i' D9 K" W) C( T) T5 |& G<P>        m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );1 g9 A) \0 h1 v2 r" W+ J. }
        UnlockPlayerData( pFromPlayer );
' d6 D6 [7 n5 C+ I        return;
& v. K3 O7 g  e! v5 m6 Z1 R    }</P>$ z+ z% I3 B- T
<P>    // Compute the cell the player should be in now( k/ d: v$ {9 U! @+ T" ^
    DWORD newcellx = int(pClientPosPack-&gt;fX);( b  |+ R- [: f9 [
    DWORD newcelly = int(pClientPosPack-&gt;fY);
9 |# N, I4 F4 F8 M$ g" c2 `    DWORD oldcellx = pFromPlayer-&gt;wCellX;! y8 ^% ~4 M5 ]  v
    DWORD oldcelly = pFromPlayer-&gt;wCellY;</P>/ N; L5 @2 R) V' ?
<P>    // Have we moved cell?
2 u- Z3 j( H+ i& H( c    if( newcellx != oldcellx || newcelly != oldcelly ). w- ]5 ]. C; T# T5 T% k  e
    {! o" u& W3 V& u9 e9 w
        // Yes, so lock the pair of cells in question
$ v& ^; r! ]* w) p  n( Q+ r        LockCellPair( oldcellx, oldcelly, newcellx, newcelly );</P>) T: m, E" S4 j
<P>        // Remove from old cell and add to new cell
: a0 b) k: }: G# K        UnsafeRemovePlayerDataFromCell( pFromPlayer );6 B3 K# |9 E% J* M
        pFromPlayer-&gt;wCellX = WORD(newcellx); pFromPlayer-&gt;wCellY = WORD(newcelly);# i: i& {, I! \; K; V
        UnsafeAddPlayerDataToCell( pFromPlayer );</P>. \- P% h6 L% J
<P>        // Unlock cells  Y. Z/ A2 f/ O/ X7 d
        UnlockCellPair( oldcellx, oldcelly, newcellx, newcelly );
3 @: I! k8 A- P: L3 O& w# k* `- k7 g    }</P>
( V4 Y8 e" ]9 l: H. r<P>    // Update player position& W# ~+ U, F- e. s9 L
    pFromPlayer-&gt;fPosX      = pClientPosPack-&gt;fX;
/ e: Z: A! B  v, X5 I    pFromPlayer-&gt;fPosY      = pClientPosPack-&gt;fY;
0 \$ E; d) {9 O    pFromPlayer-&gt;aCameraYaw = pClientPosPack-&gt;aCameraYaw;</P>
: E, M2 E+ O/ A' U8 K<P>    // Allocate space to build the reply packet, and fill in header 6 d2 q0 ?* S: \7 `& L7 ]8 n
    DWORD dwAllocSize;
3 a3 M4 @- c! }    ServerAckPacket* pSvrAckPack = NULL;</P>" v: {* F* i, ]" C- o
<P>    // Begin by allocating a buffer sized according to
& E  B( A1 t. A# [( S( u/ N3 P    // the current number of nearby players + 4.  This will give
+ Z% _" {3 A3 `8 ^    // a little room for more players to come 'near' without resize8 J9 H6 L, l, P/ h/ \
    // the buffer.
9 C( [* m" S; B    DWORD dwMaxPlayerStatePackets = pFromPlayer-&gt;dwNumNearbyPlayers + 4;</P>
& d1 X( W$ x7 E2 z9 t2 @: g<P>    dwAllocSize = sizeof(ServerAckPacket) + dwMaxPlayerStatePackets*sizeof(PlayerStatePacket);3 W( V6 `' K, j3 n& t5 Z
    pSvrAckPack = (ServerAckPacket*) realloc( pSvrAckPack, dwAllocSize );
7 c: {, d( l$ L* k( K    if( NULL == pSvrAckPack )
( l4 z+ p! D0 a* a* r) ^    {, {: c  B; L# o4 z+ o; E2 X
        // Out of mem.  Cleanup and return2 D1 _3 \0 `1 [9 I5 D& y+ v9 Q3 ?
        UnlockPlayerData( pFromPlayer );
5 y5 t+ h8 @" Z6 L0 F$ x        return;       9 ?$ p& M7 b/ |- x! D3 k6 [2 ]
    }
8 W$ b" g* v' P8 O    ZeroMemory( pSvrAckPack, dwAllocSize );</P>% ^9 G  |* e& t4 e( G) G% T1 K, f
<P>    *pSvrAckPack = ServerAckPacket(m_dwPlayerCount);! G3 l' ~$ h# Q7 t! e$ i
    pSvrAckPack-&gt;wPlayerStatePacketCount = 0;5 O+ H: z- }6 Z( F& K; t! _! D
    PlayerStatePacket* pChunk = (PlayerStatePacket*)(pSvrAckPack+1);</P>
: a9 r" z4 V5 Q8 N* |<P>    // Compute range of cells we're going to scan for players to send
, i! \! i. I# f% {    DWORD minx = (newcellx &gt; 7) ? (newcellx - 7) : 0;' r8 t6 n8 S. S! L# z1 |* s
    DWORD miny = (newcelly &gt; 7) ? (newcelly - 7) : 0;0 W# m5 b# x- B7 _* v' }0 L$ p+ l
    DWORD maxx = (newcellx+7 &gt;= m_dwWidth) ? m_dwWidth-1 : newcellx+7;. X1 b8 k5 g1 S
    DWORD maxy = (newcelly+7 &gt;= m_dwHeight) ? m_dwHeight-1 : newcelly+7;</P>
8 _4 S, n3 }  ^9 t4 `; ]; G2 n& J<P>    // Lock that range of cells
* y& D* r$ v6 O- L    LockRange( minx, miny, maxx, maxy );</P>
) c: m" K; u5 t" t) n<P>    // Scan through the cells, tagging player data onto the end of' T; J+ J- `6 e+ }  r( ?
    // our pSvrAckPacket until we run out of room
& O, c- A/ A. i" \  V: m    for( DWORD y = miny; y &lt;= maxy; y++ )
( K2 A7 k, ]% @: T    {
* s8 b  y' K7 @& b        for( DWORD x = minx; x &lt;= maxx; x++ )
) L! e2 L! p, D3 Q7 D        {5 f, S1 e' W& d6 J, |' f) g
            PlayerData* pCurPlayerData = m_Cells[y][x].pFirstPlayerData;
( W* Z2 l9 t. E5 B' w: [            while ( pCurPlayerData )
, x) W- Y' ]: H( L$ d( v" C            {/ \! I& K0 E' A8 w% m( X, Q
                if( pCurPlayerData != pFromPlayer )
9 D4 Q! ?: _( q7 v                {& N2 \/ m- M4 U# ~0 }$ E- I
                    if( pSvrAckPack-&gt;wPlayerStatePacketCount &gt;= dwMaxPlayerStatePackets )
' v1 K! z4 m! ]% h1 W# R                    {
0 i6 U7 i; t3 \- l/ S+ w; Z& m                        // Make sure pChunk is where we think it is
: Z4 Z& t! h, L, E/ Y# L6 V2 p                        assert( (BYTE*) pChunk == (BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket)) );</P>7 n+ m) ~6 _* c7 B  C6 c  x
<P>                        // There are more than just 4 new nearby players, so resize the
. t% ~1 x! ?( l/ |                        // buffer pSvrAckPack to allow 16 more PlayerStatePacket's.
. C& ?* y4 V1 L) U                        dwMaxPlayerStatePackets += 16;
! N/ K# S/ F' P7 _                        dwAllocSize = sizeof(ServerAckPacket) + dwMaxPlayerStatePackets*sizeof(PlayerStatePacket);; `$ e. {' E( j9 E8 \
                        ServerAckPacket* pNewSvrAckPack = NULL;* u0 f; @( b+ r: `0 U8 C
                        pNewSvrAckPack = (ServerAckPacket*) realloc( pSvrAckPack, dwAllocSize );4 S$ g* J2 Y$ k' k
                        if( NULL == pNewSvrAckPack )- c# U/ y4 T! C) H$ q
                        {% @1 Y' E. [) W7 F  x% e
                            // Out of mem.  Cleanup and return
4 o1 P. a3 `5 z1 g2 |0 i9 ~                            free( pSvrAckPack );
: J" N. v3 n* E! }) a                            UnlockRange( minx, miny, maxx, maxy );
; X0 K4 ?/ k- G2 m4 d; g; Z% |5 v( B                            UnlockPlayerData( pFromPlayer );* x- D* z6 k% `2 V' h
                            return;      
9 q" V( K, B0 d1 `. w                        }</P>4 z7 n. h; S% a, n; z& ~
<P>                        pSvrAckPack = pNewSvrAckPack;* e- f4 V/ M2 L6 i
                        pChunk = (PlayerStatePacket*) ((BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket) ) );</P>+ j, [1 d+ Z, ]: l( P: L3 }
<P>                        // Make sure pChunk is still where its supposed to be
# {2 B' e2 E: b% i* A                        assert( (BYTE*) pChunk == (BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket)) );, H7 ?0 E9 E. o4 W; [- t+ w
                    }</P>
4 n, S, C) T+ v6 B1 w0 z  ^<P>                    pChunk-&gt;dwID       = pCurPlayerData-&gt;dwID;/ a. h/ d5 ?" P' V8 d1 g
                    pChunk-&gt;fX         = pCurPlayerData-&gt;fPosX;
/ z% t+ E( F) }$ O# }- s- L                    pChunk-&gt;fY         = pCurPlayerData-&gt;fPosY;( y1 [* O  ]5 V
                    pChunk-&gt;aCameraYaw = pCurPlayerData-&gt;aCameraYaw;4 p/ t9 m; t: E" F8 U% L
                    pChunk++;
  B) m' H- \- Q9 t7 R8 \8 D& d( F                    pSvrAckPack-&gt;wPlayerStatePacketCount++;: d- e5 h  T" |2 N, B1 C  z
                }
6 P. i& f7 J4 \- a4 ~                pCurPlayerData = pCurPlayerData-&gt;pNextInCell;* E8 q4 T. b, s7 s# _
            }' w( j6 ^& a5 o* U; Z9 ]
        }
- z) B" P9 e6 V1 C* j# X$ A+ f* w2 O    }</P>
1 C; r: |6 p/ Y+ G0 H: w" s9 u<P>    // Update the dwNumNearbyPlayers for this player
4 N5 b2 y: \, X/ v' b  d    pFromPlayer-&gt;dwNumNearbyPlayers = pSvrAckPack-&gt;wPlayerStatePacketCount;</P>
8 N4 c1 A9 D9 H( P<P>    // Unlock range of cells( O! L5 J( E8 q* i; C& |
    UnlockRange( minx, miny, maxx, maxy );</P>7 I& _1 n, s, s; N' V) O( j
<P>    if( m_dwLogLevel &gt; 2 )
9 \$ N) G5 C) i8 A# ]    {$ L' B; |, V3 Z0 c- S: y
        ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Position is (%0.2f,%0.2f)"), pFromPlayer-&gt;NetID, pFromPlayer-&gt;fPosX, pFromPlayer-&gt;fPosY );
' G! H4 W; |) m# f2 H    }
" C; z( u3 {1 L2 O# v( l. i& r' H    else if( m_dwLogLevel == 2 )
: x: T4 t  |" H& r    {* J2 O2 u; A& X9 x
        FLOAT fTime = DXUtil_Timer( TIMER_GETAPPTIME );4 k7 ^# O% g$ L: x' ~1 a. r6 T
        if( fTime - pFromPlayer-&gt;fLastDisplayTime &gt; 60.0f )' L5 R4 `/ O1 y% `- o6 d
        {# i* J$ I5 O; g
            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Position is (%0.2f,%0.2f)"), pFromPlayer-&gt;NetID, pFromPlayer-&gt;fPosX, pFromPlayer-&gt;fPosY );
9 ]* N/ J# h6 O) {, Y6 [  A/ }            pFromPlayer-&gt;fLastDisplayTime = fTime;
2 {$ }$ g- D3 T        }
+ @& f+ [7 x: f' |    }</P>
4 l& I; h" O& r$ }; r<P>    // Unlock the playerdata4 ~; V( m& C* V2 j
    UnlockPlayerData( pFromPlayer );</P>
" D& i( E  k" {0 I. Z<P>    // Send acknowledgement back to client, including list of nearby players ! P( j5 ^0 ~) R6 b% Q
    DWORD acksize = sizeof(ServerAckPacket) + (pSvrAckPack-&gt;wPlayerStatePacketCount * sizeof(PlayerStatePacket));
2 L% p+ U9 o+ u0 u4 y* i3 ] # d# _0 D6 M6 d
    // Pack the buffer with dummy data.5 P6 r" @/ l; m; q# u
    if(m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex] &gt; 0)% e+ c- g, K, S; w
    {. B8 G* T1 P# I: A+ [8 v
        DWORD   dwBufferSize = acksize + m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex];% s6 M2 }# L3 x" r# b9 }: E
        VOID*   pTempBuffer = 0;</P>
" t# `, h3 p* D5 b# l8 m<P>        pTempBuffer = malloc(dwBufferSize);
+ b' @* ~& V% M+ Z' ]        if( NULL == pTempBuffer )! Z: u; @$ w$ ?# q/ Y
        {
8 }" ]' r! v+ ~& n! w+ H1 M5 [            //Out of memory/ F& N% d' T  Y# e1 S8 [" @
            DXTRACE_ERR_NOMSGBOX( TEXT("System out of Memory!"), E_OUTOFMEMORY );( Y! O: n2 q3 ?
            free( pSvrAckPack );
6 v+ L' E# I" d) h9 f( a            return;9 U/ c6 u8 T; q
        }</P>
5 a. {4 U8 n: e<P>        FillMemory(pTempBuffer, dwBufferSize, 'Z');4 W8 _4 F6 o4 M* R9 R
        memcpy(pTempBuffer, pSvrAckPack, acksize);</P>2 i1 j# f  _& o6 K0 t; ?1 |
<P>        SendPacket( dwFrom, pTempBuffer, dwBufferSize, FALSE, m_dwServerTimeout );% T, t# ^6 W0 B- w7 y
   
" c* N* Z& c+ }: \! p% d, o        free(pTempBuffer);9 @6 g$ A( I" N
    }   / k; w5 m7 i. ^: |' M' W" h( `& ?
    else
& G4 A0 L9 K5 m  t' Y, O    {
" C- Q/ m* h" N* X( z        SendPacket( dwFrom, pSvrAckPack, acksize, FALSE, m_dwServerTimeout );
/ Y  Y+ J' W) ]% x5 ?$ z7 A$ I    }</P>' s& K5 _. b6 S. W
<P>    free( pSvrAckPack );</P>
+ Y8 R5 t' F7 E! p. K2 d1 ]<P>}</P>) j3 Z& s; m6 ?8 R

' J7 F' J, x7 u0 V<P>
" O! l" H6 C7 N: t//-----------------------------------------------------------------------------
& N) @8 O% I! X- d6 U+ }$ `7 ^( g// Name:
$ `+ f2 n! m% S4 A& h! V+ o// Desc:
; ~& ], a+ L! r- x* M//-----------------------------------------------------------------------------: o# [, ~# b4 \& k$ h
void CMazeServer::HandleClientVersionPacket( DWORD dwFrom, ClientVersionPacket* pClientVersionPack )
" t9 S' j/ o' V! d3 V/ `0 h{
  \* `! q# p  s9 Z( \    // Grab playerdata for this client and lock it# ^5 N# e6 N5 T/ c) h% q8 B
    PlayerData* pPlayerData = GetPlayerDataForID( dwFrom );5 h/ d" W5 x9 p! g$ P# v
    if( pPlayerData == NULL )0 r) b& _. y. B! i* ?
        return;
! E3 B( C; y) X: B- i    LockPlayerData( pPlayerData );</P>
' o2 R4 E+ x) E6 Y/ a5 F/ V) j# B<P>    // Record the version number
) H; Z  q1 M. G5 ~" {" s" Z) p    pPlayerData-&gt;dwVersion = pClientVersionPack-&gt;dwVersion;</P>
7 R5 q% @9 M* k% \8 [<P>    if( m_bLocalLoopback )
' m& ]2 n7 Z( O2 q; T: e        pPlayerData-&gt;bAllow = TRUE;: z) n  m( j1 h4 ^+ C# h: r7 t" @
    else8 k% O) S  L# u0 d% x. g
        pPlayerData-&gt;bAllow = IsClientVersionSupported( pClientVersionPack-&gt;dwVersion );</P>6 T8 Y9 x- z# {/ ?5 K& o1 q
<P>    if( m_dwLogLevel &gt; 0 )+ Z- B* I( [9 S+ e6 m6 V
        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>
+ M6 K5 g/ z! R<P>    if( FALSE == pPlayerData-&gt;bAllow )/ v+ d$ t0 g0 }
    {- g: Z( m# V) W: _# \. t
        if( m_dwLogLevel &gt; 0 )
' ~8 o/ I& o+ [8 J" k4 A2 x# z            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Rejecting client"), pPlayerData-&gt;NetID );</P>
( J% }* r5 T5 E<P>        m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );
2 x. |6 [+ q' d! D# S& j: l- `        UnlockPlayerData( pPlayerData );1 N7 q9 @& V+ N. N
        return;
8 ?0 d2 q+ q, n% j4 F) K    }</P># ~) H- T+ h% f' Y
<P>    // Unlock the playerdata1 W# I4 P0 q/ ~$ U
    UnlockPlayerData( pPlayerData );</P>7 |! h4 Z- M/ g/ f5 q! S# V( L
<P>    // Send acknowledgement to client that the client was either accepted or rejected, h9 S. j) q! u: t! i9 G+ q  ^
    ServerAckVersionPacket packet( pPlayerData-&gt;bAllow, dwFrom );, P1 q8 u, J* r1 ~# g* o# L) u
    SendPacket( dwFrom, &amp;packet, sizeof(packet), TRUE, 0 );$ x0 B# O- x0 O' t
}</P>
( t/ V8 E: |5 ?; s* A$ ^  b! Z2 ]: L$ o2 O* l6 Y1 \0 I6 k
<P>
, R1 K, V5 ?! A" o//-----------------------------------------------------------------------------
) w& D) S6 `2 M1 k' Q) ?, @// Name:
, k  d" _  R5 M- j6 n; {5 q// Desc: . c* ?$ B7 Y/ \, ^
//-----------------------------------------------------------------------------
4 f( G( {0 N5 P' U3 iBOOL CMazeServer::IsClientVersionSupported( DWORD dwClientVersion )
4 B# f5 V9 P- r# F  E! w/ C{5 ?, \* f; `% m% f
    switch( dwClientVersion )! P/ j- V. I0 u1 Y5 N
    {
# _. S7 J9 q' e* t% {; t  R7 x, z        case 107: // only v107 is supported7 w! j3 W5 |: v0 s( Q9 H
            return TRUE;
: q! K0 C# U& x, F) }# T1 x        default:3 t' J% [8 U; s% s
            return FALSE;
3 b0 w- s( _1 t6 z    }
5 ^/ P% t; J) h0 Z}</P>7 Y& H. O6 x$ V/ m0 o9 ?

+ [9 P  ~: u) [7 k- x# `$ B<P>% Y7 y$ g: P" I
//-----------------------------------------------------------------------------
2 p& b" R" {6 |" k0 I, i// Name: ( C: u% k$ j2 a  ~
// Desc:
: ]$ l4 A$ |3 A" T; ?* E  O; f/ {//-----------------------------------------------------------------------------
0 U( w' I: o3 Kvoid CMazeServer::HandleUnknownPacket( DWORD dwFrom, ClientPacket* pClientPack, DWORD size )& \8 V9 u$ C9 s6 y# b
{
, g) }. u' |/ L$ h9 w0 Z    if( m_dwLogLevel &gt; 1 )2 w! @9 v% ?6 \; ?, p+ ?) f
        ConsolePrintf( SLINE_LOG, TEXT("ERROR! Unknown %d byte packet from player %0.8x"), size, dwFrom );</P>
9 t; X. u; e5 x+ S* M<P>    m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );1 ^- |/ P" ?+ f" H! y
}</P>
5 R5 H& g( h) b0 S
4 y' C, c- k$ P<P>* \& O5 g& r0 G- C! W$ q
//-----------------------------------------------------------------------------* R/ v+ ^" D. @6 h- F
// Name: , I5 [4 j( P2 v1 Z! |0 V+ Z4 f
// Desc:
7 e; R. C4 h! \% R7 t/ v7 n, T//-----------------------------------------------------------------------------6 L: \! W; B! V3 c! q
DWORD   CMazeServer::IDHash( DWORD id )8 Z, F+ d' x+ m/ y
{5 g4 P* c4 ~! e. y" o. U; w
    DWORD   hash = ((id) + (id&gt;&gt;8) + (id&gt;&gt;16) + (id&gt;&gt;24)) &amp; (NUM_ID_HASH_BUCKETS-1);
- s  B2 X+ X2 v# E- f/ G6 T    return hash;; x8 G5 N( d6 w. P# [3 L
}</P>
1 ~- Y5 W8 H+ \; w( @3 w$ b/ E. n9 ]6 z
<P>( H- t) T$ L: J! A3 t, m
//-----------------------------------------------------------------------------
6 P+ Y# X+ h* [* L// Name: 2 C- X, G6 ^' J8 v8 D( f
// Desc:
& i, q9 V* O5 t% q9 E//-----------------------------------------------------------------------------5 n& L0 a; R: v* {
void CMazeServer::RemovePlayerDataID( PlayerData* pPlayerData )
& K' m5 A- ]& f1 |. u{
3 f, x& G0 A9 @4 @    // Hash the ID to a bucket number
6 o  W; R0 ]! j" {4 L, X" q9 b" q    DWORD   bucket = IDHash( pPlayerData-&gt;NetID );</P>9 J, z; U2 i- w8 S1 z
<P>    // Lock that hash bucket( c+ l- x+ n8 u3 h% l
    const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;+ H8 f) V+ y) E( b
    m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>
  {7 j& @# }4 b" {1 ?0 Q3 V% \, M2 l<P>    // Loop though players in bucket until we find the right one
  G4 u2 L- e) `% U    PlayerData* pPt = m_pstIDHashBucket[bucket];
; O, p7 {- w/ I" N$ ?7 x. M    PlayerData* pPrev = NULL;2 x) E) }4 _" a9 j2 p7 o( j3 r5 i
    while( pPt )% n6 M1 \9 t4 `' d( h
    {
3 b" i% q& g3 N9 ^6 e        if( pPt == pPlayerData )
! i7 q5 h0 x6 F% J6 [4 t6 X; P            break;" j4 z) `* d0 g  X; ~$ S5 O. H+ c8 C
        pPrev = pPt;) |7 a7 {+ }- |4 |6 C8 t
        pPt = pPt-&gt;pNextInIDHashBucket;. d5 A) L4 ?. P/ h
    }</P>$ N; l. \9 A8 s
<P>    if( pPt )
' `# `# R% y& d. g7 X' r    {
5 H' c' [( U: f3 ~4 X, a4 a; |3 N/ F        if( pPrev )+ ^# @9 D5 ]9 t* ^
            pPrev-&gt;pNextInIDHashBucket = pPt-&gt;pNextInIDHashBucket;" l4 \6 s" |+ m0 I# o9 q
        else
  l# [- p1 N* [5 s. h$ t            m_pstIDHashBucket[bucket] = pPt-&gt;pNextInIDHashBucket;) K+ W0 t. `3 @) W, r) ?
        pPt-&gt;pNextInIDHashBucket = NULL;& g' N( Y! v- i+ }# ]  W( v
    }</P>/ Q6 b! K$ u8 I, f8 U0 x
<P>    // Unlock the hash bucket" j% i; a" n" }, ?" d
    m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();1 o% _6 g3 s- X5 c* j- {  o
}</P>6 ^5 b5 Z; P7 ]- S6 a
3 Q, p  Q+ a# c  B1 _& b, A& L
<P>
3 R: e; e, c6 N4 L3 E8 d% J) Y9 \! S//-----------------------------------------------------------------------------! D! j  ?* p$ }- J; U/ U) g( l
// Name: % W8 w& c0 h1 T8 G; C: y5 d
// Desc: + t/ B& E/ r) W. K& i/ l
//-----------------------------------------------------------------------------0 g, {2 I, s, z0 a
void CMazeServer::SetPlayerDataForID( DWORD id, PlayerData* pPlayerData )5 _/ I6 o# L6 ]  x0 b
{
+ G& r2 s4 S7 H+ U: i    // Make sure this player isn't added twice to the m_pstIDHashBucket[]/ |: V! A( K) m9 ~
    // otherwise there will be a circular reference& z& M  [' }7 Y0 E8 R3 A
    PlayerData* pSearch = GetPlayerDataForID( id );# J( K9 E+ @; p# o# ~1 A, G
    if( pSearch != NULL )) a: _, S/ u( h+ {0 D
        return;</P>
* M" Q% _) O: `4 V; m<P>    // Hash the ID to a bucket number
5 r4 B% i; k, _    DWORD   bucket = IDHash( id );</P>+ \, U$ _% l* ^
<P>    // Lock that hash bucket
) {1 A) Z% Q# o# G3 c# e    const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;8 R) Q/ Z0 U1 q, T
    m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>
5 M2 u7 F  X- G' P( o<P>    // Add player onto hash bucket chain& ]5 I# ?9 e  A6 I: n
    pPlayerData-&gt;pNextInIDHashBucket = m_pstIDHashBucket[bucket];
: q5 h# N' |& w) Y8 \    m_pstIDHashBucket[bucket] = pPlayerData;</P>
$ A/ l7 H: O+ V' D4 ^1 j<P>    // Store net id in player6 }# d4 }6 f" Q& `
    pPlayerData-&gt;NetID = id;</P>$ }# `* G% V$ _4 R$ Y& a
<P>    // Unlock the hash bucket
& _/ H2 D+ b) ]    m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();5 |/ e) x+ J$ L! X3 B5 B
}</P>
7 w4 w" y8 O/ x' j, Z5 g- _
. k+ }0 W8 m  E! p<P>0 P0 D% _# ]  [, b7 P! l/ R
//-----------------------------------------------------------------------------
. ]3 Q, G$ @) g( h. q  g0 G- q// Name: 7 W' N6 A' H' O( f7 r  o! J" r5 t
// Desc: 7 Y/ B) X/ K' @& Q
//-----------------------------------------------------------------------------* }2 S5 Q4 }7 ^- d
PlayerData* CMazeServer::GetPlayerDataForID( DWORD id )9 ?0 G3 U0 E7 v. q" K4 _" I
{
7 Q7 L, c" v+ j# R' g% R8 J7 p! ?8 P    // Hash the ID to a bucket number6 W! t- v& \) I+ d& \& T) m0 f. e
    DWORD   bucket = IDHash( id );</P>
# [; N( x0 V+ K4 |" q0 [<P>    // Lock that hash bucket
6 p  a% @5 Z  y  O6 U/ u5 ^    const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;
' E1 a- A" z7 w- f    m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>* w' F. v# c8 T* V* G7 k
<P>    // Loop though players in bucket until we find the right one: A6 E  ^% g; V, d, G4 l
    PlayerData* pPlayerData = m_pstIDHashBucket[bucket];9 _( F% N3 N: u4 s. Y
    while ( pPlayerData ), b  m7 x5 }: I2 x/ p' V
    {
; j4 z1 z6 t$ F& h. u/ e        if( pPlayerData-&gt;NetID == id )& n+ j$ h6 g2 j! B& @
            break;
6 ?% Z. j9 }8 G5 f) V        pPlayerData = pPlayerData-&gt;pNextInIDHashBucket;  b0 T, x8 Z9 `! b7 S3 g2 e4 f
    }</P>  v3 \. N0 y# ^1 t8 H; i
<P>    // Unlock the hash bucket: A! o+ W5 M, w
    m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();</P>9 ~& O- y5 J3 k9 d# G8 q( Q
<P>    // Return the player we found (will be NULL if we couldn't find it)
7 V6 [/ I% L% @- x    return pPlayerData;1 _. {( e$ a% x1 z
}</P>
4 p& V  \7 J% M: S$ T+ W
6 C. n- ~/ f2 U<P>/ t/ v  ~6 ~: N5 b# f0 c
//-----------------------------------------------------------------------------. R; K) v- k/ D) O. N* p, Y) ~
// Name: 1 \* b" g% c& L4 E
// Desc: calls DisplayConnectionInfo for each connection in a round-robin manner1 o) B% n  i; Z! g! j2 s# R
//-----------------------------------------------------------------------------
0 ?/ d# |2 j9 _- Hvoid CMazeServer:isplayNextConnectionInfo()( n5 i. D3 L7 p; O, @
{9 r3 T8 ^, o0 L& F" g
    if( m_pNet )
+ X- a0 t' e! ]0 V    {
$ P  X# ]" a9 \" i$ t( ?# p1 f        // Find the player that was displayed the longest time ago, and display it.) Q" X8 }# A4 c
        FLOAT fCurTime = DXUtil_Timer( TIMER_GETAPPTIME );
7 X+ `( s5 X4 m1 Q9 F4 e* x) |2 ^        PlayerData* pOldestPlayerData = NULL;
5 V- A# l. q: Z! a/ i& F2 \        FLOAT fOldestTime = 0.0f;</P># E  M  O& Z0 k6 O4 ^
<P>        m_PlayerDataListLock.Enter();</P>
/ m/ n8 ?/ B( J8 S% W<P>        PlayerData* pPlayerData = m_pFirstActivePlayerData;
  s2 L8 Q) |" C* R        while ( pPlayerData ), C# ]9 `" T: |, ?
        {
1 }1 v  u# q; B- E( C            if( fCurTime - pPlayerData-&gt;fLastCITime &gt; fOldestTime )
' G; ^3 Q! H- k$ g0 k/ O" `5 j            {
: |: O* x/ q& A                fOldestTime  = fCurTime - pPlayerData-&gt;fLastCITime;
  r6 a5 e" G. n7 C                pOldestPlayerData = pPlayerData;  v' i- a5 L& X, ?
            }</P>! u8 s9 E; l6 T4 a% P
<P>            pPlayerData = pPlayerData-&gt;pNext;
8 ~; S9 A1 _) K; M; K1 e0 J4 F# ]6 R        }</P>
& r5 O; v: Y0 X' t# E9 u1 j<P>        // Display the player with the oldest CI field, and update its CI field.
- [1 t0 z# i; D2 Q! U        if( pOldestPlayerData )
* K) G6 Q' p6 g5 p5 n# l        {
. y( [7 k0 I  O2 b: X& o            ConsolePrintf( SLINE_LOG, TEXT("Displaying connection info for next player") );: z- s2 |" I1 J- l1 C' D
            DisplayConnectionInfo( pOldestPlayerData-&gt;NetID );
6 b6 D' I6 K' J7 d            pOldestPlayerData-&gt;fLastCITime = fCurTime;
! a* E8 j- ?9 Y3 z; d        }( W; Y4 S- N! e7 ^5 p' d
        else
7 y# ]& O$ H) S$ E6 y        {8 Y  F2 `$ p9 X" \
            ConsolePrintf( SLINE_LOG, TEXT("No players found") );
8 d( c5 C8 |0 M* B0 K  S        }</P>2 f/ N0 q+ {2 K0 z9 @9 [; W$ Q
<P>        m_PlayerDataListLock.Leave();
/ {, ?, H/ q1 E7 \    }
5 W% ]! r3 G) y}</P>- X8 o+ y4 b0 _% _$ ^& Y7 V3 [8 d
* ]# {% \' ^( B# M: w/ c
<P>
' A! \  o3 Y( A" K* D3 h+ h  O" I//-----------------------------------------------------------------------------: x+ s0 `, |2 ?2 B; T3 b! g
// Name: # y2 j3 a2 T( S3 g; \
// Desc: 3 l  I2 p' @0 \* m0 N" z6 B) D
//-----------------------------------------------------------------------------; }- W) J: ^# U) D5 B! a3 D
void CMazeServer:rintStats()
) z; g- F% `( z7 p( x: ^8 B6 S{: ?5 i# H3 J+ S4 s9 Q; k/ |
    ConsolePrintf( SLINE_LOG, TEXT("Thread count: Active=%d Avg=%.2f Max=%d"),
' L% S9 m4 e- ^, g# q, s                                    m_wActiveThreadCount, m_fAvgThreadCount, m_wMaxThreadCount );- n% M( O4 U8 _# x
    ConsolePrintf( SLINE_LOG, TEXT("Thread Time: Avg=%.4f Max=%.4f(s)"),
: ?0 g/ Q/ Z8 h, u* C" F! ^" o                                    m_fAvgThreadTime, m_fMaxThreadTime );' i- {4 l( g' P2 \8 q/ m
    ConsolePrintf( SLINE_LOG, TEXT("Players online (not including server player): %d"), m_dwPlayerCount );
* n* b( Y' P, ]( Z. q  y    ConsolePrintf( SLINE_LOG, TEXT("Peak player count: %d"), m_dwPeakPlayerCount );" J* o9 w( s- k( l+ p, j
}</P>2 p* I& k2 V( b2 V. G0 @/ I

4 Q# g; T  L1 t3 O. s' [<P>. Z! S5 I2 \5 |
//-----------------------------------------------------------------------------
. a, C0 _: m, M) {( q// Name:
& j2 d/ R! a( n  W8 q/ H; n// Desc: 1 h( W; m0 q0 [3 n7 ?5 {3 E3 ~
//-----------------------------------------------------------------------------
7 U- N6 ~" z" K( @void CMazeServer:isplayConnectionInfo( DWORD dwID )5 v4 o7 p2 ~# u% q8 ^+ F
{9 h. C& g8 H' j1 I4 K. N7 P- w
    TCHAR strInfo[5000];/ s# u( M# M  q! t
    TCHAR* strEndOfLine;" w) U" B- G7 m7 y. s
    TCHAR* strStartOfLine;</P>
8 y, [3 e' [( H9 N. M! [* t<P>    // Query the IOutboudNet for info about the connection to this user
: G* r5 w% C8 k& Q    m_pNet-&gt;GetConnectionInfo( dwID, strInfo );</P>
$ i: M, Q& z% V0 h/ A7 _<P>    ConsolePrintf( SLINE_LOG, TEXT("Displaying connection info for %0.8x"), dwID );
; E) k7 Z8 l# j: }) \; z7 E$ K$ [/ g    ConsolePrintf( SLINE_LOG, TEXT("(Key: G=Guaranteed NG=Non-Guaranteed B=Bytes P=Packets)") );</P>
4 I; e4 k5 t6 U/ g  p/ y: |3 o<P>    // Display each line seperately$ Y) A, ?4 U; _: \2 j
    strStartOfLine = strInfo;% W& X5 s. D, ^9 G3 E( J) B
    while( TRUE )$ [# w7 F9 [0 j/ T6 Z
    {' U7 p( T/ m1 V8 Q- c
        strEndOfLine = _tcschr( strStartOfLine, '\n' );
4 H9 r- K' w/ v. O; h* o        if( strEndOfLine == NULL )
- H0 ]# h' V. j            break;</P>' Q# a  ]$ q2 L8 h
<P>        *strEndOfLine = 0;
- J* D4 ~% X* W! _3 C        ConsolePrintf( SLINE_LOG, strStartOfLine );8 S) |+ o/ j+ X* d. {
        strStartOfLine = strEndOfLine + 1;. v$ R- `. E  g1 o
    }! G$ D/ M7 P; O- ^: S+ h
}</P>
+ e6 J. v- q1 Z# Y5 |
4 c( I, c* I0 R! o$ U' G- \: c6 Y<P>
! H) G& a0 \( A- Z# Q2 K1 W7 D//-----------------------------------------------------------------------------8 O; S  a* Y: Q( f! ^
// Name:
" x; {& H# z) a* k1 n1 O// Desc:
. \' P4 _/ ~; y//-----------------------------------------------------------------------------$ ^8 w9 G  O) a. _# S
HRESULT CMazeServer::SendPacket( DWORD to, void* pData, 8 G. R, b, }) M
                                 DWORD size, BOOL reliable, DWORD dwTimeout )
1 N2 U3 N! y0 s8 g: ~' ?( h{& S7 B! ?; l# m
    // Chance of forcing any packet to be delivered reliably
, a0 B9 y; f- L- o, e/ V  I    if( m_Rand.Get( 100 ) &lt; m_dwServerReliableRate )% A, [, Q/ B+ w& n
        reliable = TRUE;</P>
1 l) ^  X( S# d& X<P>    return m_pNet-&gt;SendPacket( to, pData, size, reliable, dwTimeout );0 S% g+ H( Q! k
}</P>
9 t0 F6 Z: Q9 g- P# i7 X6 k
4 I( S! h; ?# O% e  n7 {<P>
1 P# D; `9 d$ }; c) [& O//-----------------------------------------------------------------------------
/ g  D/ z4 u$ p. y* W, N// Name: ( _! e- r' k& Q" C2 W
// Desc:
3 b- ?, Q0 x: Q  D+ u//-----------------------------------------------------------------------------" J, P$ Q+ R4 ]4 L
void CMazeServer::SendConfigPacketToAll( ServerConfigPacket* pPacket )
8 N5 ?) S% z8 C% {) R1 Q' E! ~{, T4 C& {/ V) g1 C) t4 _( p$ {
    // If we're up and running, then send this new information to all clients% X' h: w8 {" S2 @9 Q4 m
    if( m_pNet )8 D, p* x0 k: s4 p/ ]
    {
+ J' a5 X# A% e        //Use the AllPlayers ID
* I! x$ U3 h& x2 H) j" o5 q        SendPacket( DPNID_ALL_PLAYERS_GROUP, pPacket, sizeof(ServerConfigPacket), TRUE, 0 );
. e$ C& f, M% g0 W    }1 n  ^- s7 m, K, ^9 @! |4 j
}</P>  C4 T8 G& r3 y9 }% B! L2 x1 G

- P2 m1 m5 u" G; x! Z2 S% O: W<P>
3 e$ k: f, N# ^, h; O7 Q: \//-----------------------------------------------------------------------------( c9 }. }1 S: t5 _
// Name: . X7 h9 a( }) R2 `! a
// Desc:   ]: J, J  @) e' |
//-----------------------------------------------------------------------------, Y8 l, i$ h8 X( R4 [
void CMazeServer::SetClientReliableRate( DWORD percent )
% `+ e& T. {# ^- `2 Y{. r, h5 e- j' T. |, m
    // Update client config, and build packet containing that data# z7 k8 W8 L* V1 g2 F5 U
    m_ClientNetConfigLock.Enter();
* `) b' p: b5 `    m_ClientNetConfig.ubReliableRate = BYTE(percent);' p* g$ M. f. w: V
    ServerConfigPacket packet( m_ClientNetConfig );
' Z1 ?2 n% ]3 \0 ]2 [1 _    m_ClientNetConfigLock.Leave();</P>5 b  |0 Z  B0 Q! I; D& K
<P>    SendConfigPacketToAll( &amp;packet );$ `* U5 _. A) S+ w3 a
}</P>
4 l9 Z+ C+ L7 j
3 n) M4 \, N: ~* w/ X<P>
% s, H4 y- A: h) X. V//-----------------------------------------------------------------------------
- H$ g' i+ B6 ]& E/ J+ f4 d// Name:
. e! R. C+ M6 @# h  S) d9 L// Desc: - y3 k# ~7 V1 ^( g* d8 E4 q
//-----------------------------------------------------------------------------/ }" U+ k' w# T
void CMazeServer::SetClientUpdateRate( DWORD rate )
$ j" Y  y! n: l6 n) P  M{
( z! n/ W; H. S  l    // Update client config, and build packet containing that data
( D) ]( G" q# l8 d    m_ClientNetConfigLock.Enter();
- S; s0 r+ z8 G/ a( {    m_ClientNetConfig.wUpdateRate = WORD(rate);; Z4 q3 p! u# o, K2 D3 y
    ServerConfigPacket  packet( m_ClientNetConfig );" C( @+ r1 Q  F6 ~% l; B
    m_ClientNetConfigLock.Leave();</P>0 d4 Y* m$ v' J' o1 q
<P>    SendConfigPacketToAll( &amp;packet );
! G! S1 I7 D: k4 [8 x* Y}</P>
' p" S. S& T# K2 p6 U2 c* t2 [4 B9 j9 K- @/ I
<P>
, t) I5 B6 `+ c1 H& n, f, Y# k//------------------------------------------------------------------------------ h4 ^7 x" h. s( f; W
// Name: 5 D1 {1 Y0 k& L. n6 i2 B
// Desc:
* k  ^0 z1 m  x0 t, @//-----------------------------------------------------------------------------) ?6 h4 i1 f9 X! U9 B/ {  c2 ^. b
void CMazeServer::SetClientTimeout( DWORD timeout )
6 h) ^6 U6 \, p5 i) {" ^{- a/ _3 o1 s% n- E* d: B+ v2 l; e
    // Update client config, and build packet containing that data
% J/ k4 T# f- q7 c6 l! w    m_ClientNetConfigLock.Enter();  u! _' U0 K2 [9 n$ N
    m_ClientNetConfig.wTimeout = WORD(timeout);4 j9 n5 A% p$ h  ~2 a4 @
    ServerConfigPacket  packet( m_ClientNetConfig );1 a$ v4 m" i' i& |
    m_ClientNetConfigLock.Leave();</P>6 J' P1 L6 S2 x: ^( Z: C& @
<P>    SendConfigPacketToAll( &amp;packet );( P9 H+ K6 h6 x) n0 \& o! F, a' c) E
}</P>5 W- ?. ~1 C& {2 t

/ N! n: `' `9 }' ^, |<P>: C8 p- \2 H& m) d; Y/ I
//-----------------------------------------------------------------------------
0 C2 j* Z/ I. {# x% U// Name:
, x$ x: m2 s  Z" I4 u$ ^// Desc:
) J3 c) ?' R* A, J//-----------------------------------------------------------------------------
- @: _. @$ ?: ~7 w. R( r" K- J7 lvoid CMazeServer::SetClientPackSize( DWORD size )& Z+ a  Q! ~2 s4 |: C' D; R' J
{
+ `- C6 p: T! z" `9 ]- T/ }    // Update client config, and build packet containing that data* g  [2 J' v4 P0 `/ B, T
    m_ClientNetConfigLock.Enter();0 `- Z$ k! z0 R" n9 P* z  d0 U
   
# G7 N0 g3 Z0 u    m_ClientNetConfig.ubClientPackIndex++; //Increase index and verify location in array.% \. A. |& a7 }  u
    if(m_ClientNetConfig.ubClientPackIndex &gt;= PACK_ARRAY_SIZE)   
. \( d2 K- N- G' }; v! i3 K        m_ClientNetConfig.ubClientPackIndex = 0;</P>
7 e1 q  J# F* r7 q! t<P>    m_ClientNetConfig.wClientPackSizeArray[m_ClientNetConfig.ubClientPackIndex] = WORD(size);6 C- H% F) v+ Q# I/ B/ R; A
    ServerConfigPacket packet( m_ClientNetConfig );6 e' I2 w# y7 j" K2 \' V) p
    m_ClientNetConfigLock.Leave();</P>
, J9 ~; p8 O8 j+ b+ M8 L/ V<P>    SendConfigPacketToAll( &amp;packet );+ v4 |8 ]5 H7 M1 U4 L
}</P>
4 `. W/ q9 |( Z: u+ m' M- J5 [# u4 ~1 w* N# Z$ N; e
<P>
  Q: u0 m% v% u- @2 n//-----------------------------------------------------------------------------
; E$ f5 D+ Y& }- g; y// Name: ' _) j$ A- e# C. a# l3 {
// Desc:
* x; O6 y/ R( Y* H9 n8 d/ M//------------------------------------------------------------------------------ z" ^; ]' r4 o! y: Z1 V/ t/ L
void CMazeServer::SetServerPackSize( DWORD size )$ {: T3 X( J5 W8 s9 H) M
{" B  e4 N1 \# c' n
    // Update client config, and build packet containing that data2 Q8 S2 ~5 P  h: \3 B: `/ \1 q
    m_ClientNetConfigLock.Enter();! m; B( W/ ^5 e% q/ E. P& K1 j
    3 l( Q- f' ?  ?( ?5 t4 [$ V% ]; v
    m_ClientNetConfig.ubServerPackIndex++; //Increase index and verify location in array.! O) X3 W1 Z4 D( p( w' ~9 j
    if(m_ClientNetConfig.ubServerPackIndex &gt;= PACK_ARRAY_SIZE)   ' o# ?7 \) h+ Y, Z
        m_ClientNetConfig.ubServerPackIndex = 0;</P>
( {# O  d: J. A0 I# D<P>    m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex] = WORD(size);
: X5 V) g$ k' j; i- U9 G    ServerConfigPacket packet( m_ClientNetConfig );. y6 |2 `% ~, U" t4 V/ H8 ]; P
    m_ClientNetConfigLock.Leave();</P>7 R5 O3 c$ W0 H
<P>    SendConfigPacketToAll( &amp;packet );( S6 U# n# n6 T) P" L/ l- H5 c8 |
}</P>/ W5 l6 h/ n  o, g. h% F, z6 s8 ~3 C1 j
<P>" C1 D# v+ O/ ~& a/ [+ ]# V
//-----------------------------------------------------------------------------1 M; U( b5 l* z9 C' i1 t, V1 I
// Name:
5 M9 K* S: I9 o3 ^  E% {// Desc: 0 c3 @5 e& u3 o9 g( E4 C7 |
//-----------------------------------------------------------------------------
  I9 @  I7 O8 f% I+ V$ r( y$ @3 `void CMazeServer::SetClientThreadWait( DWORD dwThreadWait )% R' K$ ^4 y- N0 ^! R) Z0 G
{
  P+ v- @3 k/ P% O    // Update client config, and build packet containing that data$ n3 K+ }; E  o) G8 F
    m_ClientNetConfigLock.Enter();
1 A) w5 [: s. j    ' M- p) D% D4 g4 |8 q% S$ j# [
    m_ClientNetConfig.dwThreadWait = dwThreadWait;* A6 c# ?* ~( g0 w
    ServerConfigPacket packet( m_ClientNetConfig );
" o! L8 Q$ k% T$ A! ~% Z. T8 Y    m_ClientNetConfigLock.Leave();</P>8 S8 N0 V; q3 e/ R. a
<P>    SendConfigPacketToAll( &amp;packet );0 F3 o6 P6 G, f
}</P></DIV>




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