数学建模社区-数学中国

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

作者: ilikenba    时间: 2005-1-31 11:52
标题: [分享]MazeServer源码示例
<DIV class=HtmlCode>
/ {' [7 R! d8 m/ n5 V9 U# X' H<>// File: mazeserver.cpp7 z0 P7 }% S+ }8 ~! T' V6 E6 L
//
1 e) L% {7 Z% K* |; s( X9 s// Desc: see main.cpp
! Y2 Q7 {5 @' X6 T//
" K3 |! G: i/ v1 ?* f: p' Q& c// Copyright (c) 1999-2001 Microsoft Corp. All rights reserved.
, A, L! t* p4 P//-----------------------------------------------------------------------------
5 B' E$ g$ \- I- \% T4 h( l  v#define STRICT
" i* l  z# Z1 i$ h7 w#define D3D_OVERLOADS
( h; ~2 E' @, L#include &lt;windows.h&gt;
4 L# ?! b/ y3 N5 T2 w( p$ t#include &lt;d3dx.h&gt;
' n$ u* Z8 j, y! O1 h9 j% {#include &lt;stdio.h&gt;
. [: P( h+ M( Y9 c/ n#include &lt;math.h&gt;# U  G( J7 ~/ s; `% T0 G# s
#include &lt;mmsystem.h&gt;
, }+ P8 S# E& i+ B8 ^#include &lt;dplay8.h&gt;
; e; r" `7 R5 t6 q! b8 }! d#include &lt;dpaddr.h&gt;6 f% @9 [- ^, ~( i: m) O( {
#include &lt;dxerr8.h&gt;" j6 Q6 q' e( h8 d9 s, ~
#include "DXUtil.h"
" @  N, j( E" f# W3 y#include "MazeServer.h"
3 M4 ?) [& F! U, \2 W* A#include "ackets.h"& S, J/ [8 ]5 K1 q1 |) @  z# B
#include "Maze.h"
5 `. D1 }* L4 S/ _) ^2 Y#include &lt;malloc.h&gt;
! L* i/ k5 Z  t* I#include &lt;tchar.h&gt;</P>
* A) E; F4 B% u
  g* p. z6 i5 a4 c$ x2 h<>//-----------------------------------------------------------------------------% }) s1 G+ A: b6 x8 i% T1 _
// Name: 9 y. A; C- y- _3 {
// Desc:
) C0 {8 a  A. T//-----------------------------------------------------------------------------
, w' K% B  M. t  L: p8 \, YCMazeServer::CMazeServer()% T5 ~& G! J5 A; A
{
1 z9 ?- J' t4 ?    m_dwPlayerCount         = 0;
9 @8 c7 E1 F- F! R5 ^   
2 D  J# s. N7 D+ }    m_wActiveThreadCount   = 0;1 |* l% X2 t7 {- Q; \
    m_wMaxThreadCount      = 0;2 W+ [$ H5 {: o- z
    m_fAvgThreadCount      = 0;1 S# L$ E  [- g4 q, s) N2 T
    m_fAvgThreadTime       = 0;
  k/ I7 {2 Z! d; T    m_fMaxThreadTime       = 0;</P>
# }2 N1 a% r# E- I" I9 k# @<>    m_dwServerReliableRate  = 15;
3 ]% \9 Q* x% C% a+ z7 f( [% c    m_dwServerTimeout       = 150;
, @! `6 M5 i1 H( y5 [. d) B    m_dwLogLevel            = 2;( _  C; e- E# M! A
    m_pMaze                 = NULL;</P>2 d1 ~2 N/ J* g, G% N2 Z+ X
<>    m_ClientNetConfig.ubReliableRate = 15;
2 P: @7 X  b* N5 ^8 {  {( _    m_ClientNetConfig.wUpdateRate    = 150;: m" `/ _( K# ?% Y! y! `6 B
    m_ClientNetConfig.wTimeout       = 150;</P>" ^% [5 Q) n1 X0 F! U, v, @
<>    m_ClientNetConfig.dwThreadWait = 0;</P>
# [0 l1 z3 q; e; |<>    m_ClientNetConfig.ubClientPackIndex = 0;, p3 ~! I! [- l( x7 Y
    m_ClientNetConfig.ubServerPackIndex = 0;
5 @$ [, c5 v8 @- T$ ~$ B    for(WORD x = 0; x &lt; PACK_ARRAY_SIZE; x++)9 z, }  r0 @4 ~( ~# v
    {
* e# L9 e5 _9 U# E        m_ClientNetConfig.wClientPackSizeArray[x] = 0;8 ?' r& @& o0 O1 V' O
        m_ClientNetConfig.wServerPackSizeArray[x] = 0;8 i( Q1 R. d( [3 F9 j% S( w
    }: v7 f1 C- z# e' V
}</P>' Q* Y3 B9 u' i

. E) o6 ]. f1 e' W<>
. L+ q/ m6 r2 @( d9 x( q; _//-----------------------------------------------------------------------------+ f5 d, m' H1 b% g5 J! Y. W
// Name:
. K/ V- B9 p% q// Desc:
6 j7 b' }0 x/ Y3 `7 h+ x5 w8 @0 t7 P//-----------------------------------------------------------------------------
1 t5 b4 Z- g$ d; |, r' l, YHRESULT CMazeServer::Init( BOOL bLocalLoopback, const CMaze* pMaze )
4 ?1 c9 e9 w/ e- D2 k{$ l9 G) e$ g$ X$ {
    m_bLocalLoopback = bLocalLoopback;
) \6 [" c$ c% N    m_pMaze = pMaze;2 Y8 Y6 D6 I8 O1 e3 g) ^! O4 I) g
    if( m_pMaze == NULL )
1 K6 [  K. A7 M+ L        return DXTRACE_ERR( TEXT("aram"), E_FAIL );</P>
# g8 W4 b" @4 ?<>    // Grab height and width of maze
$ v7 q' t/ w; {1 m2 p# S4 o- U5 o    m_dwWidth = m_pMaze-&gt;GetWidth();
: n3 p0 v  S& \    m_dwHeight = m_pMaze-&gt;GetHeight();</P>
( s, B1 D% q: ?" E+ H5 S8 L<>    m_ClientNetConfig.dwMazeWidth  = m_dwWidth;" O* c) ^3 E0 ~, I/ T! J0 F( F& g
    m_ClientNetConfig.dwMazeHeight = m_dwHeight;</P>
4 b  y" ~" b* A: H<>    // Validate size. Must be a power-of-2 times LOCK_GRID_SIZE. Compute the shifts.3 v& N- J6 F' F7 G3 p3 O7 Q$ P
    if( m_dwWidth &gt; SERVER_MAX_WIDTH || m_dwHeight &gt; SERVER_MAX_HEIGHT )( c% s6 g$ l- m6 j6 ?$ @5 k) O
        return DXTRACE_ERR( TEXT("Maze height and width need to be less than 128"), E_INVALIDARG );; C+ B# C8 l' @/ P6 `3 _
    if( (m_dwWidth % LOCK_GRID_SIZE) != 0 || (m_dwHeight % LOCK_GRID_SIZE) != 0 )( j8 B& Z/ T3 t
        return DXTRACE_ERR( TEXT("Maze height and width need to be divisable by 16"), E_INVALIDARG );</P>
' T+ k4 y9 n3 r( Q, y<>    DWORD scale = m_dwWidth / LOCK_GRID_SIZE;
# B; \5 |; J* c  ^: N+ T    m_dwMazeXShift = 0;
) g, L/ T9 K3 l3 `; L' J/ N1 L    while ( (scale &gt;&gt;= 1) )
7 Y9 u3 k/ z" I, V. k        m_dwMazeXShift++;</P>+ W" `% W2 J. l% p1 [
<>    scale = m_dwHeight / LOCK_GRID_SIZE;5 ^* x! M; P- @9 O
    m_dwMazeYShift = 0;; s/ l: E5 [: `3 I* g
    while ( (scale &gt;&gt;= 1) )
, q' f2 b3 Y3 F! [# b# {$ U        m_dwMazeYShift++;</P>+ L0 M9 {5 ]# l' ^
<>    if( ((DWORD(LOCK_GRID_SIZE) &lt;&lt; m_dwMazeXShift) != m_dwWidth) ||" ?. u1 P8 }# P
        ((DWORD(LOCK_GRID_SIZE) &lt;&lt; m_dwMazeYShift) != m_dwHeight) )
6 A+ a( J  P$ M- w) j        return DXTRACE_ERR( TEXT("Maze height and width need to be power of 2"), E_INVALIDARG );</P>
. \, K; d2 k5 m- r* P$ O2 x+ {<>    // Initialise the player list4 \/ g' ~! z5 L. }$ I  X
    ZeroMemory( m_PlayerDatas, sizeof(m_PlayerDatas) );( T& @4 p3 y  }
    m_pFirstActivePlayerData = NULL;! }4 t) o- Y$ J' u" Z3 c3 D
    m_pFirstFreePlayerData = m_PlayerDatas;+ j0 d. o# a8 ]3 F: m
    for( DWORD i = 1; i &lt; MAX_PLAYER_OBJECTS-1; i++ )" j% V+ w+ A3 G' P- O
    {; F* ?# X# z+ y
        m_PlayerDatas.pNext = &amp;m_PlayerDatas[i+1];
. _* C6 e, e7 v7 E7 e  o. P% H        m_PlayerDatas.pPrevious = &amp;m_PlayerDatas[i-1];
" T8 S! s; A% E# {8 `7 `* A    }</P>: m. N- I7 N% {0 U: P' Z
<>    m_PlayerDatas[0].pNext = &amp;m_PlayerDatas[1];
3 F) x) J% f7 B    m_PlayerDatas[MAX_PLAYER_OBJECTS-1].pPrevious = &amp;m_PlayerDatas[MAX_PLAYER_OBJECTS-2];0 ]/ ?, l3 i! m" u
    m_dwActivePlayerDataCount = 0;
, @3 P. Q8 K) W7 F5 d/ n    m_dwPlayerDataUniqueValue = 0;</P>
9 C0 J9 f6 S; p/ z# x; L/ l% c% s! z<>    // Initialise the cells
7 X0 k" K' \8 U    ZeroMemory( m_Cells, sizeof(m_Cells) );8 u4 K/ \% c5 D# a( J: C% c* F7 q
    ZeroMemory( &amp;m_OffMapCell, sizeof(m_OffMapCell) );</P>9 I: ~: l8 h9 D3 x2 r9 `" ^
<>    return S_OK;
! C: m% }' f0 g7 v6 l3 c& a& ~( V}</P>+ s6 ]; n  C1 m  N0 S

6 N, v/ s/ v  g+ r6 c  O1 W<>5 S4 T% Y" G: U1 w/ G, U& t
//-----------------------------------------------------------------------------6 m& i' H2 J- V, H4 a6 W1 U& ~
// Name: $ _2 v: Q$ {% ]# V
// Desc: 8 M! D9 X: e  j9 T- g( K/ U% [
//-----------------------------------------------------------------------------) f/ J1 w9 m: {  G+ k3 s* h) n
void CMazeServer::Shutdown()
  u* U& w9 b4 o{) H& i5 X' c' g( r
}</P>0 J6 U8 z/ t. n
, f+ B  l9 X& w' @8 Y2 \
<>
% o- T5 \7 b) T$ u  D* U: g//-----------------------------------------------------------------------------; R" S4 b8 j5 F3 W  B6 X. I
// Name: / m# V' `! m" h& c
// Desc:
( @  Z+ e$ l; [7 G- o- k//-----------------------------------------------------------------------------; A' o3 f% G1 b- e% W+ P7 w
void CMazeServer:ockRange( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )/ [7 O* g# \& B3 u3 c
{
* \3 |9 l" z+ \    m_LockGrid.LockRange( x1&gt;&gt;m_dwMazeXShift, y1&gt;&gt;m_dwMazeYShift ," D" }7 h, L5 }1 ~; h1 J) A1 u
                          x2&gt;&gt;m_dwMazeXShift, y2&gt;&gt;m_dwMazeYShift );1 \" P) [, M  L8 T; w6 z
}</P>3 P5 d( ^2 g; h- P
4 \0 T+ }0 W# u9 M* t( g
<>) n' g) [+ i6 X4 ]7 ~7 W
//-----------------------------------------------------------------------------0 u% d% |4 R' C$ A* ^+ G
// Name: 9 p. x4 O( V( b
// Desc:
; r7 n9 S0 V9 P" N//-----------------------------------------------------------------------------
; Y6 t# F& k( T; uvoid CMazeServer::UnlockRange( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )6 I' H. M+ b# t2 H: k* \- G' c
{
( \4 k/ m+ T8 \9 A( _$ m# J    m_LockGrid.UnlockRange( x1&gt;&gt;m_dwMazeXShift, y1&gt;&gt;m_dwMazeYShift ,
' U3 g& j; a! @2 I( ~                            x2&gt;&gt;m_dwMazeXShift, y2&gt;&gt;m_dwMazeYShift );
8 R$ Z' R, r- B+ n9 n}</P>2 q- L( ~4 ?( `8 Y; s  l! I
& V6 v( w3 N  r& {2 e) a3 M: ]' x
<>
0 g2 N" i) c0 i/ S. z0 {# c$ F; F//-----------------------------------------------------------------------------
( B# P8 j5 M* y- Y# P9 Y: Z- [// Name: 5 U; {) x3 C' V  t3 j0 @
// Desc: ( q, K6 H' C1 Z# n- v% A
//-----------------------------------------------------------------------------
6 u& h# I& Z4 c+ P! E+ [5 gvoid CMazeServer:ockCell( DWORD x, DWORD y )
- w# Z' Q$ O6 A& \{
1 q! I: b, u- Z/ I3 H6 n/ Q    if( x == 0xffff )
; Q2 f" \9 G) ~: o. @0 f; w9 P2 o, x        m_OffMapLock.Enter();: {  d7 k% B8 h
    else
& \7 ~7 W7 a5 ~- q5 a* c; h  f        m_LockGrid.LockCell(x&gt;&gt;m_dwMazeXShift,y&gt;&gt;m_dwMazeYShift);
: m# t7 ~! n* _+ n9 l2 e/ ], {}</P>
) ?0 d! z# Q4 y; u7 k
% G1 W5 y  x6 O; j- E4 i<>
* g- w# h' ~  [5 {//-----------------------------------------------------------------------------' B1 ~8 ]( {9 F
// Name: & q4 v5 t3 @9 b# m$ K" Z; |* p* A
// Desc:
# I5 Q) q2 `. t4 R( R//-----------------------------------------------------------------------------
9 e: Z2 Y/ [( }: n; \) m- fvoid CMazeServer::UnlockCell( DWORD x, DWORD y )
  T& J; }' w, C7 B3 t9 Q7 X{
8 {2 |3 n8 d) T1 M( E4 s7 w    if( x == 0xffff )
: ~( h# z5 V. v# e        m_OffMapLock.Leave();
, j4 w; ?' L* L; X/ M, |2 h& a8 Y    else7 `: ~- U3 ]4 X+ ~2 U! c3 V8 g; V
        m_LockGrid.UnlockCell(x&gt;&gt;m_dwMazeXShift,y&gt;&gt;m_dwMazeYShift);0 Z* |4 k8 D2 G( t3 B. p
}</P>
2 U7 X# I, {- P' W  z, B' W1 \0 S5 W$ Q* s8 A
<>
1 L! H' ]& q0 n5 ]' j6 }6 J: f//-----------------------------------------------------------------------------
- w0 f2 V/ S2 U9 Q) i// Name:
, {4 ]/ R9 o# v2 q8 Z5 _// Desc: 1 r6 G6 m6 f) I1 B# f- V
//-----------------------------------------------------------------------------5 K1 Z9 a) j+ `' m' x# n. T) {
void CMazeServer:ockCellPair( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )
" H, u0 v+ Y3 Y) C( l{
2 h: h+ L! V) c. t% @3 v! l    if( x1 == x2 &amp;&amp; y1 == y2 )2 b: V+ L: I% d, e0 W
    {' ?9 u+ \; B; D* N3 w
        if( x1 != 0xffff &amp;&amp; y2 != 0xffff ). z2 j. L. ~1 t7 b7 C+ _/ `
            LockCell( x1, y1 );9 J3 l' z' ]% D0 R6 j5 r. _
        else( F0 U2 H6 n" j+ }4 }, }6 G/ }
            m_OffMapLock.Enter();</P>
/ Z. `6 ?  K  T, {6 R<>        return;( i# E, ~* E* y- c* l
    }</P>1 z! C# n- ~3 I4 X8 T1 L0 ]3 s1 H6 U) x
<>    DWORD x1shift = x1&gt;&gt;m_dwMazeXShift;3 x/ G; O" p' T# S% O( ]. Q0 P
    DWORD x2shift = x2&gt;&gt;m_dwMazeXShift;: g+ g, V* G' P2 F  d
    DWORD y1shift = y1&gt;&gt;m_dwMazeYShift;$ ^0 W8 d2 n0 E1 f( c
    DWORD y2shift = y2&gt;&gt;m_dwMazeYShift;</P>% H- K+ ]( L' E! z, C+ |9 |& }  ?
<>    if( x1 == 0xffff )9 ?* b' N/ e& l; o/ w8 {  A
    {
# R; B$ b* c* y/ ^; U9 w5 H        m_OffMapLock.Enter();; ?/ E0 j, \' s/ H
        m_LockGrid.LockCell(x2shift,y2shift);7 _, e- M4 [) J+ O
    }
0 _0 D5 `$ ]! k6 {    else if( x2 == 0xffff )
; b$ L: E' f# G3 r    {5 v! B# ?  p, l, \" a
        m_OffMapLock.Enter();+ V8 o: M* c* Q; D
        m_LockGrid.LockCell(x1shift,y1shift);. |  |2 J. {: f/ k. J) V6 T
    }/ o, B" Z$ c& @- [
    else ' \7 d' E) z# p+ B+ N9 T( y' O
    {
* t/ y$ q4 y# ]% d( e  D        m_LockGrid.LockCellPair(x1shift,y1shift,x2shift,y2shift);
! i+ r3 e& g- s7 r    }: v5 j, H+ N" v, M6 S, M" [2 ]8 k& D
}</P>7 V  E" W$ t" ~
. M' x8 F& n; F% e! ~8 E4 m
<>- @) f: A, ^. ~+ P
//-----------------------------------------------------------------------------
% L0 o6 ]6 E# Q' }// Name:
4 v. O$ c+ k! @$ I' n// Desc:
+ P5 q5 }  a; d9 M  x8 g5 k6 G/ b6 I//-----------------------------------------------------------------------------
0 z( H: a. I1 ^! ]  c) Evoid CMazeServer::UnlockCellPair( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )# H8 _# j2 E: l" x
{
0 h8 [8 w$ r% ]    if( x1 == x2 &amp;&amp; y1 == y2 ): ], W  A  J3 `: D- n. d1 V/ |
    {
, Y3 W, i, d" Z4 F+ Z        if( x1 != 0xffff &amp;&amp; y2 != 0xffff )& [/ C/ h. C$ B+ R
            UnlockCell( x1, y1 );
& L4 A3 A& v  {# _9 B% E        else/ V7 o( j6 Q% \: e9 g; m4 ^  a/ t
            m_OffMapLock.Leave();</P>
- Q0 Q. X! u( o1 U<>        return;8 \. s  E* z9 C7 k( \' V1 f: c
    }</P>! }/ ~7 J2 R* i2 B3 U
<P>    DWORD x1shift = x1&gt;&gt;m_dwMazeXShift;
4 q* y& ?2 Z7 @) l1 o1 s  B    DWORD x2shift = x2&gt;&gt;m_dwMazeXShift;1 @5 y( m& d# ^7 f; d( V! r- S( S" q3 w
    DWORD y1shift = y1&gt;&gt;m_dwMazeYShift;3 a, Y. x, g0 g, w/ J  F" \
    DWORD y2shift = y2&gt;&gt;m_dwMazeYShift;</P>- a2 |1 D# v% r; z
<P>    if( x1 == 0xffff )) y) G4 f% Q  M5 b
    {1 I% P' {# Q' E! q
        m_LockGrid.UnlockCell(x2shift,y2shift);
& l% |- L3 m+ Z        m_OffMapLock.Leave();" L- A& ?) R, p8 o0 K' `( R) [
    }
6 h1 o9 n+ R- N! P; u2 b9 n    else if( x2 == 0xffff )
  D% K$ g: j/ r& n/ @) d1 ]0 D    {- `, r" K  r+ |+ x* o
        m_LockGrid.UnlockCell(x1shift,y1shift);
3 H' \$ b1 v$ W  {* r; s# w        m_OffMapLock.Leave();
8 S2 l  L+ f# N0 Y. z    }
3 P# }  a5 z$ K5 b* z    else
7 e7 f: Y7 g0 ]  n1 l    {
& X2 u( I- l' h3 U3 _1 [9 j: }. y        m_LockGrid.UnlockCellPair(x1shift,y1shift,x2shift,y2shift);
# p) T% {- H/ Q: F6 c* o/ ~    }
6 f1 r: q8 h) x9 }1 t}</P>
" K4 y9 U  Y) I8 ^
7 ~& V7 S; G0 W: |<P>
/ U  w0 y  `& h6 k//-----------------------------------------------------------------------------6 g! g; s' |. z
// Name:
; E, b" u! M5 G( X& P// Desc: . S. m# x; G& h5 s% [. M8 ?
//-----------------------------------------------------------------------------4 v, }( `! X4 n8 O2 e
void CMazeServer::OnAddConnection( DWORD id )
1 ^0 Y; N  p: R4 A& D1 p% c{
( b' i. o1 G. n5 ?7 O    m_AddRemoveLock.Enter();</P>
, E7 g& P8 Y1 u8 X0 {$ F& n8 a<P>    // Increment our count of players4 J3 l; D. _7 O+ {
    m_dwPlayerCount++;% M# O) Z4 R" l5 l  L. k
    if( m_dwLogLevel &gt; 0 ): x% K3 x, K, m. o4 q+ M% F
    {" s' W5 w% T5 }: _  ~# \
        ConsolePrintf( SLINE_LOG, TEXT("Adding player DPNID %0.8x"), id );
. S& d$ S- _, j# @, h6 z0 X        ConsolePrintf( SLINE_LOG, TEXT("Players connected = %d"), m_dwPlayerCount );
4 J* w4 a9 C2 l2 p) e( d# ^' z    }</P>
$ w3 G- S/ o/ N4 M/ d, r<P>    if( m_dwPlayerCount &gt; m_dwPeakPlayerCount )
" d# o9 b- k) w* b        m_dwPeakPlayerCount = m_dwPlayerCount;</P>0 m. y$ M/ m$ ~/ u* g
<P>    // Create a player for this client
6 w" D" Y/ ]4 k/ \* O+ x) L# u  j    PlayerData* pPlayerData = CreatePlayerData();0 o4 O3 {- n4 a0 f1 G9 o  \
    if( pPlayerData == NULL )
8 _  ~" l3 ?' Z    {
/ ~7 U& [4 X: e& w# O6 h        ConsolePrintf( SLINE_LOG, TEXT("ERROR! Unable to create new PlayerData for client!") );3 h0 a9 h$ K$ J# p( J5 b  \* v
        DXTRACE_ERR( TEXT("CreatePlayerData"), E_FAIL );
2 J, P; U4 ~$ _0 h        m_AddRemoveLock.Leave();
4 d: h5 \3 W& r$ C, [2 {        return;7 d* ^! f6 f5 @& ]  f2 H8 s
    }</P>
9 l6 U, F8 u3 K- u8 n6 W- q) W<P>    // Store that pointer as local player data# R/ J* }( G1 O2 y: @+ P
    SetPlayerDataForID( id, pPlayerData );</P>
7 _% R4 h% y- u" _& d# H3 [<P>    // Grab net config into to send to client' d' ]3 N8 m3 ?6 A' m
    m_ClientNetConfigLock.Enter();' H! ]+ D6 i- s8 k9 Y& S
    ServerConfigPacket packet( m_ClientNetConfig );
* M% u0 ?8 @2 o; J5 ~    m_ClientNetConfigLock.Leave();</P>
8 F3 H7 R/ L% U0 C<P>    // Send it: d$ |- j6 o% @3 L; H
    SendPacket( id, &amp;packet, sizeof(packet), TRUE, 0 );</P>
; u9 f0 q6 l" s5 i* t<P>    m_AddRemoveLock.Leave();; I, ]+ L# [2 D5 M8 A+ ^7 J* t
}</P>. K2 _! h% \: K- W

6 h* ?" G) f& p  D7 G+ q<P>
& K* h: H. E7 \& h: {3 N//-----------------------------------------------------------------------------2 B" ?4 @  Q- k
// Name: / J0 h: Z( }6 s5 o; D
// Desc: 6 d, }# g0 x$ R. m5 G. c# {  C
//-----------------------------------------------------------------------------
: [5 W3 m9 j( ?1 S- Rvoid CMazeServer::OnRemoveConnection( DWORD id )" }+ _+ \5 m, W! t, p% Q( k
{
2 I2 \; r" }; z' c1 ?3 H; n    m_AddRemoveLock.Enter();</P>: K% G7 o: I- W5 V2 G
<P>    // Decrement count of players/ g; f6 [* _( Q3 r# f; A
    m_dwPlayerCount--;</P>( @+ I/ X5 j( l! q. h
<P>    if( m_dwLogLevel &gt; 0 )
/ y; r* J8 m1 ], Z( j    {: e$ i; k/ H; S8 r
        ConsolePrintf( SLINE_LOG, TEXT("Removing player DPNID %0.8x"), id );" n) ^% E8 a& \: ?! d! f
        ConsolePrintf( SLINE_LOG, TEXT("Players connected = %d"), m_dwPlayerCount );7 O( P5 U" u5 @+ m
    }</P>5 P4 E' B/ F. W1 W3 ~8 K
<P>    // Find playerdata for this client" y/ F. s! P% e/ |6 L$ T) i: o
    PlayerData* pPlayerData = GetPlayerDataForID( id );( Y* G" L  q! M3 B1 S
    if( pPlayerData != NULL )+ p$ I7 O% B: a. [6 A# H
    {
0 D; ]0 U6 [8 Q% a9 v, I2 ?        // Destroy it5 l* K) q4 u7 w# o. r5 o
        RemovePlayerDataID( pPlayerData );
8 m# ?/ X! Z* b        DestroyPlayerData( pPlayerData );$ _+ |$ R3 T8 B" X4 h: Q; i8 r  n
    }</P>
1 D! i/ f/ k' P/ h' l<P>    m_AddRemoveLock.Leave();' l3 k9 @; [9 S: l
}</P>6 r/ D+ o; x; ]7 Y; @

- o0 O7 a" }$ f" l: S<P>+ ^" p% c0 G7 y0 h3 i+ \
//-----------------------------------------------------------------------------
6 _4 v3 I% d6 d+ E, D// Name:
, O, |8 s6 Y- o+ L// Desc: ( n' N7 \, Z, H8 ^/ }$ z
//-----------------------------------------------------------------------------) v+ B% P1 ^  _& s! w
HRESULT CMazeServer::OnPacket( DWORD dwFrom, void* pData, DWORD size )! n) `& ^: U7 o6 O
{' s+ {# w1 w2 D- B; S8 F8 a# p
    BOOL fFoundSize = FALSE;</P>
; o. P* A0 O6 W5 v7 U$ {- K<P>    // Increment the number of thread we have in this process.
4 i5 u: H. `2 ~, W$ N- `    m_csThreadCountLock.Enter();</P>6 `1 S$ W0 x6 r, @; O
<P>    //Get the start time of when we entered the message handler.
: @; o7 O6 k. j; m    FLOAT   fStartTime = DXUtil_Timer( TIMER_GETAPPTIME );</P>
, `8 }6 J* U2 i) I1 B# a. N<P>    m_wActiveThreadCount++;: T; R6 d. H) D! R9 X% z, k
    if(m_wActiveThreadCount &gt; m_wMaxThreadCount)
' k- d  \( U% w) ~4 k* b7 c        m_wMaxThreadCount = m_wActiveThreadCount;
, ^+ e* b; V+ P   
1 p, w9 V; A* n( z: G  Z    // Calculate and average.
* e7 P, Z2 {& b6 b    FLOAT fdiff = m_wActiveThreadCount - m_fAvgThreadCount;
" c9 H9 P5 d# p% U3 ]/ d    m_fAvgThreadCount += fdiff/32;
( |! i- `" g% Z    % J; b# s0 ]# z/ E! E$ g
    m_csThreadCountLock.Leave();</P>
# P/ v! e$ o; W<P>
* N3 H  M% t8 }3 N# l2 o    ClientPacket* pClientPack = (ClientPacket*)pData;4 d+ c' Q1 h0 E! Y$ Y! `
    switch( pClientPack-&gt;wType )
; Z3 F1 y8 E% k( s7 @* q    {
2 ~7 S4 m+ A: x5 q        case PACKETTYPE_CLIENT_POS:+ e5 E  X' {2 m6 Y7 }: A
            6 t' a, e& f  n3 }  q8 H
            // Check to see if the packet has a valid size. Including
1 D: l: n, P. C+ w" @9 E, ~7 V" m            // the custom pack size.7 h& A( }! S1 @* u6 B9 o
            if( size &lt; sizeof(ClientPosPacket))8 i7 n: ?( X' t/ a' q2 x- N1 K
                fFoundSize = FALSE;
, o+ M+ W8 M1 U/ f/ o, l8 w6 k$ O2 K            else if( ! IsValidPackSize(size - sizeof(ClientPosPacket)))$ ]3 j0 \- S& c0 S' h9 L% a
                fFoundSize = FALSE;
8 ^: x5 F3 z3 `3 X- s1 ]            else
5 m/ ~$ K: s4 i+ ?$ v- G                fFoundSize = TRUE;</P>( I5 S% O, k4 O  ?/ s2 V0 n
<P>            // If valid sized packet, handle the position.
0 _# J- \9 }2 ?. w/ c+ P4 g/ R            if(fFoundSize)4 v" ~8 X& n' N( J# w/ z! P
                HandleClientPosPacket( dwFrom, (ClientPosPacket*)pClientPack );
' M# }# H/ |2 _# l: [: S            else
- `+ @, O5 j0 n1 D( |5 s9 K# ^# ]                m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );</P>( U7 b% k  `2 e; E8 O$ v
<P>            break;</P>
+ T( H: B4 e& n: Z<P>        case PACKETTYPE_CLIENT_VERSION:( o7 f/ @/ Y" A6 i3 \  a: W: o/ P
            if( size == sizeof(ClientVersionPacket) )+ L* E1 J4 [( p9 \  d1 _
                HandleClientVersionPacket( dwFrom, (ClientVersionPacket*)pClientPack );& v5 N& m7 f, k* O7 b. e, p4 E& K0 B
            else
6 p4 R& n: G3 c  y+ q                m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );
" {5 K3 x4 M' R7 V            break;</P>
$ g8 C9 }. A" d2 T" x& M0 ~6 i# z<P>        case PACKETTYPE_SERVER_CONFIG:</P>
7 U" F8 f5 k9 o! V<P>            // Server config packet sent to all users (including server). Just ignore and continue.</P>9 c  A* B5 S9 ?5 A( [4 b& D; ?
<P>            break;
0 o! ^; r9 n1 g" h+ d, l" O        default:
) |1 f! _' @/ s- C( Y, P4 x            HandleUnknownPacket( dwFrom, pClientPack, size );
( k# v- I- \( Q            break;0 e2 t" R8 V0 Z" P8 C" n
    }</P>% f7 x* A% k% Q# ~
<P>    //If the user wants to hold the thread, Sleep for given amount of time., @& W/ n; L: E  t
    if ( m_dwServerThreadWait &gt; 0 )& K- ^0 J1 Z* S- @4 |
    {
/ z" x- o" [8 [        Sleep( m_dwServerThreadWait );
, v2 _0 O- a1 N0 ?) Q, `    }
; T8 h/ X9 ]! }- g4 X  v   
5 O. G8 h$ q* x* G3 {1 E* g    // Retrieve thread data for this process.
: `" r7 u& k; u8 _$ d    m_csThreadCountLock.Enter();</P>
% b- E( Y% n% B4 \7 R<P>    m_wActiveThreadCount--;</P>8 T5 c/ }/ q: l) ?) w4 m+ n! ~
<P>    FLOAT fDiffTime = (DXUtil_Timer( TIMER_GETAPPTIME ) - fStartTime) - m_fAvgThreadTime;9 z) g- H8 i- p# r( n8 P
    m_fAvgThreadTime += fDiffTime/32;</P>
% C( [% p7 E) s8 m<P>    //Get the Max time in the thread.& E/ p5 T, O* p  r, s: B
    if ( fDiffTime &gt; m_fMaxThreadTime )+ Q" C4 d! I6 U
    {
, @  q! A9 f: f7 i0 [        m_fMaxThreadTime = fDiffTime;
9 V. `' I$ Z7 p2 a2 O    }</P>
% C2 u+ \' ~, o$ _  H2 h* i<P>    m_csThreadCountLock.Leave();</P>
. A( B8 W* r* M1 ~9 b1 B* E<P>    return S_OK;
6 c' Y! N$ ]. p  \, ]$ N7 @}</P>7 F, X/ |# v+ S* C

" I) o; I1 q0 D# @1 E<P>//-----------------------------------------------------------------------------6 D8 K" _$ A! r  V8 ^+ u) H
// Name: 7 a+ p+ V. F- [0 B3 }9 X; P: v
// Desc: 0 a+ U2 u6 |" X8 V, Z( @, `
//-----------------------------------------------------------------------------
, n7 H2 s2 P, s, e4 l6 V" aBOOL CMazeServer::IsValidPackSize( DWORD dwSize )" L4 ~5 s/ r# p' Z
{/ I0 k) r! E7 [9 B! d
    BOOL fFoundSize = FALSE;
: V2 B6 C# ^4 v; O; u3 H" B' }; z    BYTE ubPackLocation = m_ClientNetConfig.ubClientPackIndex;
5 g1 S7 ^: J& X. m7 E% a    3 B4 _: a, n" d
    // Check through the array of valid pack sizes.
% }9 @% {% x3 l. \    if(dwSize != m_ClientNetConfig.wClientPackSizeArray[ubPackLocation])
4 W9 D" E. w6 h) M. L/ w3 W    {
( I0 s( h1 f1 H& X9 n        for( --ubPackLocation; ubPackLocation != m_ClientNetConfig.ubClientPackIndex; ubPackLocation--)
! [* y, N6 D0 w2 o0 v( y) r  Q; C        {6 q5 a" F& v4 g. V
            if(dwSize == m_ClientNetConfig.wClientPackSizeArray[ubPackLocation])
+ h9 y7 O/ |* M/ l5 j- U            {
: ^( Q( g, _! C9 }# a' B5 K! I                // Found valid size in the array./ z& s0 p* R+ L7 f0 X
                fFoundSize = TRUE;
2 T& L& m  O0 {* n2 @+ J                break;1 b1 c4 C1 l9 U& u. i
            }
5 o6 `8 v  s0 ]1 X6 V5 i            if(ubPackLocation &gt;= PACK_ARRAY_SIZE)  ubPackLocation = PACK_ARRAY_SIZE;  //Wrap the array., I/ J/ C( l7 }: S" n
        }& `+ l  `4 ^+ Y. D
    }
0 `8 B& S* f6 D  f$ V" E    else- ]/ F) L! z3 O$ t6 t
    {
* q* t0 `, q7 {4 k5 z        fFoundSize = TRUE;' V: @- u( `8 G7 y$ i& q8 ?
    }</P>
" D. |! I% ^, e<P>    return fFoundSize;
5 Q4 G5 c. V8 A0 g" v" A5 ]3 s, ^}</P>* ?0 L8 C; v! e& _$ l& Q
<P>8 }5 J1 h. S7 z1 |
//-----------------------------------------------------------------------------: H' z( p% Z+ B( T2 P. f
// Name:
6 c6 I' \4 X2 s( n+ y  T: @$ p( s! v// Desc:
) I& l' G' W( t3 s! j, ^//-----------------------------------------------------------------------------' p4 @8 q! r9 G& G
void CMazeServer::OnSessionLost( DWORD dwReason )3 U0 K2 S* B9 B/ }5 z9 }7 n
{
1 P! k8 Z! ~0 ?    ConsolePrintf( SLINE_LOG, TEXT("ERROR! Session was lost") );9 G" h& Q& F6 G) X8 H' j4 S
}</P>
9 F. ]" e8 v# U5 I/ h
! ^- c+ y' T. [4 L, |0 z<P># m  T  |; G! G! Q# T7 A  b4 q
//-----------------------------------------------------------------------------
/ r7 j6 O4 c9 O8 E" I// Name:
) ]9 m9 y& `3 h, l9 I9 E0 }; v// Desc: 4 r/ t: T/ M" F  L
//-----------------------------------------------------------------------------& r6 Q& G6 P# w
PlayerData* CMazeServer::CreatePlayerData()- h; b+ h" H# C6 F
{0 L7 ]4 j% Y5 b% T1 K2 ~
    m_PlayerDataListLock.Enter();</P>- s+ A& K$ X- x/ R: p* Y
<P>    // Grab first free player in the list& g  i* u6 _, y$ f
    PlayerData* pPlayerData = m_pFirstFreePlayerData;</P>
& y3 ~, z- e) M6 ^<P>    if( pPlayerData )
" z1 U$ |' A# _7 K    {/ p1 b* I. t7 U  W. b8 A2 ^
        LockPlayerData( pPlayerData );</P>5 p' [+ W/ O2 }, W& ^% E8 P$ q/ r
<P>        // Got one, so remove it from the free list; }1 C% `  N) Y2 W4 F# O% \! Q
        if( pPlayerData-&gt;pPrevious )8 G  N- t- N; f9 O) G
            pPlayerData-&gt;pPrevious-&gt;pNext = pPlayerData-&gt;pNext;+ j, o- v0 Z5 Q6 L1 Z4 J
        if( pPlayerData-&gt;pNext )
$ U! u& }6 ?0 o            pPlayerData-&gt;pNext-&gt;pPrevious = pPlayerData-&gt;pPrevious;
# x% x# S, M, s5 T        m_pFirstFreePlayerData = pPlayerData-&gt;pNext;</P>
+ t" w6 s, |4 C# [; m8 ]$ ~  t<P>        // Add it to the active list9 D1 z$ x* m- a. B4 w; h- q
        if( m_pFirstActivePlayerData )4 R/ Z1 c* A/ `# s5 _- p
            m_pFirstActivePlayerData-&gt;pPrevious = pPlayerData;8 G/ v. w& |; L, i1 S+ }9 }9 U
        pPlayerData-&gt;pNext = m_pFirstActivePlayerData;0 ]$ q1 _# v/ U2 j
        pPlayerData-&gt;pPrevious = NULL;: ?& d0 r- ]: K
        m_pFirstActivePlayerData = pPlayerData;</P>
- ?6 L! B+ d+ _. u3 P- P% f<P>        // Update count of players
+ U* _, Y& A* F% q/ |; g- p        m_dwActivePlayerDataCount++;</P>
* G7 q, @0 {; F. _- k  G<P>        // Generate the ID for this player
5 K' A, G* s4 @8 |! D3 |* P" F        m_dwPlayerDataUniqueValue++;1 v& H, `! E& @
        pPlayerData-&gt;dwID = (DWORD) ((pPlayerData-m_PlayerDatas)|(m_dwPlayerDataUniqueValue&lt;&lt;PLAYER_OBJECT_SLOT_BITS));</P>" C! P. t( }3 c* F' s$ k5 |" ?
<P>        pPlayerData-&gt;pNextInIDHashBucket = NULL;* `' O* K" i" j( q
        pPlayerData-&gt;NetID = 0;7 K/ C: U) A: q! Q; R
        pPlayerData-&gt;dwNumNearbyPlayers = 0;</P>7 e- r- `# t  M8 Q
<P>        // Insert into the "off-map" cell
7 v7 _4 z! ^! U- d/ f" f        pPlayerData-&gt;fPosX = pPlayerData-&gt;fPosY = -1;- Q. k1 q1 x! q) w& r1 N0 R
        pPlayerData-&gt;wCellX = pPlayerData-&gt;wCellY = 0xffff;
8 t( u1 Q. b* D6 k        m_OffMapLock.Enter();( {% M! R2 t! a5 D. _, O8 Z  Z7 Y
        pPlayerData-&gt;pNextInCell = m_OffMapCell.pFirstPlayerData;
1 H9 G4 J# u' w2 R8 E9 B; H  i        m_OffMapCell.pFirstPlayerData = pPlayerData;, q! W& W  y9 s+ \* ]/ }
        m_OffMapLock.Leave();</P>% x1 ]" O9 h, D6 G3 F
<P>        // Mark as active, Y/ V$ r3 s, Q1 p' O( q
        pPlayerData-&gt;bActive = TRUE;</P>
9 ^+ _5 \" K( j/ j7 J<P>        UnlockPlayerData( pPlayerData );
& m5 c9 F& W, w: P4 h, G0 ?    }</P>- T* k7 J$ D% S: c& e0 e
<P>    m_PlayerDataListLock.Leave();</P>
3 n% J" w5 C8 Q0 G2 H4 \  U4 e$ d/ o<P>    return pPlayerData;
) x) [0 k' d6 j}</P>
, M- ~4 e9 d! b. B  h/ O6 s  F
  e, C. F/ K- E8 W3 d2 U<P>
; S$ w+ W2 c; f) }* ~# M//-----------------------------------------------------------------------------3 {( S* r' z' i$ e+ O
// Name:
' q; e7 b% g1 s% S' L* L" Z) N// Desc:
- M/ G% N! j$ n/ o/ \2 n6 L//-----------------------------------------------------------------------------$ ~  e7 s4 U; |2 h5 Q+ y3 _
void CMazeServer:estroyPlayerData( PlayerData* pPlayerData )
) Q# I. S! f$ p0 E4 s7 T{
9 T- y9 x+ g4 R  [; r3 L* r    m_PlayerDataListLock.Enter();( R0 U0 X* s% _8 k8 @: l! E6 j
    LockPlayerData( pPlayerData );</P>
6 y: f* i6 y0 _* m( B<P>    // Remove the player from its cell
" }2 h" x( f# T- |    RemovePlayerDataFromCell( pPlayerData );</P>
+ S9 t4 s" d! W7 J7 \- [$ _<P>    // Mark as inactive
1 [  U! [3 E& k! j$ D' W& X    pPlayerData-&gt;bActive = FALSE;</P># D3 Y: f7 A. c' U- A; B. ?1 A0 ?
<P>    // Remove player from active list; c: O( r  T- y/ t
    if( pPlayerData-&gt;pPrevious )
3 {3 j" M$ o8 X% n; D5 ?6 M        pPlayerData-&gt;pPrevious-&gt;pNext = pPlayerData-&gt;pNext;
" Y- O( x: K3 J! o. v' c    if( pPlayerData-&gt;pNext )) g3 ~3 r6 L+ R3 R- @3 J6 ^
        pPlayerData-&gt;pNext-&gt;pPrevious = pPlayerData-&gt;pPrevious;</P>
9 s. n8 v0 M5 Q7 b& m<P>    if( m_pFirstActivePlayerData == pPlayerData )/ m+ e' a3 e4 }
        m_pFirstActivePlayerData = pPlayerData-&gt;pNext;</P>. K* y3 C9 C& x: t+ q
<P>    // Add it to the free list4 B* U3 {. H& _$ k+ o! B) y1 f( p
    if( m_pFirstFreePlayerData )" X2 a" \/ \6 W2 Y
        m_pFirstFreePlayerData-&gt;pPrevious = pPlayerData;
1 J/ w' e; P' {. z    pPlayerData-&gt;pNext = m_pFirstFreePlayerData;
3 b# B( |4 r# L( A+ Q( h    pPlayerData-&gt;pPrevious = NULL;0 r2 Y) l$ Y( [. y! F; l8 c
    m_pFirstFreePlayerData = pPlayerData;</P>
6 n3 L1 p. x8 O2 s. B0 e/ X! u<P>    // Update count of players
) L* N+ r5 A  G, G9 J! d& d9 ^    m_dwActivePlayerDataCount--;</P>0 G$ r+ L& U! k6 R. W$ V, X
<P>    UnlockPlayerData( pPlayerData );
% ]- e9 s& W! E4 o    m_PlayerDataListLock.Leave();' v; D9 Z) R: S. [  |9 v+ J
}</P>
% P2 N8 ~, i0 R. y7 E5 l0 Y, ~9 k) ^- t2 q9 A
<P>3 x* Z  t7 n+ j' o$ u0 @1 x) r# }
//-----------------------------------------------------------------------------
* b( j9 W; d9 f, Y// Name:
% G9 m, W) m* b; F, M; e6 g! ?" A3 o* A// Desc:
# r! [8 U, H8 ?3 X1 X# |. f/ p: Y//-----------------------------------------------------------------------------6 r7 L* G6 R1 y5 x4 m3 F8 \/ f3 j
void CMazeServer::RemovePlayerDataFromCell( PlayerData* pPlayerData )
; b. F( N" m7 k, P+ k{
( v1 @7 Z5 ?, S# S; J. [    // Lock the player
2 p( x" ^! `: C- |* V+ Y    LockPlayerData( pPlayerData );</P>: x3 L) l. d7 I+ {% t
<P>    // Lock the cell the player is in' r( u0 e( y5 z( ~- X# @
    ServerCell* pCell;
) ?5 P+ t. o& R/ i. l    if( pPlayerData-&gt;wCellX == 0xffff )1 d% I' H5 k8 t2 t0 ~/ K' }! l
    {
, `$ {, r+ }4 O. G. Z& }        m_OffMapLock.Enter();  y' z0 Q5 \+ ~+ ^, q
        pCell = &amp;m_OffMapCell;3 r; P& A& O7 \1 c- J% }- j3 R% @
    }, c- \8 T0 I7 g2 D& T& v
    else- J( R$ }3 L% i( o* I
    {! C% `5 s9 z# p5 ~& k# k& B
        LockCell( pPlayerData-&gt;wCellX, pPlayerData-&gt;wCellY );
7 l* w4 I" L5 S4 c        pCell = &amp;m_Cells[pPlayerData-&gt;wCellY][pPlayerData-&gt;wCellX];
0 ^: G+ M& b- u3 w+ Y7 k/ L    }</P>
. {% Y, ?2 |# ~$ A  H; }: Q<P>    // Remove it from the cell
3 s+ Y+ Q2 a, Z1 s3 j, \* p    PlayerData* pPt = pCell-&gt;pFirstPlayerData;9 i2 ~1 H6 B6 E4 M8 c  k; k$ z% }5 }$ x
    PlayerData* pPrev = NULL;
  ^2 |$ \' Z0 x8 e9 e2 _    while ( pPt )
8 V3 L& M; N' x( A    {
1 l. L! f2 n. N5 T3 _        if( pPt == pPlayerData )
7 r9 N" s& ?  e* q/ {        {
' M# X% ?3 t3 U; K. ?# V, ]            if( pPrev )
# J9 y+ a- a( x6 ~                pPrev-&gt;pNextInCell = pPlayerData-&gt;pNextInCell;
, F( I8 e) Q( q* R) L( e            else
, L; O: y7 ]. d. V- i% J0 E; C( j                pCell-&gt;pFirstPlayerData = pPlayerData-&gt;pNextInCell;</P>
% D6 g7 M) f  ^% Z' c" z6 z7 V<P>            pPlayerData-&gt;pNextInCell = NULL;! M" ]4 Z; R$ `8 y/ Z
            break;4 x% O+ O% `4 O2 ~  H6 [+ n
        }
7 O) B& R1 c2 i6 H        pPrev = pPt;
3 ~6 D8 t4 u) b; B+ i* Z  i% b5 K        pPt = pPt-&gt;pNextInCell;. {9 G2 e3 m+ O3 ^4 z; A
    }</P>
: R3 C9 X7 q- h' \* @% y! H# ?<P>    // Unlock the cell
- j: x0 {. B# _# W! v+ I    if( pPlayerData-&gt;wCellX == 0xffff ); N" W  f. k1 y- u0 m! j% y
        m_OffMapLock.Leave();# S- z& a8 ^% p6 x, b2 }" c+ S
    else2 ?3 v6 q: ?; ^' _3 ~  J! y
        UnlockCell( pPlayerData-&gt;wCellX, pPlayerData-&gt;wCellY );</P>' u: h) @& ]/ c5 S# m% V% b% x
<P>    // Unlock the player
+ t( M6 O# l# \" b! ]    UnlockPlayerData( pPlayerData );2 ~  s9 \/ ]; d- J; i3 ^& o
}</P>
8 }1 Z" d; i; U* @. z& S& `1 h3 }' S+ t4 {+ k8 W: q1 ^. @: q
<P>
4 G- [6 L! u5 k  }/ ^( h6 ]9 P//-----------------------------------------------------------------------------: C3 R! u/ k) i
// Name: ! W+ z& Y! P# I: D. S
// Desc:
( L! Z0 z5 l% O( y$ G//-----------------------------------------------------------------------------4 A2 p( M  L4 q9 g6 |/ L% S4 H6 P( K
void CMazeServer::UnsafeRemovePlayerDataFromCell( PlayerData* pPlayerData )# S  m* L+ ~: N, y  i+ ~
{
' v* K( R& f$ |    ServerCell* pCell = GetCell( pPlayerData );0 I4 }' F' R3 ^4 G
    PlayerData* pPt  = pCell-&gt;pFirstPlayerData;
( P$ b, r4 J+ B* V- d& Y0 ^: }    PlayerData* pPrev = NULL;, g, w9 c5 `' T/ j, F! ?4 s
    while ( pPt )
1 j. a) \! E. q) F. Q3 Y/ y    {" Z3 d  ~# m# W$ B  w
        if( pPt == pPlayerData )
* ^* @, j* m- `1 p        {
* x$ k* C3 b% q* B% q- U8 N            if( pPrev )$ e4 b' q. w) R7 p# @
                pPrev-&gt;pNextInCell = pPlayerData-&gt;pNextInCell;4 q& v  Q% _# n6 u9 O* B4 B# b& t
            else: D4 U! G/ q7 a5 I: X/ ^
                pCell-&gt;pFirstPlayerData = pPlayerData-&gt;pNextInCell;7 c. {& _) O+ Q7 _5 b/ G5 l
            pPlayerData-&gt;pNextInCell = NULL;
' j. i! k- Z1 l            break;% p. ^% g& y8 d  X/ g
        }
& A/ m# K, ]* g% i  Y' ~/ J        pPrev = pPt;
5 O, l9 d% u* [2 n        pPt = pPt-&gt;pNextInCell;
# D) p8 N9 }' w+ i% z) y5 L    }# l8 k! v/ Q9 N, T4 {
}</P>
, u. n( G" _3 j4 _; `' d
. E8 i; Q# r2 k3 |5 s/ m/ _6 D, }<P>. t8 n/ |- g2 u* p% S* d
//-----------------------------------------------------------------------------
; x  s) }3 }) K// Name:
1 `# Z6 f& O: b2 p3 a// Desc:
/ y" K' L- d/ b  A! u# B//-----------------------------------------------------------------------------: T, v" K6 ~" L7 m3 ]7 D
void CMazeServer::UnsafeAddPlayerDataToCell( PlayerData* pPlayerData ); `5 {! U0 S. @$ Z6 m. N
{: I  @2 ^6 R! c: d( [& O: Y/ L. }
    ServerCell* pCell   = GetCell( pPlayerData );6 v" @/ s" O( C
    pPlayerData-&gt;pNextInCell = pCell-&gt;pFirstPlayerData;
) }( R. j5 E& |/ w2 }. `( I: m6 z    pCell-&gt;pFirstPlayerData = pPlayerData;* b1 l& M  F4 J- f
}</P>- h, f0 B' f: d$ h: f
; S2 D( p8 @3 H+ G' S" K: Q) I4 [
<P>
$ S3 g- [# t  r) d& Y% w+ ~! u//-----------------------------------------------------------------------------
( x, s, Z$ }9 f. M8 g& Z// Name: 5 B, F$ z1 K- t' ?; o7 W
// Desc: " H8 |$ _  U1 Z
//-----------------------------------------------------------------------------: v0 Y) w2 i* ^4 [
void CMazeServer::HandleClientPosPacket( DWORD dwFrom, ClientPosPacket* pClientPosPack )
* q/ n0 K: P* L) s6 k1 S1 c" t{
' a3 Z: S+ E, n1 g    // Grab player for this client and lock it
1 e4 J% @( o0 t0 v    PlayerData* pFromPlayer = GetPlayerDataForID( dwFrom );% R1 ~3 d! C  s+ z( p1 N
    if( pFromPlayer == NULL )
8 c5 J7 L% ?% I0 n- h7 F$ t    {
6 y" N! }& K5 ?7 b        if( m_dwLogLevel &gt; 1 )8 K' c7 r. q. w; c# b4 w
            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Could not find data structure for this player"), pFromPlayer-&gt;NetID );, B. U: M- W' A4 G! i
        return;
9 z0 D' d2 d5 r/ q% I3 L- T. @( f& n    }</P>
* L' V$ R$ M5 {; ]6 U# Q<P>    LockPlayerData( pFromPlayer );</P>
7 A, C4 y3 Y1 ~" j2 z6 R<P>    if( FALSE == pFromPlayer-&gt;bAllow )& U# s  ^1 S/ H% C1 R. G
    {
) u0 t& [( I) ]        if( m_dwLogLevel &gt; 0 )
) g5 ]1 b& W2 C  e            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Got position packet from bad client.  Rejecting client"), pFromPlayer-&gt;NetID );</P>9 x2 x. b6 Q2 w. N  I
<P>        m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );2 B8 x: p7 |# I/ F8 Y0 a
        UnlockPlayerData( pFromPlayer );5 O! ]) G& R2 D0 I% n3 F
        return;
# Y9 F6 h- H9 M" f4 u; R    }</P>8 m' V: j: w' m$ K- A
<P>    // Compute the cell the player should be in now. O: X6 i0 B6 a# s0 A
    DWORD newcellx = int(pClientPosPack-&gt;fX);  h! @% y) N: O" Q1 \: X
    DWORD newcelly = int(pClientPosPack-&gt;fY);
7 A/ s9 V4 k( @1 w$ a" [( r3 o7 b    DWORD oldcellx = pFromPlayer-&gt;wCellX;6 [0 n8 x5 ?) n& E
    DWORD oldcelly = pFromPlayer-&gt;wCellY;</P>
& v. N; {, `0 m; P( E3 Y6 [6 S: g. U<P>    // Have we moved cell?
# D+ ~- ~# _, S, ^6 ?. M+ d0 g    if( newcellx != oldcellx || newcelly != oldcelly )( s3 P  q3 k/ J# M1 h/ P8 ?
    {
! ?; F2 T: V$ R1 q' L        // Yes, so lock the pair of cells in question
* v8 q3 c4 v. j/ f0 d6 n        LockCellPair( oldcellx, oldcelly, newcellx, newcelly );</P>
; `$ @) l8 P' e<P>        // Remove from old cell and add to new cell, q+ T2 F7 x- {! |
        UnsafeRemovePlayerDataFromCell( pFromPlayer );. i5 X. Q; }# _4 f8 w
        pFromPlayer-&gt;wCellX = WORD(newcellx); pFromPlayer-&gt;wCellY = WORD(newcelly);+ C2 C" x+ e! A" \
        UnsafeAddPlayerDataToCell( pFromPlayer );</P>
+ d% A2 @; P( m! z/ P( y9 {$ B<P>        // Unlock cells& s- @/ l" {& I' `' d! A. |
        UnlockCellPair( oldcellx, oldcelly, newcellx, newcelly );
+ N4 W/ E1 s5 Z9 e( ~% D    }</P>( l$ B/ b1 j; M1 A$ f# B/ M
<P>    // Update player position
! H. k' T! R2 I, X5 B    pFromPlayer-&gt;fPosX      = pClientPosPack-&gt;fX;
- D; v* R& @. t8 f8 W$ |    pFromPlayer-&gt;fPosY      = pClientPosPack-&gt;fY;  P. l9 `: ~3 S" @5 e0 G
    pFromPlayer-&gt;aCameraYaw = pClientPosPack-&gt;aCameraYaw;</P>
: U; m. \) ?$ ~. O$ x% P% T<P>    // Allocate space to build the reply packet, and fill in header + b0 o" L( K9 {$ U. b/ G: u7 B
    DWORD dwAllocSize;' N. v# U" D7 j
    ServerAckPacket* pSvrAckPack = NULL;</P>" |) n7 \% Y9 d0 B/ z
<P>    // Begin by allocating a buffer sized according to- _2 p/ w+ o! i/ I- z0 h
    // the current number of nearby players + 4.  This will give
; p+ @; n" T# D    // a little room for more players to come 'near' without resize
3 N& m+ h  d1 d& R4 I( O    // the buffer.$ Q+ X$ W7 |0 k; ~9 g  S" I  A
    DWORD dwMaxPlayerStatePackets = pFromPlayer-&gt;dwNumNearbyPlayers + 4;</P># ]- M( f% Y+ H! }2 z$ @
<P>    dwAllocSize = sizeof(ServerAckPacket) + dwMaxPlayerStatePackets*sizeof(PlayerStatePacket);
5 P; K! i) [8 w3 C8 _# |    pSvrAckPack = (ServerAckPacket*) realloc( pSvrAckPack, dwAllocSize );
! }/ K1 |8 s2 {& h+ M    if( NULL == pSvrAckPack )
" e0 m2 k' p. ~% ?    {
) l  f3 f! i: Z/ Y" x; o! U        // Out of mem.  Cleanup and return
) y7 Q$ M- F( W$ _        UnlockPlayerData( pFromPlayer );
! v: K# A9 @( m& n' C0 o        return;      
: |3 S5 z5 t3 _/ Z3 P; K    }
0 Y2 o3 n& n7 o2 e3 v    ZeroMemory( pSvrAckPack, dwAllocSize );</P>
# M% C7 Y6 ?) [/ L' r5 S<P>    *pSvrAckPack = ServerAckPacket(m_dwPlayerCount);6 R; a# a. J1 [( f. E5 s/ R$ ?
    pSvrAckPack-&gt;wPlayerStatePacketCount = 0;. ~' j. R+ m1 j1 f: Z
    PlayerStatePacket* pChunk = (PlayerStatePacket*)(pSvrAckPack+1);</P>
" L7 X9 T0 o/ P" M; x) C7 X! l<P>    // Compute range of cells we're going to scan for players to send( [6 S: Y7 @7 ?# i3 }1 n
    DWORD minx = (newcellx &gt; 7) ? (newcellx - 7) : 0;9 s* |3 |" R) q
    DWORD miny = (newcelly &gt; 7) ? (newcelly - 7) : 0;; B, g, s, P8 |# ^" a! Q: U
    DWORD maxx = (newcellx+7 &gt;= m_dwWidth) ? m_dwWidth-1 : newcellx+7;$ f* ~% K( v1 {0 p. i$ j! z8 W
    DWORD maxy = (newcelly+7 &gt;= m_dwHeight) ? m_dwHeight-1 : newcelly+7;</P>) A4 @9 h# w. C" ]8 }
<P>    // Lock that range of cells
; H% D% m+ t1 ^' d0 ~    LockRange( minx, miny, maxx, maxy );</P>
" K6 L: k; \4 G) ]* f' }' O7 X<P>    // Scan through the cells, tagging player data onto the end of
: m% p" L/ ]2 o3 @' V: S9 f' Z    // our pSvrAckPacket until we run out of room7 [" |$ \1 n7 k% F
    for( DWORD y = miny; y &lt;= maxy; y++ )
0 O* x, ~0 c. W    {9 z4 y0 d# @. S& T
        for( DWORD x = minx; x &lt;= maxx; x++ )9 Q6 s0 K4 k. b( Z. b
        {
$ J5 j$ c: ?" _  U0 C( n' \. X            PlayerData* pCurPlayerData = m_Cells[y][x].pFirstPlayerData;" X0 [3 V; d6 H% e" d( S! ]0 Z
            while ( pCurPlayerData )) ]. y. U( [1 c. M
            {
& X* _# P; |" L. ]) f                if( pCurPlayerData != pFromPlayer ), E8 p1 Q6 N" e  W4 _
                {
2 e% p" f; e' @4 ]* U! |                    if( pSvrAckPack-&gt;wPlayerStatePacketCount &gt;= dwMaxPlayerStatePackets )
6 f$ j- ^2 s& F: L                    {* X+ c% e! A: h/ b3 _
                        // Make sure pChunk is where we think it is
8 h' ]: D$ C3 q1 M9 I                        assert( (BYTE*) pChunk == (BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket)) );</P>
3 l8 w, m6 V3 w6 l/ Q; h<P>                        // There are more than just 4 new nearby players, so resize the - J0 z3 R* k# u! n( B4 v3 x1 @
                        // buffer pSvrAckPack to allow 16 more PlayerStatePacket's." r( r5 n; j8 n0 Q- f
                        dwMaxPlayerStatePackets += 16;" o6 O' t. ^! |& v+ e0 @. }4 c5 ]
                        dwAllocSize = sizeof(ServerAckPacket) + dwMaxPlayerStatePackets*sizeof(PlayerStatePacket);) C0 {# K9 ~# F' k3 [8 J
                        ServerAckPacket* pNewSvrAckPack = NULL;5 q1 o7 [* W& N4 J8 @
                        pNewSvrAckPack = (ServerAckPacket*) realloc( pSvrAckPack, dwAllocSize );
7 ]" m+ ?8 y( v$ t- O3 x4 S                        if( NULL == pNewSvrAckPack )
) n2 |- g+ @0 t5 {                        {
/ \$ m3 S5 f- u7 b' T$ a- Z                            // Out of mem.  Cleanup and return
' k; _' V8 M% D9 @# p5 D- ^$ G0 @                            free( pSvrAckPack );
2 h, e. l0 N% P; h9 y. c                            UnlockRange( minx, miny, maxx, maxy );+ \  m7 u& {& n/ T! b3 _+ ]
                            UnlockPlayerData( pFromPlayer );
  p1 m' |7 i7 _0 q7 f5 O$ R: z& s) u                            return;      
) a" ~# Y' A. E9 D: a                        }</P>
9 o0 Z# p/ X6 L0 u' H<P>                        pSvrAckPack = pNewSvrAckPack;
- m  U& W6 ^- @  a5 L  I2 J                        pChunk = (PlayerStatePacket*) ((BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket) ) );</P>
0 u2 n; k( O! z! j* N<P>                        // Make sure pChunk is still where its supposed to be& o2 F. R. R5 c% \) F
                        assert( (BYTE*) pChunk == (BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket)) );
2 ^/ U0 ]3 M, {: \- b" {+ ^* L. v                    }</P>
8 r4 i$ z3 Z( l; A0 _. s<P>                    pChunk-&gt;dwID       = pCurPlayerData-&gt;dwID;
6 ^$ f9 \" {+ @- \- H+ ~; q" E                    pChunk-&gt;fX         = pCurPlayerData-&gt;fPosX;
0 u3 D2 {  O. y0 D9 j                    pChunk-&gt;fY         = pCurPlayerData-&gt;fPosY;
& v& \% c3 o# I: ]5 I                    pChunk-&gt;aCameraYaw = pCurPlayerData-&gt;aCameraYaw;
/ J% e0 q$ N8 n+ d4 C" ]) j                    pChunk++;- \2 h, x5 l. J$ e3 Q4 P1 m
                    pSvrAckPack-&gt;wPlayerStatePacketCount++;
6 k7 k) {7 A" `                }2 k0 b" e& W* U
                pCurPlayerData = pCurPlayerData-&gt;pNextInCell;) n7 f8 I5 i9 x3 H! k! G
            }
2 b5 }4 {# g, h/ i$ `; k7 |- E: G! K5 {        }
, G7 {$ u& d, U9 x8 t- u& N& W    }</P>
: z/ z6 }  z. {, s' c; L<P>    // Update the dwNumNearbyPlayers for this player
: h5 P8 k. l, s# I: f8 k    pFromPlayer-&gt;dwNumNearbyPlayers = pSvrAckPack-&gt;wPlayerStatePacketCount;</P>
0 t- M5 f9 X1 M0 \<P>    // Unlock range of cells
4 K3 `: R3 o0 s) e" U) ^/ @    UnlockRange( minx, miny, maxx, maxy );</P>
( v. D% }* q% P<P>    if( m_dwLogLevel &gt; 2 )5 V; U, H' \8 w0 L1 }3 q% ?
    {7 a  V* J6 M1 K5 I; l7 o5 k% p
        ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Position is (%0.2f,%0.2f)"), pFromPlayer-&gt;NetID, pFromPlayer-&gt;fPosX, pFromPlayer-&gt;fPosY );, M; J, I; P8 q
    }
) F4 v  x# U8 N    else if( m_dwLogLevel == 2 ), J1 a7 y  {0 B1 G* H0 ?
    {! g/ D# k0 A* \; m
        FLOAT fTime = DXUtil_Timer( TIMER_GETAPPTIME );* P! `$ `, `: Q9 `) ~* H
        if( fTime - pFromPlayer-&gt;fLastDisplayTime &gt; 60.0f )' X; P$ w, ]: r6 t
        {" g6 L' v6 k7 w5 z0 f# Z4 h
            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Position is (%0.2f,%0.2f)"), pFromPlayer-&gt;NetID, pFromPlayer-&gt;fPosX, pFromPlayer-&gt;fPosY );
% {2 o: M, G% [6 ?. g' w            pFromPlayer-&gt;fLastDisplayTime = fTime;8 G9 w& m! g& \' _5 B4 ~0 O
        }
9 A9 z0 x& N* h4 _0 P  R" \    }</P>3 {5 t1 x) f( g6 Y* E
<P>    // Unlock the playerdata* M/ T8 R$ ^$ m6 b
    UnlockPlayerData( pFromPlayer );</P>
8 l; y* A3 G. X7 J7 f" Z<P>    // Send acknowledgement back to client, including list of nearby players
; ^9 X* j( S' g' q$ z; `    DWORD acksize = sizeof(ServerAckPacket) + (pSvrAckPack-&gt;wPlayerStatePacketCount * sizeof(PlayerStatePacket));3 l# ^: Z' k& A( E  x' Q

$ ?+ Z7 _$ V. I5 g8 r: ]1 J$ z- K    // Pack the buffer with dummy data., O6 y0 S2 F) K$ N* J
    if(m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex] &gt; 0)0 R# M% H8 K3 I" `
    {
, |  @7 d3 K' P) }" J/ c        DWORD   dwBufferSize = acksize + m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex];0 y! H: E1 K. b, M/ K. Y) q
        VOID*   pTempBuffer = 0;</P>
5 j" b' e7 r5 |, E<P>        pTempBuffer = malloc(dwBufferSize);: |, F) I# `# K1 c( F
        if( NULL == pTempBuffer )# h! M7 G3 q% l3 [' X
        {
7 O; f/ E+ k+ J% e8 g            //Out of memory
% _' Z. z$ t( q            DXTRACE_ERR_NOMSGBOX( TEXT("System out of Memory!"), E_OUTOFMEMORY );
" \% m& v; o% k3 k. R            free( pSvrAckPack );
3 R; W7 K9 {. f            return;
: `* A& l4 ^/ M        }</P>1 n% t- m: F8 [/ M' O5 Z7 w8 m
<P>        FillMemory(pTempBuffer, dwBufferSize, 'Z');
8 E& j8 r" \7 F        memcpy(pTempBuffer, pSvrAckPack, acksize);</P>
! }; A! C1 z* o. x<P>        SendPacket( dwFrom, pTempBuffer, dwBufferSize, FALSE, m_dwServerTimeout );
* }$ i- P3 P1 u& T8 S    6 [4 Y1 M2 U2 C
        free(pTempBuffer);
* ~' I- J9 `* e    }   
3 T8 j* x  T" {. I0 t: U6 D    else
! p. _1 O" P/ Q4 L' w; [    {
& `0 n% M( x# P$ @! }1 a% r; ~        SendPacket( dwFrom, pSvrAckPack, acksize, FALSE, m_dwServerTimeout );
* `0 G; @  O9 m' g( u+ Q9 ~0 f    }</P>& A5 @( z- j# F  c* M6 w1 y) }
<P>    free( pSvrAckPack );</P># q/ ]# G0 {# c9 A7 @
<P>}</P>
  N, i9 c$ C  k0 v# l- X
- Q* _/ c' M6 _<P>
& S) q1 z$ j$ `4 Q//-----------------------------------------------------------------------------; [  V4 L2 O3 P, t  y& h: l- Q( q
// Name: ( S  }7 B! Q8 E9 y) R# U
// Desc: ) p, O+ R9 t4 Y5 }: B3 }7 D- d6 ^
//-----------------------------------------------------------------------------
  t* B; X! G4 E; d, S1 Ovoid CMazeServer::HandleClientVersionPacket( DWORD dwFrom, ClientVersionPacket* pClientVersionPack )
6 s0 D8 Y: W. H3 B' [/ k{
' B) K# ^8 H3 F) ~" X5 N. d    // Grab playerdata for this client and lock it1 p" ?( q5 i$ z# Y$ e: \. \& I
    PlayerData* pPlayerData = GetPlayerDataForID( dwFrom );
% ]' Q3 e- m0 _: t& L    if( pPlayerData == NULL )* V9 Y& }9 B  e2 c  M& B1 X9 ?
        return;
; X: z' h  B5 l8 c    LockPlayerData( pPlayerData );</P>
  K0 F) w+ `2 D" u# U<P>    // Record the version number
# e9 N0 v$ E  r8 p( u1 X    pPlayerData-&gt;dwVersion = pClientVersionPack-&gt;dwVersion;</P>
! S% R1 s" |! d, s7 k<P>    if( m_bLocalLoopback )
- Z* b% X- _  X% T; J- B        pPlayerData-&gt;bAllow = TRUE;# ~1 ?2 f  k' H/ C
    else# ^, o9 [- `' J! J
        pPlayerData-&gt;bAllow = IsClientVersionSupported( pClientVersionPack-&gt;dwVersion );</P>  h/ b" G4 ?& b" H$ V% a5 T
<P>    if( m_dwLogLevel &gt; 0 )
+ R% k9 B( @# i  R& N/ U5 `- D; u9 K0 |4 u        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>
1 E$ v. x% b& ?' A<P>    if( FALSE == pPlayerData-&gt;bAllow )) v, T2 i( H/ K1 z( \+ }
    {
) [  J1 @$ W3 d" ]# V. L        if( m_dwLogLevel &gt; 0 )2 x0 u/ J- _6 S
            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Rejecting client"), pPlayerData-&gt;NetID );</P>, b, `5 Z( V; o6 W0 T7 [; b
<P>        m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );- `7 t! f" m8 `
        UnlockPlayerData( pPlayerData );
2 j  J# c7 _; d* Q4 M& D        return;3 H2 I- W8 E6 I
    }</P>
6 Y1 Q( }, I% x5 \1 M7 B<P>    // Unlock the playerdata
( w0 \1 V" |& i5 F; M3 A    UnlockPlayerData( pPlayerData );</P>
3 y. j; P6 @8 h$ P+ F<P>    // Send acknowledgement to client that the client was either accepted or rejected, `1 G+ b$ C- V1 y) g7 O
    ServerAckVersionPacket packet( pPlayerData-&gt;bAllow, dwFrom );& |( F' ^2 U# N1 H5 F' ^# }
    SendPacket( dwFrom, &amp;packet, sizeof(packet), TRUE, 0 );
0 z) Y9 Z5 B) J) y$ y: B8 s}</P>
: _2 a5 G/ Z' ~6 ^8 s
' O3 u; z$ Y/ n+ k& q& u<P>
: {/ l" y* `" {  @+ M) M//-----------------------------------------------------------------------------
( O( l# I+ o$ n// Name:
. ^" @5 o  F& Z* l' x. n// Desc:
7 Q+ O0 T6 H5 E6 Q! z7 Z//-----------------------------------------------------------------------------" @5 Q; E4 o1 d1 |* F, A
BOOL CMazeServer::IsClientVersionSupported( DWORD dwClientVersion )
; Y& }$ e; h& u- U{
0 t3 R7 a' x9 k/ ]* m( v    switch( dwClientVersion )
' `! S6 l* s. P# U& D8 M) h6 a, a    {) W0 y" l+ s  e; T7 D4 g* U
        case 107: // only v107 is supported" v( Z0 a6 w; i" [( X+ C$ f! D3 ^
            return TRUE;
* b' k. k7 ~2 b: w' a3 U        default:8 z) a7 @6 o6 `& I& z9 Y+ d* Z* L
            return FALSE;
2 b/ I& `+ R+ u6 t0 s    }* {9 x/ i% Z0 [8 s
}</P>
! D, [/ f- I- N6 O# I3 u) t
7 E4 C1 H# g! K; p7 L<P>, H3 ^1 k8 i  G
//-----------------------------------------------------------------------------
& r2 {. e! u2 V& t, _$ c- s# t7 F// Name: / \$ v3 u, ^- O* {
// Desc:
( y/ R4 a" _2 v. N- U9 k//-----------------------------------------------------------------------------# X  b1 q& d1 T+ W+ r3 [
void CMazeServer::HandleUnknownPacket( DWORD dwFrom, ClientPacket* pClientPack, DWORD size )
4 z4 v* `& y8 U{( X" b$ v) B4 Q8 E2 A
    if( m_dwLogLevel &gt; 1 )5 E& b4 _( m) \
        ConsolePrintf( SLINE_LOG, TEXT("ERROR! Unknown %d byte packet from player %0.8x"), size, dwFrom );</P>
: \; p) e7 h5 p! Y$ l<P>    m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );
! W* G/ v% ~+ g. o* G+ _7 K}</P>
+ l) A+ O8 ~+ w# H  l1 _: o2 `+ \8 Z  S. A. Q& K, Q
<P>" D) [* e3 i0 G. q1 l
//-----------------------------------------------------------------------------
+ ]$ P* l* O, `* W  S// Name: 8 t; Z7 r: L: _1 T! Y
// Desc: # U" _7 t$ j# W
//-----------------------------------------------------------------------------8 |, o9 ?. b0 R5 p% F2 j
DWORD   CMazeServer::IDHash( DWORD id )
8 ]- w5 C: Z: B0 M* ]{
7 k6 E5 H& ~! j- S    DWORD   hash = ((id) + (id&gt;&gt;8) + (id&gt;&gt;16) + (id&gt;&gt;24)) &amp; (NUM_ID_HASH_BUCKETS-1);& V+ O' Y' Q* p' z4 z( w
    return hash;: K5 a# f. |" ~! ]: ^# t( m
}</P>1 R9 h# Y- G5 j

+ ?9 w! Y3 q; @1 W: Q5 y. O<P>$ {  o0 S6 h' B2 j. M
//-----------------------------------------------------------------------------
  w1 |# G: ?: |2 e. j// Name:
7 \( X/ P, I) A1 x! ]// Desc: $ s8 Q; n8 `' N4 ?" G( u5 ]
//-----------------------------------------------------------------------------
3 g# d6 P& l, T* |void CMazeServer::RemovePlayerDataID( PlayerData* pPlayerData ); f! e4 X3 F4 U# y- U8 b. p1 J
{& }: f. ]" \1 M
    // Hash the ID to a bucket number
! P4 v' K; p" L    DWORD   bucket = IDHash( pPlayerData-&gt;NetID );</P>
7 j+ ?/ a/ m, ]% h' B& ]/ k<P>    // Lock that hash bucket
) I" M3 ]7 \1 f- R2 I    const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;
* V  T6 ~6 c8 D4 F3 R4 M5 s& p    m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>2 M, S: L& _) e( e
<P>    // Loop though players in bucket until we find the right one
& {2 K. O9 [- d4 R1 Y7 Q7 F    PlayerData* pPt = m_pstIDHashBucket[bucket];
5 J( p6 }# ^( p1 O( G1 v    PlayerData* pPrev = NULL;* n' ?1 g% R+ s/ n& }/ e
    while( pPt )
5 I. k/ T7 n' [# b9 J2 x' p2 S    {
) _6 k. Y" ], g, Q# [        if( pPt == pPlayerData )- c& q3 L& Y* e  U# y2 B' U2 z, `  M2 K
            break;: @6 |; \8 }: R6 D& e: O( A' r4 X
        pPrev = pPt;' w' r# w) Q4 Y% q/ e, l7 D
        pPt = pPt-&gt;pNextInIDHashBucket;
  f- ?  p( T6 ?. Q! b$ k' B5 N' Z    }</P>6 v/ H) }6 A. P6 m; q- o# i8 j
<P>    if( pPt )% O! t, d" O' `$ W# m# W$ O* R
    {  s7 `4 \3 D! S
        if( pPrev ), D& a2 d( H( b& L) |
            pPrev-&gt;pNextInIDHashBucket = pPt-&gt;pNextInIDHashBucket;3 n! \7 I4 o2 W4 ~4 l  G3 ]: R6 `
        else9 P, ?! f' z0 j
            m_pstIDHashBucket[bucket] = pPt-&gt;pNextInIDHashBucket;- k: W+ {7 ?  j% M9 p
        pPt-&gt;pNextInIDHashBucket = NULL;
2 R& @& o2 g" \; r# O    }</P>
# d! H" h0 L" k: N; H<P>    // Unlock the hash bucket2 l8 p5 X( h: ?# j- ~
    m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();& b; n9 o# W" p$ [4 Z* m
}</P>
  ]1 t+ @' ?0 \, S9 H8 d* w# q" h- Y5 ?, E( m9 T% O2 a
<P>
3 ?. M, g4 V6 `//-----------------------------------------------------------------------------0 q3 q& F! W# O) |% ^
// Name:
$ Z( r0 e" I  k/ j% _// Desc: * ~3 c  u' B! x) Q/ V) @0 T- K
//-----------------------------------------------------------------------------
. \# }) v1 o( i4 J1 m& Q3 M; bvoid CMazeServer::SetPlayerDataForID( DWORD id, PlayerData* pPlayerData )* h1 A3 i- W2 w. ]7 J! s5 P; n
{
" ?* U" e$ f' V8 k5 ?8 `& V    // Make sure this player isn't added twice to the m_pstIDHashBucket[]; u) a8 [* r) M7 a2 g6 O7 U
    // otherwise there will be a circular reference
/ j7 _) b5 N, I, X) [    PlayerData* pSearch = GetPlayerDataForID( id );/ X) b2 `: z* E7 W) w% ]7 }
    if( pSearch != NULL )
: k) P: r0 k8 [2 _) a: j        return;</P>' D# n1 j1 |  b5 w9 v
<P>    // Hash the ID to a bucket number& D. E* _2 z2 ^1 ^9 U# T% K
    DWORD   bucket = IDHash( id );</P>* ^* z6 J) i9 w" k6 R7 X% O
<P>    // Lock that hash bucket
* z8 J4 a( l/ U0 `    const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;/ |, m  e! |1 S2 b5 v% n2 z3 }
    m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>
5 J  i& ^# v4 K" I" T2 m<P>    // Add player onto hash bucket chain
) |8 q) v5 A8 q: ]3 W( _; ~$ w    pPlayerData-&gt;pNextInIDHashBucket = m_pstIDHashBucket[bucket];
+ V( t2 H# E% e: x    m_pstIDHashBucket[bucket] = pPlayerData;</P>
, P) T2 R, b) k8 ~" u% k<P>    // Store net id in player+ s0 h1 p8 F: ^) z1 k
    pPlayerData-&gt;NetID = id;</P>; L  n" N: o! g: \
<P>    // Unlock the hash bucket, M) X. U. l+ B4 C: |" ]& {
    m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();
5 k% B. E% P; K9 Y! b5 ]}</P>2 F9 `( N3 O( d

$ }' P4 o- F) \5 l3 U<P>9 e! |1 D4 u/ d8 ]3 q( W7 s. N' `
//-----------------------------------------------------------------------------1 D* o* Z2 X3 p! w- a& F
// Name:
7 j& T" a) _) T$ _% P- [% z/ Q- ?// Desc:
( }7 k( F5 _0 S% f% S% v6 X3 J0 z, O//-----------------------------------------------------------------------------( v3 [) Z2 m$ R. k# e$ y
PlayerData* CMazeServer::GetPlayerDataForID( DWORD id )& s- ^( W: q, u
{0 y6 [* C2 U: c8 f0 @4 T8 o
    // Hash the ID to a bucket number- O3 E5 I/ y& R, @
    DWORD   bucket = IDHash( id );</P>
7 j# w; @% Z& E  A, e- {3 L1 |<P>    // Lock that hash bucket
/ O. s7 A- i4 P- D" V! u7 D/ B    const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;
; G: n* N1 J' _3 ~7 z# O5 V& C    m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>' a; r, O4 }0 j1 Z( }7 j" M
<P>    // Loop though players in bucket until we find the right one
0 m$ w' I1 I7 e0 W# i8 [8 I    PlayerData* pPlayerData = m_pstIDHashBucket[bucket];
& L8 w7 H: W& X; X4 l1 ~. C    while ( pPlayerData )# ]; ~3 V& k, L0 S! D( m
    {/ x2 _5 O/ J1 i" c& V, d6 z: C; X
        if( pPlayerData-&gt;NetID == id )( e) h! B7 F3 ~, W* \- N5 ~
            break;
; u+ I3 ^1 u0 |, P1 f, i        pPlayerData = pPlayerData-&gt;pNextInIDHashBucket;% E* }2 E6 K" }' N: {% ~- i2 `
    }</P>
9 S* G5 E5 W; k) ~<P>    // Unlock the hash bucket
0 p2 Y, ]; U$ v: j+ m0 G    m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();</P>6 }3 Y! S; `/ }" I: p% s3 A
<P>    // Return the player we found (will be NULL if we couldn't find it)+ e5 [+ E; K8 [) t
    return pPlayerData;$ {' U- M! S1 `" ~( H- s3 u/ ~  t9 h
}</P>- a, Z% o9 y( T6 P5 H7 F
. P5 i: Q. Q' C# H3 s, a9 w
<P>
4 ?( a3 U- p! |+ q//-----------------------------------------------------------------------------9 P6 \) T5 [+ f* t4 m- m1 ~) N" @9 q
// Name:
* P  X/ D% J  v9 }6 S( R7 p// Desc: calls DisplayConnectionInfo for each connection in a round-robin manner
" u& n; d8 |& L3 y//-----------------------------------------------------------------------------
# _6 f/ E7 F2 U0 {; Zvoid CMazeServer:isplayNextConnectionInfo()4 d6 X* `4 p6 }1 |1 H! j4 q, u
{
. ?5 k6 z6 V* K" `    if( m_pNet )
" G4 u, E6 v, n    {$ X2 y4 }: h, K
        // Find the player that was displayed the longest time ago, and display it.
" K$ \5 C8 \( R' r. {5 {. Q# d        FLOAT fCurTime = DXUtil_Timer( TIMER_GETAPPTIME );. {% f5 u+ M% w* w& Q* _( z
        PlayerData* pOldestPlayerData = NULL;$ Z0 H7 `2 E2 w7 F
        FLOAT fOldestTime = 0.0f;</P>
/ X9 p9 k! F1 V/ Y% g<P>        m_PlayerDataListLock.Enter();</P>
+ j+ H( s, r% i4 X<P>        PlayerData* pPlayerData = m_pFirstActivePlayerData;* c) H5 l& D( ?; A2 a" v* D8 o
        while ( pPlayerData )
( T8 |  {* v" Q. c& L: L        {
" k3 m; M1 j8 k# F. N( E$ O  p            if( fCurTime - pPlayerData-&gt;fLastCITime &gt; fOldestTime ), @( `% y% @4 R! D, P
            {2 I% O6 @: a) ?+ R0 j8 D
                fOldestTime  = fCurTime - pPlayerData-&gt;fLastCITime;$ M# t9 }5 A8 g! o/ N' ?6 Z8 Q2 a
                pOldestPlayerData = pPlayerData;9 h; L5 W/ A6 o" e( n% j
            }</P>
1 `* v% D/ n( ]% h/ G<P>            pPlayerData = pPlayerData-&gt;pNext;8 f" E$ r% N; |$ `5 l2 }
        }</P>
8 w/ M+ G% x2 F; @<P>        // Display the player with the oldest CI field, and update its CI field.
' f  V2 Y, `" D        if( pOldestPlayerData )+ ]6 @5 e$ W) v+ ^. I
        {& k* O% u- [. t
            ConsolePrintf( SLINE_LOG, TEXT("Displaying connection info for next player") );; P  v& {  @2 }6 h+ m# ?: y
            DisplayConnectionInfo( pOldestPlayerData-&gt;NetID );1 x  r7 [9 g5 ^0 S+ N4 t/ r4 b
            pOldestPlayerData-&gt;fLastCITime = fCurTime;
0 Y7 D8 A& H) G; M        }
4 p2 V% r, S! t3 z% U; I. o" @0 O        else
4 @- i; B4 L4 ^. k: k        {* i( Q* H0 S- |
            ConsolePrintf( SLINE_LOG, TEXT("No players found") );
, i9 a, t% \8 Z$ N' b! ]        }</P>
$ B- G) v* }% |5 ]9 ]# I( n) j7 q. A<P>        m_PlayerDataListLock.Leave();
$ m5 j: X3 G! n5 s* C! v    }
) W* o! `  U8 e( I4 d}</P>
1 R- {! A0 V7 J- V
1 o& ~' W6 a# @" \% B4 M<P>6 z8 U1 z8 N1 K
//-----------------------------------------------------------------------------* A7 W$ r5 t! w+ U/ h
// Name: % n% N- w) n5 C/ B
// Desc: 6 x  g1 {, u# y! Q) G; Q
//-----------------------------------------------------------------------------7 V0 l9 h* r3 f. ^+ N" X
void CMazeServer:rintStats()/ k! I0 H) S! u5 [' G: X
{+ N: s4 `" p& R6 h1 |
    ConsolePrintf( SLINE_LOG, TEXT("Thread count: Active=%d Avg=%.2f Max=%d"),
6 ?& V) G6 u5 x6 W- X  p' p8 W                                    m_wActiveThreadCount, m_fAvgThreadCount, m_wMaxThreadCount );, M6 v% l) L, U4 [
    ConsolePrintf( SLINE_LOG, TEXT("Thread Time: Avg=%.4f Max=%.4f(s)"),; y$ c2 ]* H, u7 \6 {) E
                                    m_fAvgThreadTime, m_fMaxThreadTime );. x3 d0 T" i* J
    ConsolePrintf( SLINE_LOG, TEXT("Players online (not including server player): %d"), m_dwPlayerCount );
7 b9 W  s2 J# T" X    ConsolePrintf( SLINE_LOG, TEXT("Peak player count: %d"), m_dwPeakPlayerCount );6 g9 l$ V0 m6 e1 e' s/ O$ a
}</P>, Z" i% v1 ~6 x- |
" `8 P/ `, u5 R) F) t2 x
<P>
0 G& D. d) ]  f- e) ]//-----------------------------------------------------------------------------
  L1 D! h4 u6 F8 @+ ?6 B0 r# O$ N' b// Name: 0 C; G, i% V* [$ P: u+ q! N$ _
// Desc: ! V  S& o2 N' D
//-----------------------------------------------------------------------------
& @: [0 Y* N6 X% Z! w: l9 Cvoid CMazeServer:isplayConnectionInfo( DWORD dwID )
- Y  \/ r! y, w# \' ?{5 ]* j# m  l# W0 x" e) Y8 R3 H
    TCHAR strInfo[5000];
& [$ v# Q* p) E0 F6 ?6 e    TCHAR* strEndOfLine;( \8 |4 }$ i+ J* n# `0 z2 x
    TCHAR* strStartOfLine;</P>
+ H" M  F3 X- W4 t: g<P>    // Query the IOutboudNet for info about the connection to this user2 \+ N( z4 ]0 }+ v/ @7 q9 I4 A
    m_pNet-&gt;GetConnectionInfo( dwID, strInfo );</P>& C1 |& M$ Q+ R* @+ i
<P>    ConsolePrintf( SLINE_LOG, TEXT("Displaying connection info for %0.8x"), dwID );
- ~5 q+ @$ l: L. r' @    ConsolePrintf( SLINE_LOG, TEXT("(Key: G=Guaranteed NG=Non-Guaranteed B=Bytes P=Packets)") );</P>2 Y( W' a6 z# N* \, ~
<P>    // Display each line seperately
0 d5 A. W6 j& V- j* t( r& G. }2 u    strStartOfLine = strInfo;
! Q! {* e5 [  P- P, z* P+ S    while( TRUE )
: R/ y# F/ @" x/ N! y/ J. I" I    {5 K! Z# M) {; v; v
        strEndOfLine = _tcschr( strStartOfLine, '\n' );2 Y1 L! ~# T( Z& [' Y6 L
        if( strEndOfLine == NULL )
5 z  ]: u: I' F" Y0 K            break;</P>2 q8 T- U4 \6 P
<P>        *strEndOfLine = 0;
8 q* {6 X1 K8 K6 T( [- Z0 A8 R        ConsolePrintf( SLINE_LOG, strStartOfLine );1 t* H7 \/ Y/ C1 }
        strStartOfLine = strEndOfLine + 1;
" h+ _; ~% x8 O    }
* w: x& E" S. |* I}</P>) }5 z8 ]4 F7 |2 K
7 T; X1 p. t3 S
<P>3 ^) j/ Q, B4 k& p
//-----------------------------------------------------------------------------
1 _0 k! l+ W; v// Name: . h/ l# k. G% }: Q) E, l: O7 R
// Desc:
" a' m8 E7 P/ ^8 X; S# ]2 A, f//-----------------------------------------------------------------------------
) G! R7 C( s5 ^1 w! e4 V0 F9 FHRESULT CMazeServer::SendPacket( DWORD to, void* pData,
0 |5 B  P$ U& S& N; V                                 DWORD size, BOOL reliable, DWORD dwTimeout )
* A$ Y0 \& x- r& f9 J1 R' [2 [8 s; r{
) `9 |% t# X" B- |0 ?    // Chance of forcing any packet to be delivered reliably( ^' ?2 x! Q# ]8 n9 [
    if( m_Rand.Get( 100 ) &lt; m_dwServerReliableRate )4 w: \- H5 e& b+ r4 l5 p- a
        reliable = TRUE;</P>( {$ ?$ }# g2 |+ [4 q$ f
<P>    return m_pNet-&gt;SendPacket( to, pData, size, reliable, dwTimeout );  f3 ]2 b* E$ `* o8 T3 u3 k+ {' [
}</P>- f3 w/ `$ n9 Q0 V5 @* A* d

/ y, r1 [1 e- N# Z6 h<P>$ U7 I3 @( x2 ~
//-----------------------------------------------------------------------------
6 K2 ?, P- P7 b8 {// Name:
' M2 J+ {3 e1 A7 ?// Desc:
+ i! Z2 T: p* @//-----------------------------------------------------------------------------+ m) Y. N9 B- N
void CMazeServer::SendConfigPacketToAll( ServerConfigPacket* pPacket )
3 m8 s" j  c" C4 n  x- O! d{
4 O6 p% j9 A, t$ V) X8 x" H' q5 w    // If we're up and running, then send this new information to all clients2 q( |" F% p3 U; Q1 A; l; o
    if( m_pNet ). ?  G/ n5 P0 e0 L+ W3 X
    {
) @( A2 e+ S/ N3 x4 v$ H3 f3 i# X        //Use the AllPlayers ID1 a- x5 Z' e# N! E( V) o
        SendPacket( DPNID_ALL_PLAYERS_GROUP, pPacket, sizeof(ServerConfigPacket), TRUE, 0 );& S" |: G% W4 C
    }
  t- S/ E: W% Z& D% t1 `; r$ i: n}</P>
7 }: X5 Z9 Q  x: B. L1 Q$ s3 H# V- @9 }6 V8 T: q2 U
<P>, U4 x+ g* j5 {: M2 K
//-----------------------------------------------------------------------------
. B# e% {. F, s3 Q  n* T7 p0 t0 M// Name:
8 X1 m* W. P' t5 m& V" y2 u// Desc:
6 ^0 ?/ K! x7 B0 c4 g1 Q, ?//-----------------------------------------------------------------------------5 F7 d4 s; K/ ~) }; @( ]1 X, W; p
void CMazeServer::SetClientReliableRate( DWORD percent )# }' [" Z# M6 [9 |: y" ]( a
{6 h; m6 W3 I! S4 Z+ E
    // Update client config, and build packet containing that data
; }* M" h$ L) p' _7 h    m_ClientNetConfigLock.Enter();
( Z( m; y, R! E2 b    m_ClientNetConfig.ubReliableRate = BYTE(percent);
) v. Q# m9 X) m5 C3 W; v, |7 G( i    ServerConfigPacket packet( m_ClientNetConfig );
9 N/ N2 ^( O/ c0 ~$ \    m_ClientNetConfigLock.Leave();</P>  C: i# D& w' z- p! G) e
<P>    SendConfigPacketToAll( &amp;packet );
# w8 j, r( }: ~7 P* b! v}</P>
* [. X! r7 r1 i' u8 A1 k; U  g; t7 t
<P>2 J' i. j- Y2 L0 E/ L& F6 A
//-----------------------------------------------------------------------------/ ]8 K# i7 Z. v: `4 ~
// Name:
" [3 L! ^) m8 Q# y// Desc: 1 l2 _5 A) F5 q2 ^8 ^
//-----------------------------------------------------------------------------
/ h  s  t2 q& `* _, h6 @void CMazeServer::SetClientUpdateRate( DWORD rate )9 y3 @/ f: t2 A# Q3 y4 s( n
{
% x5 m/ W3 G/ F# P0 H    // Update client config, and build packet containing that data
1 Q9 k: ~' a# U0 g% q    m_ClientNetConfigLock.Enter();) r4 x" x; ?% ]3 ^# g
    m_ClientNetConfig.wUpdateRate = WORD(rate);
  b- W/ d. h' z6 P9 u* h  r4 W    ServerConfigPacket  packet( m_ClientNetConfig );
! C+ f9 I' p1 \& T/ X    m_ClientNetConfigLock.Leave();</P>/ e7 w/ N+ r. }8 R7 J
<P>    SendConfigPacketToAll( &amp;packet );# N$ S  ^' N3 ^
}</P>3 V0 a# R8 [* L, W0 K
6 ~7 q3 ?6 R. P, h6 K
<P>2 D. x; B2 T  H& S8 W! |% l- n
//-----------------------------------------------------------------------------" H  i# N5 I! U8 ~( @
// Name:
$ a5 u# R+ U6 R$ w, V; |// Desc: & x9 f3 `; o6 C9 p$ ?0 X; U( z
//-----------------------------------------------------------------------------5 g# H( M+ {7 `3 B5 ?
void CMazeServer::SetClientTimeout( DWORD timeout )
6 v6 J5 g3 p9 D{
- M# x  m0 X4 P7 [    // Update client config, and build packet containing that data- }4 {* |+ L. n! Q+ g! l
    m_ClientNetConfigLock.Enter();8 q6 C$ w4 [% X, M
    m_ClientNetConfig.wTimeout = WORD(timeout);5 W6 e+ L1 h9 w2 V$ i) p
    ServerConfigPacket  packet( m_ClientNetConfig );
# @2 a5 ?' k! x- z    m_ClientNetConfigLock.Leave();</P>
1 `3 s* _1 `, p/ c6 u<P>    SendConfigPacketToAll( &amp;packet );
- j7 D, y! o: K$ \( i}</P>: b& J" e5 B: n% G0 e
8 X! f- S4 d. f+ @
<P>
/ t6 |% g! s, X6 E" ^//-----------------------------------------------------------------------------
: d0 N, z2 u9 x# s  A1 m( e// Name: 0 Z- @, z. i3 G, }
// Desc:   J+ N4 a: q" k1 p
//-----------------------------------------------------------------------------
. E6 M5 I& S. ?/ A5 F: }0 |0 Avoid CMazeServer::SetClientPackSize( DWORD size )/ Y* O! d2 j1 E  ]+ z
{
) Y, J. {* F# V1 A; W. M; Y! Y    // Update client config, and build packet containing that data
1 \4 ?1 y* t  W1 h# q3 k    m_ClientNetConfigLock.Enter();/ q7 \4 g1 k# X6 B9 F$ M0 @' x' e
    2 Q( ~! A$ S7 d
    m_ClientNetConfig.ubClientPackIndex++; //Increase index and verify location in array./ i% h* X6 P9 z  K, P0 T
    if(m_ClientNetConfig.ubClientPackIndex &gt;= PACK_ARRAY_SIZE)   
" y; E  @7 ]" N' h6 \        m_ClientNetConfig.ubClientPackIndex = 0;</P>7 o( z4 ]. r* q! H
<P>    m_ClientNetConfig.wClientPackSizeArray[m_ClientNetConfig.ubClientPackIndex] = WORD(size);1 j* g" S8 \3 m9 z9 _$ {
    ServerConfigPacket packet( m_ClientNetConfig );
6 S& m& u9 `3 s- Q; o    m_ClientNetConfigLock.Leave();</P>: \) L$ m: S$ R! A/ b3 K* n/ e
<P>    SendConfigPacketToAll( &amp;packet );
. h$ b7 Q& H9 t  [7 H6 U}</P>
5 T% A% v$ y. z. r) l2 p
/ h' V& J- s* g" d- M' b# [% ?+ \<P>' H$ M5 |0 Y9 {
//-----------------------------------------------------------------------------
0 J" X0 T  L. H8 u// Name:
1 B  m8 Y; C; }0 m% @// Desc:
! X: K3 J% l* ^  p//-----------------------------------------------------------------------------
* ]. ~: i; @/ L- L/ ^void CMazeServer::SetServerPackSize( DWORD size )
6 S2 i! j- s) l0 ^  N! k{6 i) e" r( O8 `/ V; b
    // Update client config, and build packet containing that data3 S& f1 F7 D# b; V9 Q
    m_ClientNetConfigLock.Enter();. f5 ?* j  U$ e: U
    ' w4 K1 y& S. w1 T
    m_ClientNetConfig.ubServerPackIndex++; //Increase index and verify location in array.
. B1 Z* I5 c5 u' }/ Y8 d    if(m_ClientNetConfig.ubServerPackIndex &gt;= PACK_ARRAY_SIZE)     t, g0 z- `4 K% t) K* K
        m_ClientNetConfig.ubServerPackIndex = 0;</P>; n9 e; d6 t4 \% ~
<P>    m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex] = WORD(size);
# t5 e5 ^3 O( R7 X7 {" w    ServerConfigPacket packet( m_ClientNetConfig );* c8 R" t& L% g/ V7 F7 |' S" p
    m_ClientNetConfigLock.Leave();</P>
& P! q4 B& }( w7 p<P>    SendConfigPacketToAll( &amp;packet );2 V$ w' F) {2 }# B, p5 {0 @
}</P>% E8 B- |* p. U& a& K0 k
<P>0 a! t; a1 r5 }6 v
//-----------------------------------------------------------------------------
$ N3 b2 z" `& Z9 h! B+ R! \7 N% H// Name: , z; k! s! Y/ a1 i
// Desc: . F, y7 i# Q, q; b- K
//-----------------------------------------------------------------------------8 ?3 }- c" c8 ?' V1 r2 A7 b, c
void CMazeServer::SetClientThreadWait( DWORD dwThreadWait )
( Q: @2 B; [& y7 ?{  i* n' C( z) s& _  |1 g
    // Update client config, and build packet containing that data
* S2 U' B& `2 h" Z  \6 b0 R2 C    m_ClientNetConfigLock.Enter();9 M) I4 t0 Z8 q( x" A; U9 B
    9 `, _9 P8 ~4 i
    m_ClientNetConfig.dwThreadWait = dwThreadWait;
1 M' j/ n$ z( Z" r5 o3 D6 e- w    ServerConfigPacket packet( m_ClientNetConfig );. P9 h9 i" r  ]' V: E
    m_ClientNetConfigLock.Leave();</P>
  M1 Z6 d- ?" p$ G* X3 ~0 m<P>    SendConfigPacketToAll( &amp;packet );
  G7 F" v0 y/ \% z0 y- Y; T}</P></DIV>




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