QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 4196|回复: 0
打印 上一主题 下一主题

[分享]MazeServer源码示例

[复制链接]
字体大小: 正常 放大
ilikenba 实名认证       

1万

主题

49

听众

2万

积分

  • TA的每日心情
    奋斗
    2024-6-23 05:14
  • 签到天数: 1043 天

    [LV.10]以坛为家III

    社区QQ达人 新人进步奖 优秀斑竹奖 发帖功臣

    群组万里江山

    群组sas讨论小组

    群组长盛证券理财有限公司

    群组C 语言讨论组

    群组Matlab讨论组

    跳转到指定楼层
    1#
    发表于 2005-1-31 11:52 |只看该作者 |正序浏览
    |招呼Ta 关注Ta
    <DIV class=HtmlCode># W9 @- S  `) F( S/ V
    <>// File: mazeserver.cpp
    & O/ }* I: R0 F  a+ U//: B% h" \4 k3 ]2 j- _
    // Desc: see main.cpp
    " g6 U) f) c8 v/ q$ t3 v( {; n/// ?2 g! c" m7 ~5 c  m7 B+ j/ F
    // Copyright (c) 1999-2001 Microsoft Corp. All rights reserved.
    & K" e& q, G  a4 _4 J//-----------------------------------------------------------------------------
    ' a# Y% p- X0 q# _  l#define STRICT
    1 S" b" T9 Q( ^' p- H% Q#define D3D_OVERLOADS4 U/ X: B$ }0 W, l& [3 W
    #include &lt;windows.h&gt;* D( B! r* n! r$ X& _) F
    #include &lt;d3dx.h&gt;
    9 ]- N; c; [  T6 {3 W* T#include &lt;stdio.h&gt;* R% b* x; D# |8 l- ?
    #include &lt;math.h&gt;
    3 F  J% d/ P+ `+ ?#include &lt;mmsystem.h&gt;( Z& K& F* |: G! P) ^+ h, N' I7 y" ~
    #include &lt;dplay8.h&gt;* j, q) j: N- x0 a2 ~  A
    #include &lt;dpaddr.h&gt;
    8 I2 l' J' C! e6 c#include &lt;dxerr8.h&gt;5 ^$ g9 i/ h5 K! l" e
    #include "DXUtil.h"% S  t. o- P" K4 J7 I
    #include "MazeServer.h"2 D$ o! O& [7 ~9 F- w
    #include "ackets.h"5 ^8 N) K" _- Y" S7 c
    #include "Maze.h"
    , B8 [7 Y' {' Z* A/ u% d! A# o#include &lt;malloc.h&gt;
    : }2 S) x8 l" U' Q#include &lt;tchar.h&gt;</P>; Y3 x; e8 V5 L' L% O7 T
    + C, X$ }) I2 ?! J$ u, u  Q
    <>//-----------------------------------------------------------------------------# |* E$ r6 C1 m& L
    // Name:
    6 ]" G( n6 l% {1 A// Desc: 9 w% L/ X8 j/ m8 n7 `3 z
    //-----------------------------------------------------------------------------
    . s& r) x3 z4 gCMazeServer::CMazeServer()
    + d% x3 D, O! ]/ {. N0 U{
      c. ^* {% \8 B, r  M    m_dwPlayerCount         = 0;
    + f1 G  i8 f1 k3 V' x' \$ L    2 G  d4 {) T  g- r: }
        m_wActiveThreadCount   = 0;0 s0 t8 w' D& \4 w3 c  X
        m_wMaxThreadCount      = 0;
    9 c+ |! I! B- e% d: g4 i    m_fAvgThreadCount      = 0;
    ) v3 H: V# s' k) A; `0 W5 j    m_fAvgThreadTime       = 0;
    - E- q- W: m' h0 J3 K( l: T, k    m_fMaxThreadTime       = 0;</P>
    % [$ ]; e" c2 E<>    m_dwServerReliableRate  = 15;
    2 N+ r$ I) S$ N' w+ I+ Q# ]" |    m_dwServerTimeout       = 150;5 ]1 d7 y5 ]0 ]' f
        m_dwLogLevel            = 2;  ]7 k4 A( T; i# \# M* l
        m_pMaze                 = NULL;</P>
    $ Q) X5 D: v: w<>    m_ClientNetConfig.ubReliableRate = 15;: H% s# o% ?: }# ]' @
        m_ClientNetConfig.wUpdateRate    = 150;9 r. I. d% b6 x2 p0 l5 T
        m_ClientNetConfig.wTimeout       = 150;</P>3 f3 \- K9 E% b" b" n. I& }
    <>    m_ClientNetConfig.dwThreadWait = 0;</P>
    4 ]: t, J( ~0 g3 G- ?7 `6 g<>    m_ClientNetConfig.ubClientPackIndex = 0;5 P0 }9 r8 `1 p1 E8 U
        m_ClientNetConfig.ubServerPackIndex = 0;( Q+ s$ K% q6 e6 D  S
        for(WORD x = 0; x &lt; PACK_ARRAY_SIZE; x++)$ o8 b- h: C1 C" L: X6 R
        {. d3 G: J. ]9 `) G. z9 Y: l
            m_ClientNetConfig.wClientPackSizeArray[x] = 0;% o* W3 f5 N' S
            m_ClientNetConfig.wServerPackSizeArray[x] = 0;
    ( y1 W1 T, U3 d- R* v- f    }
    / D! b! q( d* K0 {' |}</P>; q+ l* E. v9 c
    + @, n+ Y0 F  ]* ^& j6 Z* \
    <># N- o3 J, v" D$ _& V
    //-----------------------------------------------------------------------------
    / u  p/ }/ r4 }// Name: & N1 `2 b" Q) c+ w1 n
    // Desc: 2 ^8 l' V* ~  e. y" ^6 x
    //-----------------------------------------------------------------------------
    " S8 {/ I7 X% a7 q9 A( XHRESULT CMazeServer::Init( BOOL bLocalLoopback, const CMaze* pMaze )
    + y5 U0 s; Y- O& A) d3 _7 u{, R' b5 g7 ?4 W- ]" u  O. i; M8 ?
        m_bLocalLoopback = bLocalLoopback;. V# }% h  r5 @
        m_pMaze = pMaze;6 {$ z$ C5 F2 f
        if( m_pMaze == NULL )5 e9 Y3 H2 X7 o7 F
            return DXTRACE_ERR( TEXT("aram"), E_FAIL );</P>$ ~8 U: ]* z0 z% O6 w: I
    <>    // Grab height and width of maze
    0 [! T* |" H) J+ h$ Y; Z. k0 ^    m_dwWidth = m_pMaze-&gt;GetWidth();$ u+ E( n! r1 b$ c: o  g0 r1 F
        m_dwHeight = m_pMaze-&gt;GetHeight();</P>' P3 w: ~7 N5 {5 w: c# i
    <>    m_ClientNetConfig.dwMazeWidth  = m_dwWidth;# E$ b- S: ^6 L" R* n# ]
        m_ClientNetConfig.dwMazeHeight = m_dwHeight;</P>6 n/ p3 x7 s1 ?' t$ E) ]2 j
    <>    // Validate size. Must be a power-of-2 times LOCK_GRID_SIZE. Compute the shifts.
    " Q/ L( ~9 a4 \- Q% x! P; c  Z3 f5 e    if( m_dwWidth &gt; SERVER_MAX_WIDTH || m_dwHeight &gt; SERVER_MAX_HEIGHT )
    4 o4 B; }4 V5 T# S8 b        return DXTRACE_ERR( TEXT("Maze height and width need to be less than 128"), E_INVALIDARG );
    * [- a; Y& z2 c' Z6 e- x    if( (m_dwWidth % LOCK_GRID_SIZE) != 0 || (m_dwHeight % LOCK_GRID_SIZE) != 0 ): E8 g( p# }; S9 c: L" y& F8 `
            return DXTRACE_ERR( TEXT("Maze height and width need to be divisable by 16"), E_INVALIDARG );</P>$ z2 o& v( c6 l+ s3 ^
    <>    DWORD scale = m_dwWidth / LOCK_GRID_SIZE;
    % ~8 a6 h! m; P2 o& b    m_dwMazeXShift = 0;
    + Y" p: G) ~" r% F, y9 e    while ( (scale &gt;&gt;= 1) )
    ) x3 q1 _! e, e        m_dwMazeXShift++;</P>
    . F8 [# h8 ~* H. A; I<>    scale = m_dwHeight / LOCK_GRID_SIZE;8 B( M( H# ?4 g2 l) }* G4 i
        m_dwMazeYShift = 0;% @* f( f6 Q$ B. l
        while ( (scale &gt;&gt;= 1) )
    ; J& v$ n- \1 r        m_dwMazeYShift++;</P>! _& {+ G4 y" Q5 Q8 D# M. T. f
    <>    if( ((DWORD(LOCK_GRID_SIZE) &lt;&lt; m_dwMazeXShift) != m_dwWidth) ||6 K3 x% g5 f! [2 `  Q
            ((DWORD(LOCK_GRID_SIZE) &lt;&lt; m_dwMazeYShift) != m_dwHeight) )+ {; c5 M4 J( T- D" i8 @
            return DXTRACE_ERR( TEXT("Maze height and width need to be power of 2"), E_INVALIDARG );</P>
    7 M; Z& y1 f, t1 r$ p! C<>    // Initialise the player list
    " h! _# h# x2 }$ e/ H    ZeroMemory( m_PlayerDatas, sizeof(m_PlayerDatas) );. x. X/ s2 q4 y' l  C' b, ^6 S. d
        m_pFirstActivePlayerData = NULL;2 ?7 m; ]+ E, Y4 k" O5 v, k
        m_pFirstFreePlayerData = m_PlayerDatas;% y9 w7 }  n- |/ Y) u
        for( DWORD i = 1; i &lt; MAX_PLAYER_OBJECTS-1; i++ )) E* W+ M- S5 P1 m
        {
    $ b9 Y, ?$ e+ C1 r: q# X4 H        m_PlayerDatas.pNext = &amp;m_PlayerDatas[i+1];
    " L6 x' \* L0 o9 e8 d5 f7 c9 j        m_PlayerDatas.pPrevious = &amp;m_PlayerDatas[i-1];: R. C8 ~! Q; ~. D  J
        }</P>
    7 P5 \) U9 ^. M( P' q<>    m_PlayerDatas[0].pNext = &amp;m_PlayerDatas[1];% l; u  J% L0 }( M6 C# M% W" ]# K
        m_PlayerDatas[MAX_PLAYER_OBJECTS-1].pPrevious = &amp;m_PlayerDatas[MAX_PLAYER_OBJECTS-2];
    1 ^2 u) j) x/ Y* L: Q" F, d    m_dwActivePlayerDataCount = 0;' k: x0 `; X/ U2 V
        m_dwPlayerDataUniqueValue = 0;</P>
    & ?5 [; K/ C4 Q1 f# L/ o" s. n<>    // Initialise the cells
    , [5 H0 e, w+ X    ZeroMemory( m_Cells, sizeof(m_Cells) );
    ! v6 k2 L( ~2 Z; V1 g8 t+ p! n$ M    ZeroMemory( &amp;m_OffMapCell, sizeof(m_OffMapCell) );</P>
    # i7 V; `/ p0 A' m1 X6 w# `( T<>    return S_OK;
    # u: [: w! T6 d}</P>' R' I- f: v' q* L

      M: R( y* V/ o5 G& z6 I- J<>. {) t6 H4 M" j* H9 s* z# A- K
    //-----------------------------------------------------------------------------3 m' V! j( T5 s5 R+ o+ ?. M
    // Name:
    6 \3 ^' G- F5 Q// Desc: ' P1 n. N9 N4 ~% M2 Y% Z
    //-----------------------------------------------------------------------------  P) q. i0 P" d4 J6 J* u8 P
    void CMazeServer::Shutdown()7 _9 g2 K5 w! z) X, U/ d
    {9 b: t+ j: b7 J! Q6 |% u
    }</P>
    2 C# r  M( Q% I6 w
    ' W- {" [4 d0 h6 e7 n6 {<>5 ~# `$ N& q( V& j: U1 K1 N
    //-----------------------------------------------------------------------------0 q" d% _8 o; b8 }8 l! Z/ m0 Z
    // Name: 3 D* r, m$ Z2 A' T
    // Desc:
    7 f: w% Q% h* j, _//-----------------------------------------------------------------------------2 s! ~5 a' ?$ W* X& n
    void CMazeServer:ockRange( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )$ {( M- T& i0 {% H
    {
    / r1 R" a3 _* t9 M3 G& D    m_LockGrid.LockRange( x1&gt;&gt;m_dwMazeXShift, y1&gt;&gt;m_dwMazeYShift ,
    8 s. y. W5 Y' n$ ^' g+ t  u; F+ q* J                          x2&gt;&gt;m_dwMazeXShift, y2&gt;&gt;m_dwMazeYShift );
    , ?* s) j. L2 q4 s}</P>: T! P9 c# F+ B/ h& H5 l! [0 [
    ) ]! Q. o" o9 Y. N; A/ r
    <>1 t6 m( x9 V$ v5 N  h; n& O
    //-----------------------------------------------------------------------------
    5 d3 h2 e" o2 l; x4 j  U& s// Name:
    ( ~; m8 K  m- ^  s1 Y+ S// Desc: 4 ^' h9 n" I. a& b' D2 {8 f
    //-----------------------------------------------------------------------------& j4 A: E$ S. V' E1 S4 L6 j; _- M' i
    void CMazeServer::UnlockRange( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )
    : L* `/ f6 q5 I% j7 w8 ^{
    4 k* {$ W# y1 ~+ m! L    m_LockGrid.UnlockRange( x1&gt;&gt;m_dwMazeXShift, y1&gt;&gt;m_dwMazeYShift ,. u1 K! s6 Z* ?( Y0 I6 _
                                x2&gt;&gt;m_dwMazeXShift, y2&gt;&gt;m_dwMazeYShift );* C; F. N4 |  f" v( t" r0 g! I
    }</P>
    / K5 E1 E  e+ O# v; {( X( ^5 l, t' k: Y; m
    <>! o, k8 v! q0 C9 b1 i. @  j
    //-----------------------------------------------------------------------------
    ' l# B, g$ p' l9 m5 J// Name: # S  a6 r: L" X3 \
    // Desc: 8 Q! M5 W. q9 J1 X0 L& c
    //-----------------------------------------------------------------------------% J$ B, A5 _2 `
    void CMazeServer:ockCell( DWORD x, DWORD y )
      y( ]* s+ Q5 t& o8 Z$ U{
    " x; W5 y& X& B  l2 d( t    if( x == 0xffff )6 |$ v7 M1 g; P# P" z/ v( a
            m_OffMapLock.Enter();. i7 a1 d* t8 {7 w4 \/ _. e, F
        else7 X4 L$ v. P) O
            m_LockGrid.LockCell(x&gt;&gt;m_dwMazeXShift,y&gt;&gt;m_dwMazeYShift);
    $ f# ^- f; R# I6 g# w' m% `- S}</P>, c: g: }2 t0 z: e

    7 b( U, X# ]% K2 g<>5 y) w/ v9 C% t$ c1 N. v" x$ J6 u5 `
    //-----------------------------------------------------------------------------
    3 H1 t- u9 Z! _  O, o" o- e( d// Name:
    . S& Q7 v( @- Z; j: q4 M6 t// Desc:
    4 W' i/ x' `: O, I6 q( O: ~7 |) y//-----------------------------------------------------------------------------" `# n$ K6 J- k4 r
    void CMazeServer::UnlockCell( DWORD x, DWORD y )
    ! r9 K) N- Y5 }( V: V+ B% b{
    , ~& h. c0 s  f9 W  _9 x3 Q. R: f    if( x == 0xffff )
      [) N- [; l; L2 y2 D8 `" S9 A        m_OffMapLock.Leave();) C6 T& n" Y  [3 G/ t& q: _! {; ~: |
        else% P1 q2 @- y; ?' Z: _) |
            m_LockGrid.UnlockCell(x&gt;&gt;m_dwMazeXShift,y&gt;&gt;m_dwMazeYShift);1 o3 d% n$ q. o6 `% Q
    }</P>
    8 U, o* S! @. k  J& }
    % E- |, E4 p# c! @7 C1 h! [<>4 F) O  Y9 F! P( g$ Z- q4 A1 a% J) l
    //-----------------------------------------------------------------------------) b  s  l& A' H1 @
    // Name: . o! J0 E% {/ j# }$ \, n
    // Desc:
    0 Y7 ~8 q; b. j9 b" c//-----------------------------------------------------------------------------
    7 a% i1 Q: x. }0 |. q% jvoid CMazeServer:ockCellPair( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )* a4 c3 T% y5 T% [
    {
    ! a' |" V) A; S! N8 N    if( x1 == x2 &amp;&amp; y1 == y2 ): l4 D- m, b9 m! A8 E- _- t% o" V# S
        {; m+ n2 N' @6 n
            if( x1 != 0xffff &amp;&amp; y2 != 0xffff )
    ) F  [3 R! W* J7 q            LockCell( x1, y1 );
    4 h  X! n% y# u        else4 l' o* l4 c1 Q, U
                m_OffMapLock.Enter();</P>3 m7 |* }7 N4 C. p
    <>        return;
    / d5 b8 {. n. s    }</P>
    9 J6 \6 [$ W( B6 E' Y* K  u<>    DWORD x1shift = x1&gt;&gt;m_dwMazeXShift;4 k4 a  e% w/ u$ P8 W0 p! l- O
        DWORD x2shift = x2&gt;&gt;m_dwMazeXShift;
    8 O( `  C" N& r: h    DWORD y1shift = y1&gt;&gt;m_dwMazeYShift;
    8 ]. j( H" o, ^' L" W9 I! N    DWORD y2shift = y2&gt;&gt;m_dwMazeYShift;</P>
    ) U+ y5 \& C  @3 X0 M$ j4 ?<>    if( x1 == 0xffff )4 v2 {! G( G2 `. r+ v+ a% R. E
        {; X3 C0 S% Q5 ^6 k1 L, r8 V  l' d
            m_OffMapLock.Enter();
    : {2 y# q1 i' r: y4 u        m_LockGrid.LockCell(x2shift,y2shift);
    ! N+ k# f5 ~, e; i$ {2 U. S* w. N! X    }3 U# f  c9 G6 L( |
        else if( x2 == 0xffff )! F# j9 C, P* B) {2 o2 s
        {
    1 \- O7 c, O/ r* e0 P5 f        m_OffMapLock.Enter();/ J, |% G) @$ @1 m( r" {
            m_LockGrid.LockCell(x1shift,y1shift);; q# ~! e4 v: m3 P0 t& j
        }
      z0 j9 C  L- |% D' b    else * M" g7 r' W3 C: h/ s7 E4 b. k
        {
    : v- t5 l1 W/ L& F        m_LockGrid.LockCellPair(x1shift,y1shift,x2shift,y2shift);& D$ x0 t  B( o% z7 F; \7 j
        }. N' H! e" v1 K' G- c
    }</P>- w" o7 A  h+ d$ w% N- f
    6 \' O) S0 [, X8 `$ y2 J9 @
    <>% [) x/ \6 p) Z# {9 W
    //-----------------------------------------------------------------------------4 @# A# ]( g9 m( Y1 e3 L; Z
    // Name:
    $ {3 D4 O8 G( F/ K7 j4 W// Desc:
    1 L% z' t& q" ]3 i6 K9 u& @, u//-----------------------------------------------------------------------------
    , Q; D- C  X$ i+ wvoid CMazeServer::UnlockCellPair( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )
    % Q9 G; n$ d" m+ K1 C" b8 X. @{
    , Z3 h! H0 P4 G# T) w0 O" u* j    if( x1 == x2 &amp;&amp; y1 == y2 )
      o* t% X, {6 ?' m, B- C) `2 O    {' i& X# H$ ]& H9 S, }
            if( x1 != 0xffff &amp;&amp; y2 != 0xffff )
    7 L$ y4 R& L4 b+ Q) `; l            UnlockCell( x1, y1 );
    3 k% s& w3 D5 y. `  t( Z7 ^7 K        else: y! x3 ]2 K1 i& a! ]$ ]
                m_OffMapLock.Leave();</P>3 m' M( z8 Q2 k! H
    <>        return;
    1 p- r  g8 [  E4 G& o' g    }</P>9 t# E% m! F1 L/ N" i9 u4 u2 H
    <P>    DWORD x1shift = x1&gt;&gt;m_dwMazeXShift;  B  m3 f) F) W( k- k
        DWORD x2shift = x2&gt;&gt;m_dwMazeXShift;3 S. E& A0 q. H1 p" i
        DWORD y1shift = y1&gt;&gt;m_dwMazeYShift;
    6 H0 x* Y% Y8 ~5 I    DWORD y2shift = y2&gt;&gt;m_dwMazeYShift;</P>1 `& B8 R2 c$ X$ U- ]% {; j+ H! d
    <P>    if( x1 == 0xffff )
    % q1 D/ ^$ `( U) O! w8 N" Q+ B    {
    3 `% Z3 p" Q% Z! j        m_LockGrid.UnlockCell(x2shift,y2shift);2 {. b+ r/ ^9 m" X8 q
            m_OffMapLock.Leave();
    # `: R8 n8 [& M" y& ^0 R, Q9 M    }
    6 i( H2 h: J* E; G  f0 w9 C( H    else if( x2 == 0xffff )
    * j4 G& F. T0 J' F; G' a+ ^' ~    {# ^4 E3 o* m2 Y% v& _
            m_LockGrid.UnlockCell(x1shift,y1shift);
    5 u* F7 j/ |1 t/ d( D8 I, L2 }4 l        m_OffMapLock.Leave();9 q% ?4 h3 A0 a6 O) c6 I8 W8 C' B& b
        }
    - v# D% T6 [7 m- c    else # t+ c4 w6 N; O. z/ D0 a
        {
    9 r2 X# _. I, V        m_LockGrid.UnlockCellPair(x1shift,y1shift,x2shift,y2shift);
    9 x$ s, t8 ?9 v/ J) o# p1 Z    }
    + O0 |2 J3 Z$ k& M5 X. d}</P>, u% t3 N0 \1 H+ T! f! `2 d; J

    9 Q+ ~5 H: B# f<P>
    3 Z4 u# v* T2 f  A" u//-----------------------------------------------------------------------------9 W' L# E) s! x: }' R! q  l1 k
    // Name: $ D! e0 }3 g: j
    // Desc: # l0 S  f& P* p0 ~, {; T$ i
    //-----------------------------------------------------------------------------
    / y7 C; [# i: Ivoid CMazeServer::OnAddConnection( DWORD id )
    : C% }9 a+ j" l, H4 e# e) ^{: W. Y  M; G# n3 {
        m_AddRemoveLock.Enter();</P>, O  c5 d# x1 \. @- C2 v
    <P>    // Increment our count of players* w( ^, x6 u, |% d
        m_dwPlayerCount++;
    % C# E& q- [: x* [" `* D    if( m_dwLogLevel &gt; 0 )
    , n( a% a' v2 @( w" k  |8 y  x    {) M& a* o7 _, c) h, j% Y  r
            ConsolePrintf( SLINE_LOG, TEXT("Adding player DPNID %0.8x"), id );
    / m* U, C- `, i& A        ConsolePrintf( SLINE_LOG, TEXT("Players connected = %d"), m_dwPlayerCount );0 x+ H. {6 f" C4 h9 p
        }</P>
    ( W% F; W+ s9 m3 Z<P>    if( m_dwPlayerCount &gt; m_dwPeakPlayerCount )
    & i+ t! M" X/ ~0 n3 \1 O9 i        m_dwPeakPlayerCount = m_dwPlayerCount;</P>
    ( ^3 f7 D& E6 I+ x  l/ M; e<P>    // Create a player for this client( i) z  L* C: c. e& @& m
        PlayerData* pPlayerData = CreatePlayerData();& _/ I0 S: ?" U: H5 j
        if( pPlayerData == NULL )$ a7 @+ X! F, I5 q4 T' h8 D
        {9 {: z. P! J) M2 P
            ConsolePrintf( SLINE_LOG, TEXT("ERROR! Unable to create new PlayerData for client!") );
    2 X0 J! u- f2 \        DXTRACE_ERR( TEXT("CreatePlayerData"), E_FAIL );6 c5 @/ J! z2 @# k' g
            m_AddRemoveLock.Leave();
    % t/ V# f9 i) e3 Q; I7 N; a1 F        return;
    " j% P" A) e2 K  A6 S8 @    }</P>: x' j9 k; j: z# r. w. j
    <P>    // Store that pointer as local player data
    " M5 r" |6 o8 x+ _' w- B    SetPlayerDataForID( id, pPlayerData );</P>; i$ ~8 k) i/ U2 ], ~' }, W
    <P>    // Grab net config into to send to client
    % e6 V- S1 K  h3 W    m_ClientNetConfigLock.Enter();0 n. B3 x, }5 l) L( q& c
        ServerConfigPacket packet( m_ClientNetConfig );
    1 D0 z" `* L, ], o. k    m_ClientNetConfigLock.Leave();</P>' S& X+ C$ h5 k
    <P>    // Send it
    7 Z1 Y: k; [, {7 |" B# H    SendPacket( id, &amp;packet, sizeof(packet), TRUE, 0 );</P>$ v: S) b) e7 W  z0 \
    <P>    m_AddRemoveLock.Leave();
    8 l" D# y6 T8 |% h}</P>3 {. |& x6 O( g5 \) d; v0 }/ p

      _+ I' ~3 b9 s2 g) G( O# X<P>
    9 x' S) E/ k4 q/ w# s/ W//-----------------------------------------------------------------------------& r5 t. f& W, p0 u! Y0 M" Q
    // Name:
    : S9 [* _8 y, y// Desc:
    3 T: G4 l& n' z. T2 e" Q0 Q( W) x//-----------------------------------------------------------------------------
    : |2 G; g0 Z  T" G2 Qvoid CMazeServer::OnRemoveConnection( DWORD id )
    * ]$ ]5 y: A+ V7 s. B{* _+ p' U9 z6 x+ B' J4 R4 V" U: Q( b
        m_AddRemoveLock.Enter();</P>
    % n7 s4 e/ r. |- _& O* H<P>    // Decrement count of players
    - [0 ], ]0 V" g( f    m_dwPlayerCount--;</P>* t5 A; E# w* j( u3 w
    <P>    if( m_dwLogLevel &gt; 0 )  q! Z( a1 Q$ c, D) {
        {
    1 I: `8 q) z' A6 ?        ConsolePrintf( SLINE_LOG, TEXT("Removing player DPNID %0.8x"), id );
    3 }5 E" n9 I5 ]; k& G, C        ConsolePrintf( SLINE_LOG, TEXT("Players connected = %d"), m_dwPlayerCount );
    ! e; q- j  j7 c, y1 P    }</P>( r7 K( Z5 `! P" k$ a: E# R5 I
    <P>    // Find playerdata for this client
    : U, Y" b5 D. j    PlayerData* pPlayerData = GetPlayerDataForID( id );
    , i$ W8 J9 i: u+ N6 S/ k, I# d, ~    if( pPlayerData != NULL )0 i. E* R4 ]) o3 d' \2 N
        {1 A" r' w. N# ]. `/ a
            // Destroy it
    ( u/ d+ N+ ?: ~) }9 c6 h        RemovePlayerDataID( pPlayerData );
    + }$ ?5 \. T& l- u( i        DestroyPlayerData( pPlayerData );$ X; i) E2 N8 V6 ^0 T
        }</P>6 P( t) g! k2 M7 T8 i7 T
    <P>    m_AddRemoveLock.Leave();
    + w0 z. ^$ h: W& d}</P>
    5 H5 S& i! f; l# d. o) K$ D
    ( ~; R5 b  L: C<P>, U7 S+ f$ r! a6 G& W
    //-----------------------------------------------------------------------------
    * {' A2 ?1 u; K3 g; l' o$ ]- o2 V// Name: , _. J! H) c- _* c: r+ j
    // Desc: " |8 D: h4 c- n$ |
    //-----------------------------------------------------------------------------
    4 \% S1 r) {! EHRESULT CMazeServer::OnPacket( DWORD dwFrom, void* pData, DWORD size )
    $ ?) v7 o7 ~' H, c: N- Z{
    # p2 @: `2 E6 x0 l9 h: B& I    BOOL fFoundSize = FALSE;</P>- t- X. E  {8 j9 P! ~
    <P>    // Increment the number of thread we have in this process.2 C& A" q$ c2 _
        m_csThreadCountLock.Enter();</P>
    7 k8 w6 z- V) A2 v: w<P>    //Get the start time of when we entered the message handler./ b% v% P" g6 c% p3 N7 r
        FLOAT   fStartTime = DXUtil_Timer( TIMER_GETAPPTIME );</P>. }9 N; f! c8 j9 ^3 }
    <P>    m_wActiveThreadCount++;
    ! |2 d$ N+ r/ c; a: l. l2 X    if(m_wActiveThreadCount &gt; m_wMaxThreadCount)/ V) q4 \1 y, B1 l1 i
            m_wMaxThreadCount = m_wActiveThreadCount;8 H! L( X: x( }5 L
        3 z7 ?, ?) \2 M
        // Calculate and average.4 ?1 |- ]4 ]% Q$ g: G" O
        FLOAT fdiff = m_wActiveThreadCount - m_fAvgThreadCount;
    ! T( |( Q! {8 m2 g* c* O) g4 l    m_fAvgThreadCount += fdiff/32;
    $ v) B; ]$ v5 L* G2 {: ?   
    6 Z" Q1 T# E2 q8 F# p: r    m_csThreadCountLock.Leave();</P>. l% D& I% O6 R! {
    <P>1 T" G, H8 s" `% {( C
        ClientPacket* pClientPack = (ClientPacket*)pData;
    2 g8 |5 F: W7 C- X* T) ~& m    switch( pClientPack-&gt;wType )
    $ r/ |8 h: b4 `0 c# Z    {
    3 {: E8 d. Z9 d0 }5 T        case PACKETTYPE_CLIENT_POS:) s. Z" o. b+ \" {
                
    & J' I. m8 q3 t: E( s: _8 o. B            // Check to see if the packet has a valid size. Including
    # }, J4 g( I' f0 n8 w% w            // the custom pack size.
    4 [, [; V$ y2 J            if( size &lt; sizeof(ClientPosPacket))
    & P) ]- P9 ]% H* T# l                fFoundSize = FALSE;
    % F$ r. k. P  q# F            else if( ! IsValidPackSize(size - sizeof(ClientPosPacket))), H8 j5 o7 a$ P+ N. R* f
                    fFoundSize = FALSE;
    6 N; X) G- Z/ G# q( E) [            else
    7 I4 @1 E0 R2 A  ?8 E: X8 R. Y: S                fFoundSize = TRUE;</P>  q' y! T" @3 E, j1 y! k, b
    <P>            // If valid sized packet, handle the position.* x0 ?4 `2 d0 q! S( r) J  y
                if(fFoundSize)$ R. T# {$ z  k% T/ M0 y& d
                    HandleClientPosPacket( dwFrom, (ClientPosPacket*)pClientPack );& b- \/ }5 ?+ T1 l
                else
    , d: _2 H0 }. d0 x& i. F8 S$ `% @                m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );</P>
    ( V- q; G) ^; E% ]: ]% F  A<P>            break;</P>7 v0 {2 |9 J. W' U1 P$ s
    <P>        case PACKETTYPE_CLIENT_VERSION:/ a) z# l7 E+ ?0 z, }
                if( size == sizeof(ClientVersionPacket) )  C6 l1 M3 K3 r- {
                    HandleClientVersionPacket( dwFrom, (ClientVersionPacket*)pClientPack );
    . k- F7 g8 ?* Q+ d            else
    ( p( v( O2 f+ v' j8 M                m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );
    ( m6 H  B7 M$ g3 U            break;</P>
    # n3 q1 v5 D; i* H5 V' _<P>        case PACKETTYPE_SERVER_CONFIG:</P>
    2 d2 N: I- E6 ^$ z" ?+ x6 A6 o9 D<P>            // Server config packet sent to all users (including server). Just ignore and continue.</P>
    . V' E7 p$ t* U* L* G, s  Q) `8 t<P>            break;
    0 R: S2 B- W, f6 C1 T% H' v        default:- \) y3 |: b0 N$ ^; Q5 P
                HandleUnknownPacket( dwFrom, pClientPack, size );' ]: D% F- d1 x& h; J  M1 Q: ^
                break;
    ( g+ z6 `3 }6 p) l7 N5 Y    }</P>
    * j( S! _$ J2 k- S, Z; f6 m+ [4 Q<P>    //If the user wants to hold the thread, Sleep for given amount of time.
    6 r# w0 `9 N8 U4 h5 f    if ( m_dwServerThreadWait &gt; 0 )+ d' r/ H6 o6 U1 ?5 j: [0 y
        {
    . j, V4 j9 B# R8 j  y, Q        Sleep( m_dwServerThreadWait );
    6 ?. w- X. E/ i/ i# X    }
      r) z1 T$ D) J! h5 L, X8 K   
    : x; }* v' U  d; g2 X2 o    // Retrieve thread data for this process.
    # h+ `1 z4 h0 i: a* {    m_csThreadCountLock.Enter();</P>
    8 l$ c3 i) f0 D  i/ h9 R* p& d6 |<P>    m_wActiveThreadCount--;</P>
    : R% G, a1 Z9 `2 N' F0 h3 O; P7 b+ w4 }$ A<P>    FLOAT fDiffTime = (DXUtil_Timer( TIMER_GETAPPTIME ) - fStartTime) - m_fAvgThreadTime;
    4 q  w: K; p$ V9 x/ H- E! o    m_fAvgThreadTime += fDiffTime/32;</P>( z- s7 y7 V5 v! y9 l
    <P>    //Get the Max time in the thread.
    + e7 r) r+ k/ L5 j    if ( fDiffTime &gt; m_fMaxThreadTime )
    % P5 K* ~( c* s6 a* B    {5 u- c  |/ u/ W0 D. Z" ]0 o5 c
            m_fMaxThreadTime = fDiffTime;. G' o7 R: C4 F  ?" l4 U
        }</P>
    8 }5 J- ^% z! {) P& L5 \0 {1 [<P>    m_csThreadCountLock.Leave();</P>
    + x' [3 G- I7 N( k<P>    return S_OK;
    0 o# \3 N2 D% n1 m; `}</P>
    0 A0 l; \7 V. F  c, X: f' z9 w" H
    2 j3 f/ t; {) |/ k  X: ?! h<P>//-----------------------------------------------------------------------------
    " G* d2 H3 F& k* T0 k. ~// Name:
    ; l3 b: _# i, ^// Desc: 4 G( z4 Z* V- j' k+ E* k* ?% [/ M
    //-----------------------------------------------------------------------------
    - W4 E% z4 f( V% k4 t1 oBOOL CMazeServer::IsValidPackSize( DWORD dwSize )
    " R% ]$ A" f9 p  v# p. K{
    5 \! _1 e+ A, t    BOOL fFoundSize = FALSE;& [* b- J# y- l4 `1 ]" {
        BYTE ubPackLocation = m_ClientNetConfig.ubClientPackIndex;
      C' @6 P' Q& G    0 x3 |' V! {8 [
        // Check through the array of valid pack sizes.
    8 d: k: R, U3 w" M" A8 t' m! t: }' ^    if(dwSize != m_ClientNetConfig.wClientPackSizeArray[ubPackLocation])8 P) V& L& O$ l1 v. o# t4 L
        {
    $ c# L9 f0 P& s0 f0 b- H        for( --ubPackLocation; ubPackLocation != m_ClientNetConfig.ubClientPackIndex; ubPackLocation--)" R5 ~# B2 M, w9 N/ A
            {  s. Y) M' [5 m& G0 T" i$ }- {  @
                if(dwSize == m_ClientNetConfig.wClientPackSizeArray[ubPackLocation])
    4 o$ L! |+ B% G4 |) S% T            {
    4 X' V5 o% i7 c8 b9 ]6 j  `8 \                // Found valid size in the array.
    % l& g- ?* g9 I2 W' x                fFoundSize = TRUE;: o2 `. x" U! v. e) Q2 ~
                    break;2 B4 Q# P+ n3 ~: n4 d
                }
    + z; ^" r. t0 B: i1 G            if(ubPackLocation &gt;= PACK_ARRAY_SIZE)  ubPackLocation = PACK_ARRAY_SIZE;  //Wrap the array.+ F( e. v# G+ M  L
            }" D. o9 P* c+ |. u3 w% Q
        }
    4 }' H0 v3 C6 p    else' v- {9 o$ b# V1 O: ^. c/ q
        {$ G% x' |& [  M- Z& [1 Y" D7 k9 C
            fFoundSize = TRUE;
    & @/ h" y6 v+ f9 d9 B1 x. L    }</P>  U5 j& b' O" H  ]
    <P>    return fFoundSize;
    5 M% K! ?* O% H' k9 T, r" y* U6 h}</P>: q: H9 t/ J4 q7 n
    <P>. U/ ~( v$ S* d# h2 D
    //-----------------------------------------------------------------------------
    / D/ u1 C7 t0 y4 G// Name: / U5 @/ F9 s* w
    // Desc:
    4 T/ G* s2 S+ s3 K//-----------------------------------------------------------------------------% S+ X% ]- u/ H2 k6 Y
    void CMazeServer::OnSessionLost( DWORD dwReason )
    8 `1 W+ m) S2 Q* t6 @# H) t% I( i{3 a5 h3 X' F4 Q6 g  `$ O4 u8 w. f
        ConsolePrintf( SLINE_LOG, TEXT("ERROR! Session was lost") );8 h  y: L2 \9 S  ~) g
    }</P>
    ! n$ m; q% g9 w, g$ M4 [/ K1 q' S" S4 d1 O) F
    <P>
    9 V& K, s  X5 w3 T, K: l. U. _9 ~  p: L//-----------------------------------------------------------------------------* S/ k! j3 e* {8 g
    // Name: 3 n" h* I! v& x4 W8 P' T* C
    // Desc:
      y* \9 u$ ?, h1 q! V//-----------------------------------------------------------------------------% a* H5 D2 C: P. U% a; n
    PlayerData* CMazeServer::CreatePlayerData()/ h  a  J- ^2 h
    {' W7 H- F1 n+ S8 d
        m_PlayerDataListLock.Enter();</P>
    & B- x/ Z- l/ m: X<P>    // Grab first free player in the list
    : f. s- j6 V+ T' Q  m    PlayerData* pPlayerData = m_pFirstFreePlayerData;</P>/ V5 K; x. \' v9 a. h" |( s
    <P>    if( pPlayerData )3 U9 P7 a0 W/ n; B
        {2 [! B7 I( E9 P7 t) M
            LockPlayerData( pPlayerData );</P>9 [, B2 W. e- z/ t7 B! k! B
    <P>        // Got one, so remove it from the free list# W) \' f* P: t1 p1 M" W8 H$ W1 ^! p0 d
            if( pPlayerData-&gt;pPrevious ). }9 e2 n# z& T# i
                pPlayerData-&gt;pPrevious-&gt;pNext = pPlayerData-&gt;pNext;
    6 X- k- A0 o6 X        if( pPlayerData-&gt;pNext )- J2 z  ]8 E% M8 m( J
                pPlayerData-&gt;pNext-&gt;pPrevious = pPlayerData-&gt;pPrevious;" `: }) V/ M/ `1 x3 T
            m_pFirstFreePlayerData = pPlayerData-&gt;pNext;</P>
    ' J+ U; g7 P) I  D<P>        // Add it to the active list
    ) }6 b. K4 Z( q" m- \3 m        if( m_pFirstActivePlayerData )
      c/ m4 {' f- J- `            m_pFirstActivePlayerData-&gt;pPrevious = pPlayerData;
      W8 x, |+ k: @" s3 x' n" S        pPlayerData-&gt;pNext = m_pFirstActivePlayerData;
    3 V! \4 J4 d2 o& E; D/ y4 l        pPlayerData-&gt;pPrevious = NULL;) z# n' a$ {  m- P
            m_pFirstActivePlayerData = pPlayerData;</P>7 M. t  r# u% y0 s' f+ g% B. o  ?
    <P>        // Update count of players
    3 a' F6 _6 x3 G1 x4 y        m_dwActivePlayerDataCount++;</P>
    * V/ v6 a  N9 L& P: r; I<P>        // Generate the ID for this player8 r) E6 F5 ^2 X7 a* B0 q
            m_dwPlayerDataUniqueValue++;
    1 ~$ }1 z. L  P        pPlayerData-&gt;dwID = (DWORD) ((pPlayerData-m_PlayerDatas)|(m_dwPlayerDataUniqueValue&lt;&lt;PLAYER_OBJECT_SLOT_BITS));</P>
    % m* _! B1 q0 [, S: y<P>        pPlayerData-&gt;pNextInIDHashBucket = NULL;6 e! `. h0 g) g( P
            pPlayerData-&gt;NetID = 0;0 l. c0 ~0 s' w( j
            pPlayerData-&gt;dwNumNearbyPlayers = 0;</P>
    + x. {! V* P$ Z9 V" G1 n<P>        // Insert into the "off-map" cell: p! X5 v; D" W0 R) M$ `* j
            pPlayerData-&gt;fPosX = pPlayerData-&gt;fPosY = -1;) u, ^0 s# n2 W, _4 K4 |; a% {1 o
            pPlayerData-&gt;wCellX = pPlayerData-&gt;wCellY = 0xffff;. z- m6 r* V- J3 V  u
            m_OffMapLock.Enter();3 @* {" J) |# p* Z# f0 y  n
            pPlayerData-&gt;pNextInCell = m_OffMapCell.pFirstPlayerData;
    ) P( w# E; A9 e* |5 Y        m_OffMapCell.pFirstPlayerData = pPlayerData;
    % S6 ~) n  M& L/ M1 Z( W8 d4 \! e        m_OffMapLock.Leave();</P>
    , Y' w  y' t) ~# X8 F- C* H<P>        // Mark as active% i- f9 b/ Q. ^( ~9 [* n
            pPlayerData-&gt;bActive = TRUE;</P>& {0 Y- O0 @8 K
    <P>        UnlockPlayerData( pPlayerData );
    $ g2 ^$ R+ j1 a* {$ ]. f! D8 A    }</P>. ~  j0 J! {  Q3 @# j* B
    <P>    m_PlayerDataListLock.Leave();</P>8 T; A- S3 c7 |6 S/ G; V
    <P>    return pPlayerData;: I: N) S! N0 J* E" `- u* r' F" i: c% j
    }</P>; [, N9 w' ?2 [& V5 p; m7 _
    . N: \& Z* E$ d! I# c
    <P>
    ( z5 r+ r- e  G; ^3 i# H0 ^! y7 p//-----------------------------------------------------------------------------
    " [: O2 `, ?5 \- |/ b! |! X// Name: + B) ?+ {5 c& e' B  b
    // Desc: , o$ E+ E( a! N2 ?3 W) n6 O1 y
    //-----------------------------------------------------------------------------; Y/ l. M7 F( b5 [8 O
    void CMazeServer:estroyPlayerData( PlayerData* pPlayerData )" q: o, e& X; h. o& S
    {
    6 q; C5 l. F8 W0 @% Q    m_PlayerDataListLock.Enter();
    1 E" m! B& E0 v, y" t  w& T    LockPlayerData( pPlayerData );</P>5 p* i7 S: V/ ?3 i' @, J% O
    <P>    // Remove the player from its cell9 [8 ~! m" Z1 r
        RemovePlayerDataFromCell( pPlayerData );</P>
    ! z8 ?4 D/ Y6 ]7 c<P>    // Mark as inactive
    + w1 {( `) N4 {2 R6 u    pPlayerData-&gt;bActive = FALSE;</P>' w$ H0 Q; g! }% i2 }# a- \
    <P>    // Remove player from active list
    9 u  {. ~! J" h! N    if( pPlayerData-&gt;pPrevious )
    , {7 d4 {' Y# u+ |0 {0 v        pPlayerData-&gt;pPrevious-&gt;pNext = pPlayerData-&gt;pNext;- M9 O/ l: }' i/ t# K
        if( pPlayerData-&gt;pNext )- n) G+ Z9 D# j0 ~( u: n
            pPlayerData-&gt;pNext-&gt;pPrevious = pPlayerData-&gt;pPrevious;</P>6 P- \  s( q9 w0 e7 w5 {8 @0 y
    <P>    if( m_pFirstActivePlayerData == pPlayerData )0 `! f) x* e$ W# ?* n
            m_pFirstActivePlayerData = pPlayerData-&gt;pNext;</P>
    # p: Z$ W) X2 l<P>    // Add it to the free list3 j- E; C; B' I1 q# W1 u9 q5 w0 Y- K# w
        if( m_pFirstFreePlayerData ). P2 m7 p# \; |8 D: u7 k4 X4 D
            m_pFirstFreePlayerData-&gt;pPrevious = pPlayerData;: C& m  P! M& r* d  u# G, k! e
        pPlayerData-&gt;pNext = m_pFirstFreePlayerData;
    ( k# M0 n5 _0 a0 f- l- c- W    pPlayerData-&gt;pPrevious = NULL;+ q" T1 V% b- O  J$ n9 R
        m_pFirstFreePlayerData = pPlayerData;</P>, B9 n6 C' Y# O7 c1 s; C% }
    <P>    // Update count of players
    4 A, B- F0 C7 Z+ L% Y+ ~1 e    m_dwActivePlayerDataCount--;</P>/ V% S: I# Q$ N- d
    <P>    UnlockPlayerData( pPlayerData );. m1 I1 r1 e" r" U6 p+ i' E
        m_PlayerDataListLock.Leave();" A% L1 r+ D& E% f6 W4 m
    }</P>
    9 q# W; k  U2 D  ?4 P1 q) d( r9 B
    1 b  }! `, ~7 C<P>
    # {4 X' g$ [( C8 D//-----------------------------------------------------------------------------9 K9 P3 `: |- u0 B% J
    // Name:
    , o6 b( Y, [5 v8 A# `9 _4 |7 x6 s// Desc:
    ' p3 c4 G! d) r4 _  m- F2 X//-----------------------------------------------------------------------------3 I8 C$ U" ^6 @9 m4 U3 Y) ^0 P% {
    void CMazeServer::RemovePlayerDataFromCell( PlayerData* pPlayerData )
    ; s# o/ H9 o6 X+ Z/ H0 r1 S{
    ; H+ B1 }' ?' H; ^' m    // Lock the player
    / R* v* r( g  l9 q: I- R  q    LockPlayerData( pPlayerData );</P>
    % [- W( |. s  W3 A8 g  a' S5 }5 V% F<P>    // Lock the cell the player is in
    - \6 |' n$ l7 e: K( t    ServerCell* pCell;
    9 b/ \' g+ W+ t' t. h    if( pPlayerData-&gt;wCellX == 0xffff )4 H& C( u6 V& _; g
        {
    8 G, X* r6 d' I. t5 A/ E" H        m_OffMapLock.Enter();
    & R" Y8 n8 s! e. E  i, p0 R        pCell = &amp;m_OffMapCell;# \" v* y$ V- l7 s  X9 K' [
        }
    0 d6 o; W: f, N+ [7 x, ]" z; r9 a. R    else
    , K* I0 I3 I4 l6 w4 ~! k: z    {. h# f2 }& m! o
            LockCell( pPlayerData-&gt;wCellX, pPlayerData-&gt;wCellY );
    6 v  c. U7 O# |: h$ @        pCell = &amp;m_Cells[pPlayerData-&gt;wCellY][pPlayerData-&gt;wCellX];0 M, W! ]1 b6 c
        }</P>8 Y2 Y. d" G( H# K
    <P>    // Remove it from the cell+ t+ L3 K" d- t# d2 r6 G  P
        PlayerData* pPt = pCell-&gt;pFirstPlayerData;
    7 r) |1 x+ Z6 a8 H# n# @2 z2 ]4 T" x    PlayerData* pPrev = NULL;' {, [( `) U4 U8 {
        while ( pPt )
    8 f8 {7 R% {) Y: Q; d; y    {1 j8 f+ ?1 _  ?: \% h% W& g  b0 {
            if( pPt == pPlayerData )& ?3 L/ K* z% @5 i$ P5 g: S
            {
    " u( @: w/ D# s. p) M9 q/ j            if( pPrev )
      o& K: w7 b! W  `4 [                pPrev-&gt;pNextInCell = pPlayerData-&gt;pNextInCell;
    8 F6 s3 V3 `% B' O            else% h  p4 M4 h3 @6 Z( b" G% Z
                    pCell-&gt;pFirstPlayerData = pPlayerData-&gt;pNextInCell;</P>& H9 S' z; m# g8 ~  Y
    <P>            pPlayerData-&gt;pNextInCell = NULL;7 E' E% K, v0 g, W
                break;
      y4 a3 y( u1 q        }
    ; w( {, J! s; ?0 p; S        pPrev = pPt;
    # Y' [  v. {/ l/ i. @; D        pPt = pPt-&gt;pNextInCell;
    ( `2 o$ C, c3 C7 X; I% }+ b( S    }</P>( Z+ I& X0 I0 S( Y: P% P
    <P>    // Unlock the cell
    " q# e" H1 a; X8 d9 B  ^    if( pPlayerData-&gt;wCellX == 0xffff )
    . O, c. c1 W, r, |& p' K        m_OffMapLock.Leave();$ Y; ~& {2 X& C: Y2 C3 e
        else* c; o: m3 Y& e" `, N: e
            UnlockCell( pPlayerData-&gt;wCellX, pPlayerData-&gt;wCellY );</P>- o. L0 m! ?$ [4 Z6 ]* O1 q$ E
    <P>    // Unlock the player' V4 w8 }7 F7 |& k- h/ Q, Q
        UnlockPlayerData( pPlayerData );1 `8 g$ n! @) G6 D
    }</P>$ ], f* j" Z2 g* m

    - N7 G! [2 P/ I<P>) ~# D3 z  j$ i, V
    //-----------------------------------------------------------------------------5 I' C4 k8 J& n7 Z4 a; a& ?
    // Name: , D9 [- ?* w* f* Z* p( t" a( t/ _
    // Desc: 4 t6 \0 M7 o! C
    //-----------------------------------------------------------------------------
    4 R4 F) P* X9 k7 tvoid CMazeServer::UnsafeRemovePlayerDataFromCell( PlayerData* pPlayerData )
    6 U! K) {4 |5 p: l% d- [{, V1 }5 }: d! w) T6 M/ o0 E
        ServerCell* pCell = GetCell( pPlayerData );9 x; ?/ g3 h3 p4 q+ s) w
        PlayerData* pPt  = pCell-&gt;pFirstPlayerData;
    1 U7 w$ _1 C7 C. q9 J    PlayerData* pPrev = NULL;- M& n& D- y1 T# q$ r
        while ( pPt )3 E0 P  ~8 N6 i! }- l/ H
        {9 y$ n& c2 ?" l& N$ c1 m) ?) m6 ?. H
            if( pPt == pPlayerData )
    & t* b6 ?9 u0 o& L! Z: y        {' X4 c; T7 u! t2 E% G
                if( pPrev ). A1 v$ u' M0 n; A1 ?
                    pPrev-&gt;pNextInCell = pPlayerData-&gt;pNextInCell;% U' T5 }: Z) l" Z
                else
      u" {; ?' i& U5 i                pCell-&gt;pFirstPlayerData = pPlayerData-&gt;pNextInCell;
    * `, J3 _8 l! @, N$ R! u            pPlayerData-&gt;pNextInCell = NULL;3 Q4 G4 p1 V1 w) g0 a( {& p# T
                break;
    & m. |. z9 h6 a' r4 W        }
    ( {. ?$ h0 l5 U/ X, P        pPrev = pPt;
    1 e* ?) p7 o1 l) k, k& ]) y/ Z  \  U        pPt = pPt-&gt;pNextInCell;
    8 n) s$ e6 p9 V7 q# d    }
    * J$ s9 n! R) ?}</P>
    . W1 p! p4 \2 _7 d' }, a* Y8 Z
    # n" R. ~, h* A7 Q% |" R1 P2 W; B<P>. P" X* q/ K. l8 D
    //-----------------------------------------------------------------------------
    & T; q. p2 a! |7 j; I1 i// Name:
      e4 d# T0 e! v( d4 `: V$ i. w// Desc: 1 o# E  {5 z, ]4 ]; z8 _% C
    //-----------------------------------------------------------------------------: e# u, \3 [$ d( A
    void CMazeServer::UnsafeAddPlayerDataToCell( PlayerData* pPlayerData )2 _5 j/ P7 i: c( ]& q( D1 v7 q9 o
    {
    : G$ s' N5 o% D8 I7 v" ]    ServerCell* pCell   = GetCell( pPlayerData );# [- p2 c6 f$ F) ]9 p7 o
        pPlayerData-&gt;pNextInCell = pCell-&gt;pFirstPlayerData;
    8 P/ H( s7 ^! f4 s: p    pCell-&gt;pFirstPlayerData = pPlayerData;, m1 I6 S0 m9 F: t, ]* b
    }</P>
      S( P# A: g, ?- v9 P$ ]$ M/ L& D- K! e& l0 `
    <P>
    ' i" u3 B7 h# l6 q//-----------------------------------------------------------------------------% ~6 _7 O- q! k: ~
    // Name:   ~8 i* |. W2 B) h7 @' @
    // Desc:
      |1 x" @0 I2 w( p1 z2 z- I; n//-----------------------------------------------------------------------------6 z" H+ C9 \- \$ J9 p, h
    void CMazeServer::HandleClientPosPacket( DWORD dwFrom, ClientPosPacket* pClientPosPack )
    $ p# P4 p& t6 h; d{/ M* i6 P/ X- U% J2 X! O9 _( Z2 x
        // Grab player for this client and lock it, |9 c2 ^: ]  V) `3 k* f
        PlayerData* pFromPlayer = GetPlayerDataForID( dwFrom );& d* b; D+ I4 E1 W, C# r3 S
        if( pFromPlayer == NULL )
    $ w9 j% h) x. e6 g4 X    {: C- X8 k8 Z$ J& `: P; z
            if( m_dwLogLevel &gt; 1 )6 D0 m# Z0 {6 d4 d- [1 s5 K
                ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Could not find data structure for this player"), pFromPlayer-&gt;NetID );
    $ A. t* O- Y1 ?( v' t- K/ i        return;0 v, k3 B1 }# O, m: }9 R
        }</P>
    1 l0 B8 `8 w! q5 Q<P>    LockPlayerData( pFromPlayer );</P>. \4 A0 _$ `! X9 D/ C- T( H
    <P>    if( FALSE == pFromPlayer-&gt;bAllow )+ \- \- Z% o, Y
        {
    ) g8 s, ?/ n+ |3 j% _        if( m_dwLogLevel &gt; 0 )
    3 W6 v* {$ r, U0 i. O            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Got position packet from bad client.  Rejecting client"), pFromPlayer-&gt;NetID );</P>
      F- P( M& ^# H& J<P>        m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );& x( C0 |8 d1 [" l
            UnlockPlayerData( pFromPlayer );! {9 k& x0 [1 J& Q% a. U+ L: c
            return;3 Q5 E+ a. |) \% D6 l. ^! Q% S" V
        }</P>6 r( S: r! ?6 x0 `+ l" }8 n
    <P>    // Compute the cell the player should be in now  M7 |; E& d# O2 x1 S* J8 j
        DWORD newcellx = int(pClientPosPack-&gt;fX);+ ^+ i$ P; r3 i/ M, h
        DWORD newcelly = int(pClientPosPack-&gt;fY);
    & J0 y9 \$ u1 F" |9 _    DWORD oldcellx = pFromPlayer-&gt;wCellX;+ |# ]. y6 r  f  K1 t
        DWORD oldcelly = pFromPlayer-&gt;wCellY;</P>4 n, Z- P8 d3 n/ G5 X
    <P>    // Have we moved cell?% r+ A! I. k! n  y
        if( newcellx != oldcellx || newcelly != oldcelly )4 I3 B! v6 u# n" ^& q7 l
        {/ \/ u* w2 T0 z5 Z+ Y* I' f; X% j2 t
            // Yes, so lock the pair of cells in question+ \2 A, e/ l& I3 v& v
            LockCellPair( oldcellx, oldcelly, newcellx, newcelly );</P>
    ; L$ `3 ^- G3 g" V8 T- R4 n6 Y<P>        // Remove from old cell and add to new cell, Y$ `: t+ P7 i( k/ g% C- E
            UnsafeRemovePlayerDataFromCell( pFromPlayer );9 t+ q9 L* }! `
            pFromPlayer-&gt;wCellX = WORD(newcellx); pFromPlayer-&gt;wCellY = WORD(newcelly);
    4 d+ L# Z4 z1 T) n! u        UnsafeAddPlayerDataToCell( pFromPlayer );</P>
    + l( F0 [% H: m8 @5 O2 \/ y9 k<P>        // Unlock cells
    1 W& m" C% m4 ]. P" L        UnlockCellPair( oldcellx, oldcelly, newcellx, newcelly );
    - Q" |& X4 R- M& ]+ ?    }</P>
    ( X' r+ i+ M9 W9 ^9 Y; ]<P>    // Update player position
    6 u4 n& h- a3 @7 L# K! s  n; R    pFromPlayer-&gt;fPosX      = pClientPosPack-&gt;fX;) J4 m8 r7 M2 @
        pFromPlayer-&gt;fPosY      = pClientPosPack-&gt;fY;! B/ _+ J4 C; T2 K; _: s/ d
        pFromPlayer-&gt;aCameraYaw = pClientPosPack-&gt;aCameraYaw;</P>9 c6 t; R3 a& p# i
    <P>    // Allocate space to build the reply packet, and fill in header
    8 F5 p3 I3 C7 ^; u    DWORD dwAllocSize;
    ) [: h* L- T1 C  F/ H8 r7 W- `    ServerAckPacket* pSvrAckPack = NULL;</P>; T$ f/ V0 F/ k
    <P>    // Begin by allocating a buffer sized according to
    / m: \- G  }  q. t; i0 K    // the current number of nearby players + 4.  This will give
    6 k0 [+ o4 E; r' ?# v    // a little room for more players to come 'near' without resize( s) I  ~' s& T  g
        // the buffer.3 ^; {$ f( g1 C  i- ?
        DWORD dwMaxPlayerStatePackets = pFromPlayer-&gt;dwNumNearbyPlayers + 4;</P>
    - T, B2 j& s' T  x9 m- `' x<P>    dwAllocSize = sizeof(ServerAckPacket) + dwMaxPlayerStatePackets*sizeof(PlayerStatePacket);) F; p8 N8 p6 o1 y) T
        pSvrAckPack = (ServerAckPacket*) realloc( pSvrAckPack, dwAllocSize );
    4 f1 L& e% l2 b, V. p& O    if( NULL == pSvrAckPack )4 O$ [# G: x1 x5 c
        {! U2 u5 {7 s* q
            // Out of mem.  Cleanup and return% `: x' E2 n# E: A( _
            UnlockPlayerData( pFromPlayer );4 N! A2 A3 K" L, O
            return;       * F0 v5 S+ h6 ?8 n% {  ?  l) h
        }: k7 t1 ~5 K  c* Z/ l& G
        ZeroMemory( pSvrAckPack, dwAllocSize );</P># \' h4 d% c. S& {
    <P>    *pSvrAckPack = ServerAckPacket(m_dwPlayerCount);8 @8 d0 m3 v/ Q* C% k7 \- }4 B
        pSvrAckPack-&gt;wPlayerStatePacketCount = 0;
    8 M0 d2 F. Y1 _. x7 u! N' `/ }    PlayerStatePacket* pChunk = (PlayerStatePacket*)(pSvrAckPack+1);</P>* p+ q" U9 b) @
    <P>    // Compute range of cells we're going to scan for players to send
    $ N; B4 [' V+ W$ k4 l    DWORD minx = (newcellx &gt; 7) ? (newcellx - 7) : 0;7 [" Q+ o% V9 W  E: t+ C
        DWORD miny = (newcelly &gt; 7) ? (newcelly - 7) : 0;! ~( |  P$ Z+ G- W# s$ `
        DWORD maxx = (newcellx+7 &gt;= m_dwWidth) ? m_dwWidth-1 : newcellx+7;- }, ~% _" Z2 s7 D7 r; Z
        DWORD maxy = (newcelly+7 &gt;= m_dwHeight) ? m_dwHeight-1 : newcelly+7;</P>
    8 Q, ^/ V& Y- a5 p  o4 ~<P>    // Lock that range of cells- t! u, }) Q+ M  `
        LockRange( minx, miny, maxx, maxy );</P>4 y9 r* Q6 t, |. G, p4 b
    <P>    // Scan through the cells, tagging player data onto the end of
    5 S( @* B# j1 A% ]2 _    // our pSvrAckPacket until we run out of room
    . h) Z8 J8 q/ F. [    for( DWORD y = miny; y &lt;= maxy; y++ )
    # M( H+ W) [5 b: f- v7 \    {
    1 s! H% k9 T# x5 q+ `        for( DWORD x = minx; x &lt;= maxx; x++ ): I" n% K+ Z7 I7 N$ o7 W
            {
    ; C( h) C% X3 F3 g7 g" R' C            PlayerData* pCurPlayerData = m_Cells[y][x].pFirstPlayerData;
    ! @. G9 M9 C9 K+ ~. v4 L; {            while ( pCurPlayerData )
    ) P  N% K9 g9 E; `5 B5 m" S$ x            {4 N6 Y( U, r7 y
                    if( pCurPlayerData != pFromPlayer )  t: C9 Y/ n( Q; I* G9 ]
                    {
    0 j4 \+ N7 N) j' ~6 j9 n  \3 A) M                    if( pSvrAckPack-&gt;wPlayerStatePacketCount &gt;= dwMaxPlayerStatePackets )' h) O7 Z& {* |
                        {
    ) u& U& r, M% m: w- g                        // Make sure pChunk is where we think it is  D! T" Q+ a: @& T& m
                            assert( (BYTE*) pChunk == (BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket)) );</P>
    9 U. }* z3 E" Y3 _8 d# Q<P>                        // There are more than just 4 new nearby players, so resize the
    - g" u/ ~& h5 B' J                        // buffer pSvrAckPack to allow 16 more PlayerStatePacket's.
    ' K1 l- m5 N+ E0 W                        dwMaxPlayerStatePackets += 16;
    * |6 g; z, L+ _% r% J                        dwAllocSize = sizeof(ServerAckPacket) + dwMaxPlayerStatePackets*sizeof(PlayerStatePacket);
    . W: B+ V9 M( X2 f1 r4 w1 l: V                        ServerAckPacket* pNewSvrAckPack = NULL;+ D$ E) `; K# D- E1 A8 Z
                            pNewSvrAckPack = (ServerAckPacket*) realloc( pSvrAckPack, dwAllocSize );$ X; U+ a) t' y) y4 {
                            if( NULL == pNewSvrAckPack )9 S; r( l! f, P& T( r3 C
                            {
    # C& q0 Z, E5 A! V  q& t5 ]: R. P, M" ?                            // Out of mem.  Cleanup and return
    & D& S6 x+ n; ]: k3 f  U1 v- v                            free( pSvrAckPack );
    + |5 G2 T* H. U                            UnlockRange( minx, miny, maxx, maxy );. b' I6 r8 W$ p6 O0 L& L* A
                                UnlockPlayerData( pFromPlayer );- J$ t" K' Q0 w9 p* A6 \: I) H
                                return;       8 p/ R& i. d; w9 f% b: q+ O& \) m
                            }</P>$ ]4 ]# ~8 A8 M& Z3 }( ^" ]" N
    <P>                        pSvrAckPack = pNewSvrAckPack;
    4 i( h5 d: R" B6 A( D2 }4 n9 ~                        pChunk = (PlayerStatePacket*) ((BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket) ) );</P>
    " R7 X0 h; ]( h5 i" q<P>                        // Make sure pChunk is still where its supposed to be1 q9 c/ @, Q: \/ g; m
                            assert( (BYTE*) pChunk == (BYTE*) ((BYTE*)pSvrAckPack + sizeof(ServerAckPacket) + pSvrAckPack-&gt;wPlayerStatePacketCount*sizeof(PlayerStatePacket)) );% _( u- H# n4 Z3 t5 s3 Z
                        }</P>
    4 j' V9 V$ L  H( K<P>                    pChunk-&gt;dwID       = pCurPlayerData-&gt;dwID;
    5 |' d7 R( f2 l* N0 n                    pChunk-&gt;fX         = pCurPlayerData-&gt;fPosX;
    3 y6 g7 A' A( m                    pChunk-&gt;fY         = pCurPlayerData-&gt;fPosY;& |; k7 _9 \9 K: i' t6 X# W* _
                        pChunk-&gt;aCameraYaw = pCurPlayerData-&gt;aCameraYaw;8 X6 f. d' ?- t' \4 g. z. _$ p% @
                        pChunk++;
    6 b! `% k! z3 H" Y9 |4 k                    pSvrAckPack-&gt;wPlayerStatePacketCount++;; \. h! Z2 d& H- P
                    }
    ! l5 b' f( ~. {1 ]  m                pCurPlayerData = pCurPlayerData-&gt;pNextInCell;
    5 g+ j- t0 n2 P- D, _            }
    9 B+ v1 @1 \+ k) t, o9 j        }
    3 h5 C3 ]) b) {' d) B    }</P>
    5 i% v2 W$ P+ ~/ @) F<P>    // Update the dwNumNearbyPlayers for this player
    7 b( |) b) \' h. q2 }2 [/ B; N4 f5 p    pFromPlayer-&gt;dwNumNearbyPlayers = pSvrAckPack-&gt;wPlayerStatePacketCount;</P>
    " X/ Z0 A1 n* L& e" y# d( f<P>    // Unlock range of cells! M/ y  N0 B5 k* B% R$ C% \
        UnlockRange( minx, miny, maxx, maxy );</P>' c! l/ c8 V0 A1 s5 n0 }
    <P>    if( m_dwLogLevel &gt; 2 )) k1 [/ a: N3 l" m( Q
        {
    5 H% m& W7 Q) i4 y        ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Position is (%0.2f,%0.2f)"), pFromPlayer-&gt;NetID, pFromPlayer-&gt;fPosX, pFromPlayer-&gt;fPosY );
    1 t# R" R0 L/ x2 g& i2 n+ i8 X    }
    3 P7 f' l& }" R( |$ g* P    else if( m_dwLogLevel == 2 )  R1 z5 ~; e0 h4 K' t5 F/ X1 h8 N
        {& W: x1 N) _/ O3 e5 N+ S; M
            FLOAT fTime = DXUtil_Timer( TIMER_GETAPPTIME );
    # W6 x% d/ v; o- K3 z8 E, V2 V: W* k        if( fTime - pFromPlayer-&gt;fLastDisplayTime &gt; 60.0f )& P; n, `0 N' L/ F
            {
    # P2 X) A/ |: d' R# `! e            ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Position is (%0.2f,%0.2f)"), pFromPlayer-&gt;NetID, pFromPlayer-&gt;fPosX, pFromPlayer-&gt;fPosY );
    , O5 y$ B, J" \  L            pFromPlayer-&gt;fLastDisplayTime = fTime;9 [' D3 b$ z) }  T$ S9 ^# |# `! m
            }
      \' `1 o( H0 _( Y1 y" {    }</P>
    4 W$ C$ y4 q) H0 o<P>    // Unlock the playerdata& X# T) R" X- s  }# e
        UnlockPlayerData( pFromPlayer );</P>6 {: q! {% A/ K3 }  t& [
    <P>    // Send acknowledgement back to client, including list of nearby players
    2 j- M' R% y: ~1 H! t    DWORD acksize = sizeof(ServerAckPacket) + (pSvrAckPack-&gt;wPlayerStatePacketCount * sizeof(PlayerStatePacket));( f. G) U0 ?0 u3 ^2 D3 b/ f* i

    % \, V2 T1 E7 @" r/ x/ Z8 e    // Pack the buffer with dummy data., J1 ~0 }: S% l7 j$ b- I
        if(m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex] &gt; 0)" [( ?6 |7 |$ i/ O/ }+ O9 Q
        {
    $ M, C0 ^- R- o' P' j% \( t& t; u        DWORD   dwBufferSize = acksize + m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex];
    * q& Y% X2 S' S) @$ {        VOID*   pTempBuffer = 0;</P>7 T+ d5 j* p5 _* d! N' v- N4 n
    <P>        pTempBuffer = malloc(dwBufferSize);9 P+ `  V  U) j) \7 W
            if( NULL == pTempBuffer )) @" x$ S- i9 C- m! x- G- w
            {' M. I8 a& b+ ?4 N3 l2 @
                //Out of memory' [4 v( L" ^7 a% a9 e) u% R3 E4 A# Q
                DXTRACE_ERR_NOMSGBOX( TEXT("System out of Memory!"), E_OUTOFMEMORY );
    8 A, {5 j4 o, p7 w            free( pSvrAckPack );
    & h) X, }' w6 ?            return;; |9 k- v) L0 v* I( d; q+ w+ l, C
            }</P>
    / M% m3 d5 F1 q: i$ A<P>        FillMemory(pTempBuffer, dwBufferSize, 'Z');' Z# v* ~! B( Y$ a) R
            memcpy(pTempBuffer, pSvrAckPack, acksize);</P>4 u( Q- v. N- F2 a9 g" R: S, ~
    <P>        SendPacket( dwFrom, pTempBuffer, dwBufferSize, FALSE, m_dwServerTimeout );
    + Q( [* l! \  _1 W7 O' P   
    5 Z, s! J1 E3 L3 M# C        free(pTempBuffer);
    ' O& U, u, y$ f. ^    }   
    5 [* \1 j1 A6 e" i8 k- w) m    else
    ' h" I( d# ?0 m0 _% X# @  U    {
    " i0 a1 v0 b9 n' D! u. n+ i- R$ c        SendPacket( dwFrom, pSvrAckPack, acksize, FALSE, m_dwServerTimeout );
    # J. c7 @$ @% O% R) L- t5 o" C2 S    }</P>
    , l2 N. E, A" S6 D<P>    free( pSvrAckPack );</P>
    & h" `# N, C" Y$ ?: u3 i7 H<P>}</P>& x: y  L5 T. _; u
    5 Y: Y- b) L' b
    <P>' f, t/ ]& P8 Y; ~- U# p3 Z
    //-----------------------------------------------------------------------------) l% t  C/ l% A; e4 @6 Q0 {
    // Name: & J) L  S; Z" N& }% O8 s
    // Desc:   \  l  \9 X1 \, {4 @9 r
    //-----------------------------------------------------------------------------
    / R: ^7 h7 w% w) Svoid CMazeServer::HandleClientVersionPacket( DWORD dwFrom, ClientVersionPacket* pClientVersionPack )1 I& {0 c; \6 t/ g) ~7 v
    {
    : i4 o9 D; q2 `: O5 a    // Grab playerdata for this client and lock it; E/ E+ o$ u. d1 `0 t8 b
        PlayerData* pPlayerData = GetPlayerDataForID( dwFrom );
    8 f& z0 w# l' H3 F    if( pPlayerData == NULL )
    6 g0 o- w: S2 D4 y+ K        return;! C9 r* E( T0 B, H0 W
        LockPlayerData( pPlayerData );</P>! L% D5 U+ J4 {, [1 H& |" g
    <P>    // Record the version number
    / Z' k( D/ e) c! w- H    pPlayerData-&gt;dwVersion = pClientVersionPack-&gt;dwVersion;</P>+ U6 a0 [6 O+ i
    <P>    if( m_bLocalLoopback )! }" h/ D9 ]) ?
            pPlayerData-&gt;bAllow = TRUE;* r' w2 D9 \- m4 }+ _! m+ q
        else
    6 u8 J+ h' t6 N2 ~% z1 C5 V& R0 H: Z        pPlayerData-&gt;bAllow = IsClientVersionSupported( pClientVersionPack-&gt;dwVersion );</P>. X* l$ D4 q- m& s
    <P>    if( m_dwLogLevel &gt; 0 )* p- `, C5 M0 V& V! g5 ?
            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>
      B9 Y; D# x4 r: Y! O/ @9 q<P>    if( FALSE == pPlayerData-&gt;bAllow )
    ) p4 O+ ?0 n; |5 I" h* Y+ [    {& H: C+ U+ n5 a6 r! n( A
            if( m_dwLogLevel &gt; 0 )% h/ p& Y2 u' c' S4 ]6 \
                ConsolePrintf( SLINE_LOG, TEXT("DPNID %0.8x: Rejecting client"), pPlayerData-&gt;NetID );</P>+ F' a- p  h% y# M1 S. x  ~
    <P>        m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );& {1 }/ Z( R3 Z9 W5 ?! b; u
            UnlockPlayerData( pPlayerData );
    7 R" ^, t2 R! c; Y        return;& R6 e. t% I, S2 T; j
        }</P>
    5 P2 P, v" t" M9 ~# t4 b<P>    // Unlock the playerdata
    0 Y' \5 L% m; i! `+ m+ o1 o" U$ q    UnlockPlayerData( pPlayerData );</P>
    4 O3 s( e) X" l. ]% L) `/ m<P>    // Send acknowledgement to client that the client was either accepted or rejected, `" J2 l8 |' d  J
        ServerAckVersionPacket packet( pPlayerData-&gt;bAllow, dwFrom );# ~2 l9 @& j* C& l' e* x0 e8 c
        SendPacket( dwFrom, &amp;packet, sizeof(packet), TRUE, 0 );) u: k4 L5 J* i! V: s
    }</P>
    & s& I: G+ f1 m. ]9 _8 k* C! j. [2 S* `
    <P>
    # Z. c  M0 h: w" \& K//-----------------------------------------------------------------------------
    . J9 j& Y4 b' Z4 |/ j// Name:
    7 `% E5 j% V3 s" [4 E; |// Desc: 1 Y6 v  n+ I: t
    //-----------------------------------------------------------------------------
    / A# w5 s( D% A- NBOOL CMazeServer::IsClientVersionSupported( DWORD dwClientVersion )% M7 \: e6 k9 a) y5 _. E7 v" E2 p% b
    {
    ; u6 u2 \' N, f, t, d- T  b& d    switch( dwClientVersion )
    & t4 \+ e7 f+ `" f9 h* S8 t* F3 G    {4 l" ]& r2 }$ i+ K
            case 107: // only v107 is supported2 ]+ Z( r$ O/ C2 m: g7 o
                return TRUE;4 `  o8 j* M( `" l$ _( w3 ^
            default:
    7 q) i; P  Y$ b' y1 P( F  @            return FALSE;/ `5 G3 Y0 V8 k* \- `
        }
    $ B' c, Y9 Y: p}</P>
    1 b4 x- ]% l1 Z, I4 k7 V  i: S3 j- Q
    <P>
    * @2 g( P6 F/ i+ S9 K' V//-----------------------------------------------------------------------------
      Z8 K: Z0 n5 k" F/ l+ R$ C! e/ y// Name:
    # W( @; R  }1 u0 u% v8 l// Desc:
    # s( c" m% O) u$ u; |//-----------------------------------------------------------------------------6 Q1 G& A9 t3 m" u. f5 D* A
    void CMazeServer::HandleUnknownPacket( DWORD dwFrom, ClientPacket* pClientPack, DWORD size )" P$ {8 m/ k* Y6 Q2 n, Y2 K* t
    {
    4 c3 \7 U- f: T! Q$ z    if( m_dwLogLevel &gt; 1 )5 l& W- |  u4 f$ F9 Q7 {7 F
            ConsolePrintf( SLINE_LOG, TEXT("ERROR! Unknown %d byte packet from player %0.8x"), size, dwFrom );</P>
    4 N) ?; s0 W( I<P>    m_pNet-&gt;RejectClient( dwFrom, DISCONNNECT_REASON_CLIENT_OUT_OF_DATE );5 }$ {& e" }( ?% J! @
    }</P>/ K# G+ U8 j" ~: ~/ S

    8 [2 L4 I! p6 F" ^* B, G/ p<P>7 b+ t. D7 y0 l8 n- [
    //-----------------------------------------------------------------------------
    ' y$ \! W/ J" ~# y// Name: ; x' A; U2 S( `" w; x* U
    // Desc: 9 W5 F% u1 Z  \; s0 j
    //-----------------------------------------------------------------------------( G% Y! W4 d$ V& n% i! @, |$ u
    DWORD   CMazeServer::IDHash( DWORD id )
    0 w* k7 _9 t% F4 F: r2 w. M{
    3 R6 D- s# A8 G7 w    DWORD   hash = ((id) + (id&gt;&gt;8) + (id&gt;&gt;16) + (id&gt;&gt;24)) &amp; (NUM_ID_HASH_BUCKETS-1);7 n4 H; O6 N7 K* {8 i
        return hash;5 d5 |/ G9 M% p4 o: w0 Y3 g
    }</P>
    3 [5 B, {7 |" t! X5 Y/ g& r0 ^  n0 E( ~
    <P>
    4 V0 D/ s+ s& r' D/ Y4 N, o//-----------------------------------------------------------------------------
    , \+ f. l' _; s. `4 L0 ~1 p: j1 W// Name:
    1 |! U/ o( f$ J$ i# ~4 F  n// Desc:
    & y* F4 `4 g- t8 j/ J; _& ^//-----------------------------------------------------------------------------
    2 A. r" f# ~* y- S$ L" S1 Dvoid CMazeServer::RemovePlayerDataID( PlayerData* pPlayerData )
    5 g, z5 \9 e8 x+ V{; F" i0 r1 E$ n4 T2 R/ j
        // Hash the ID to a bucket number) S' r& P$ I2 s, `6 P2 x# {
        DWORD   bucket = IDHash( pPlayerData-&gt;NetID );</P>4 R2 i/ D/ x9 z/ m
    <P>    // Lock that hash bucket4 Z: a3 S9 c- W: j0 w$ a0 P
        const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;
    : d% D( U9 h6 d9 y- x4 i: y    m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>0 O( X" G; x! X6 c7 m. x* ]* `* y
    <P>    // Loop though players in bucket until we find the right one
    " }6 ^9 x# |2 W; i: a9 ?. `    PlayerData* pPt = m_pstIDHashBucket[bucket];6 [1 P5 M, ^9 f& ~" I  d8 l2 `6 x/ u
        PlayerData* pPrev = NULL;! X; K* r2 _+ |
        while( pPt )7 D, \; N& K! ?9 F) D
        {7 [7 T2 l3 o' n, n1 @9 j
            if( pPt == pPlayerData )
    ! f4 L; X3 R" f3 b3 a' l            break;
    9 f" i8 u! p9 h1 V0 P( z        pPrev = pPt;
    * L6 Z( w, l* X        pPt = pPt-&gt;pNextInIDHashBucket;4 ~: K" {/ C. m/ T7 P6 F
        }</P>
    5 ^4 e& L: M2 {4 D$ p/ m. w% s  d+ T<P>    if( pPt )$ k; z3 }* ^7 w3 [: N" g( B
        {& s: K4 U$ e; c$ a1 E
            if( pPrev )
    - ~* v% s9 G, f/ C/ \8 D& T            pPrev-&gt;pNextInIDHashBucket = pPt-&gt;pNextInIDHashBucket;
    # ?6 `9 `4 F: S/ g        else
    ( J8 `9 N; j& g4 a7 ?7 M            m_pstIDHashBucket[bucket] = pPt-&gt;pNextInIDHashBucket;/ ]. y1 }& B# T4 `3 @
            pPt-&gt;pNextInIDHashBucket = NULL;5 ?4 z  o+ F/ R* ?
        }</P>
    % g' |9 K; @5 C$ C3 X4 y<P>    // Unlock the hash bucket
    ) \  `+ M2 |. w    m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();
    % Z' U* c- s4 H1 Y$ q4 K3 x}</P>$ g5 g; E; j7 D& S
    0 L# v) d: v! K+ @7 u% C
    <P>  B/ z3 Q+ M; _* n( A
    //-----------------------------------------------------------------------------+ ]8 b0 K0 X. h, I! \/ X" G$ m0 P
    // Name:
    $ F# [6 O3 X* f- b+ P1 b// Desc: - m! j1 z3 L& _
    //-----------------------------------------------------------------------------: J6 f* V3 O5 ~( X5 D( |
    void CMazeServer::SetPlayerDataForID( DWORD id, PlayerData* pPlayerData )
    4 G( {$ S8 a+ h% j1 [1 L, @/ r3 q{
    $ I1 ?6 T$ X; H8 z! A' h' i: a    // Make sure this player isn't added twice to the m_pstIDHashBucket[]
    & w1 z  ^3 c" ]5 d' k    // otherwise there will be a circular reference% x# J8 d  m, O8 Y& w
        PlayerData* pSearch = GetPlayerDataForID( id );
    7 f; i) v# L  e8 H( L+ H    if( pSearch != NULL )
    ; ^  }0 j1 z) Q  q; Y        return;</P>' d, h& a6 Y6 i
    <P>    // Hash the ID to a bucket number) a  P+ @7 o5 f2 ^
        DWORD   bucket = IDHash( id );</P>
    ( o: w% o  t3 ?% A- X! n" K<P>    // Lock that hash bucket
    * l8 R3 @; s1 [- R. G" u    const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;
    . q% r0 W9 m: y! D3 s% N    m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>
    ) f0 X5 Z/ |$ n7 K5 g7 u<P>    // Add player onto hash bucket chain
    + Z5 I3 I5 H% k$ @, @' A' \5 Y. ^    pPlayerData-&gt;pNextInIDHashBucket = m_pstIDHashBucket[bucket];
    9 a* D3 b) H( x6 m" d3 p    m_pstIDHashBucket[bucket] = pPlayerData;</P>
    $ Q# {1 V' L  J1 n; B6 C; v<P>    // Store net id in player) x0 a* P/ L; {) g! q$ Q2 E. Z
        pPlayerData-&gt;NetID = id;</P># N1 ~( A' P" w/ l! S1 V% s% ?
    <P>    // Unlock the hash bucket
    $ z; U+ c4 X1 C8 ?* b- g6 ]! Z) g# P    m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();( k8 w) ^1 M% N& n8 d
    }</P>
    * Y& g- w5 D1 a) {
    1 l) p' ~) e. s7 Y<P>
    5 w2 D$ [: {1 M% N+ [//-----------------------------------------------------------------------------7 g- a8 h* k; O3 c& Z% R
    // Name:
    9 T: T7 c6 h7 ^! B// Desc: : G% P/ b4 d# T3 }: ~4 ]
    //-----------------------------------------------------------------------------" X* g0 n9 c: \. X5 M9 T
    PlayerData* CMazeServer::GetPlayerDataForID( DWORD id )* G0 C# U  P/ W0 z2 x- Y2 ]
    {
    7 e. S* Y1 M8 |+ @6 {6 P    // Hash the ID to a bucket number
    3 S% Q/ _  ^! ^* `7 ~5 ^' F    DWORD   bucket = IDHash( id );</P>( f- U8 B9 `/ O
    <P>    // Lock that hash bucket
    * {$ a0 M8 ?/ l    const   DWORD   buckets_per_lock = NUM_ID_HASH_BUCKETS / NUM_ID_HASH_BUCKET_LOCKS;5 b4 U5 x/ _* _' _" g, `$ L) O
        m_IDHashBucketLocks[bucket/buckets_per_lock].Enter();</P>
    ( T  L9 K0 @# _# Y4 F" M3 k<P>    // Loop though players in bucket until we find the right one; K# S$ @* }# M  T7 C) l
        PlayerData* pPlayerData = m_pstIDHashBucket[bucket];. U' Y7 g2 h- b7 q/ F$ i+ Z! D% M
        while ( pPlayerData )) N6 K6 M5 ^5 Q! a: \
        {
    & L1 @, F! Y3 F& O+ Z; C# _        if( pPlayerData-&gt;NetID == id )
    9 f* l" M3 E$ b8 @) j            break;
    6 U6 V0 R% ^0 H  P/ d4 h        pPlayerData = pPlayerData-&gt;pNextInIDHashBucket;
    ; Y4 I  G) @9 t% o8 k) Q# I    }</P>
    " I7 p+ l, \' e# O% i2 X+ N7 g<P>    // Unlock the hash bucket" I, D. x$ U- E& y' q
        m_IDHashBucketLocks[bucket/buckets_per_lock].Leave();</P>
    8 c4 D4 P* H# N) x# h" L<P>    // Return the player we found (will be NULL if we couldn't find it)
    ; [  t8 L" S  X& t    return pPlayerData;. L% K$ N3 O$ z8 L- k2 |. T
    }</P>
    ( r3 ?6 {+ L5 K# U7 s
    $ l; d/ M; ^! D9 c  v1 Q: U9 D  L<P>3 c+ z7 ]7 F# E4 w1 L3 @& H6 _; s
    //-----------------------------------------------------------------------------9 H8 `/ q: O3 W2 V% h1 T* q3 ~9 {
    // Name:
    ) \# W$ u- J0 X9 Z) Y, m; d. q' L// Desc: calls DisplayConnectionInfo for each connection in a round-robin manner- C% B1 e4 W0 T! v
    //-----------------------------------------------------------------------------, T/ b- d3 A+ x5 v  k6 B1 n
    void CMazeServer:isplayNextConnectionInfo()
    & Z$ ?: W& S( f' g- m+ ^3 T0 W{6 ~/ h! g8 v" d' z. D
        if( m_pNet )
    2 s7 S% q# h+ A  C1 J$ j0 R3 _    {
    0 q$ p& _- p/ {% C) c2 @9 x% ~        // Find the player that was displayed the longest time ago, and display it.9 z. F* d, c% W  z/ {  B
            FLOAT fCurTime = DXUtil_Timer( TIMER_GETAPPTIME );" H, a# e9 ?" q; J0 _. U! n
            PlayerData* pOldestPlayerData = NULL;
    / e- Z5 i+ y7 s& l        FLOAT fOldestTime = 0.0f;</P>- R$ F& U0 a* K6 n0 I, G! m9 Y$ _
    <P>        m_PlayerDataListLock.Enter();</P>
    ' o: j2 T% u9 _" e# b/ N<P>        PlayerData* pPlayerData = m_pFirstActivePlayerData;
    - [5 F2 Z7 i. e$ ]- H* S        while ( pPlayerData )& {) j9 J( v: O$ |
            {& X; p0 l$ w# H+ _% \% R
                if( fCurTime - pPlayerData-&gt;fLastCITime &gt; fOldestTime )
    " x0 T- o. u$ Y# i' F# p) ^# z            {
    , {' w  b4 X3 g$ m/ d# R                fOldestTime  = fCurTime - pPlayerData-&gt;fLastCITime;
    # r+ w5 e# K9 {7 }, V                pOldestPlayerData = pPlayerData;
    . Y. H/ F8 B8 T7 i) P            }</P>& k4 l3 m; V* ^0 s
    <P>            pPlayerData = pPlayerData-&gt;pNext;: ^& ]3 a3 j8 k  o8 N4 I9 p* U
            }</P>6 I6 g' H; x7 v2 I
    <P>        // Display the player with the oldest CI field, and update its CI field.' W0 @2 N" x$ X. M% _5 `/ a
            if( pOldestPlayerData )  f" y  a) A3 N# T; l+ Z' C& v* M
            {
    7 e0 Y" D8 G  Q$ m, S$ M# U            ConsolePrintf( SLINE_LOG, TEXT("Displaying connection info for next player") );
    . i! m4 m, k9 y            DisplayConnectionInfo( pOldestPlayerData-&gt;NetID );/ i- H1 M  J. X& N1 {
                pOldestPlayerData-&gt;fLastCITime = fCurTime;
    ; X5 I5 E; U2 _' a8 b3 i        }" Y/ V5 e8 s3 R* L" Q
            else8 P4 D6 ~7 K; n0 V/ v
            {3 y: `, [2 `. d* z' Y$ D; q
                ConsolePrintf( SLINE_LOG, TEXT("No players found") );1 Q# o) a6 s  w# H& m0 o
            }</P>0 A/ V4 n. J, e# }, B; Q
    <P>        m_PlayerDataListLock.Leave();
    . s+ p5 {1 }# S    }
    6 M: E7 ]* p: g  y3 |}</P>& i  [9 }4 ]" e6 A1 m

    . B5 o8 e6 S5 I<P>
    " [: t0 \1 m# H" y5 t; t: t//-----------------------------------------------------------------------------
    3 I# {/ D* b6 i; J, {) R// Name: ) m6 O! {. E4 t3 b
    // Desc:   g$ a* T8 J( o
    //-----------------------------------------------------------------------------
    * H" z! W) D& X4 Yvoid CMazeServer:rintStats()  c3 C2 v! z& F! p5 d5 f0 [
    {
    6 ]. D9 B& M( g; m9 F$ P! \    ConsolePrintf( SLINE_LOG, TEXT("Thread count: Active=%d Avg=%.2f Max=%d"), 5 w: c' k# ]" G2 P: l
                                        m_wActiveThreadCount, m_fAvgThreadCount, m_wMaxThreadCount );
    3 G# y% f  n+ M# K9 n" p9 W    ConsolePrintf( SLINE_LOG, TEXT("Thread Time: Avg=%.4f Max=%.4f(s)"),9 Q$ |) d9 S) i, y. M. G. X
                                        m_fAvgThreadTime, m_fMaxThreadTime );
    4 e) n  a. T' S2 L  Y8 F9 O  i    ConsolePrintf( SLINE_LOG, TEXT("Players online (not including server player): %d"), m_dwPlayerCount );
    / G$ A7 P( u% N3 Z0 M# N6 A& G    ConsolePrintf( SLINE_LOG, TEXT("Peak player count: %d"), m_dwPeakPlayerCount );
    9 p* f" b3 K4 z" t' ]}</P>
    + V3 f( _  i+ K( A7 h; w, p+ b% R% O' C. P
    <P>$ i0 C+ Y% S# W. y
    //-----------------------------------------------------------------------------; k. w* y* C2 H( O+ t
    // Name: 6 e4 w5 `5 C0 ^6 H5 }, i% u5 {8 r
    // Desc:
      `* H3 t$ I+ e) n; V! D  J//-----------------------------------------------------------------------------
    & ~4 v/ G6 [$ evoid CMazeServer:isplayConnectionInfo( DWORD dwID )# a) S6 ?5 v, T# F0 M- q& H& }/ S
    {
    9 @( y- ?' c+ {# g    TCHAR strInfo[5000];
    $ `8 s) V5 Z- H; d% S4 G# b; L    TCHAR* strEndOfLine;$ S% W' E$ J& X+ E
        TCHAR* strStartOfLine;</P>
    " r: Z; v+ F7 z. J0 e+ }' M0 D<P>    // Query the IOutboudNet for info about the connection to this user) Y) L: P7 ]! S: |
        m_pNet-&gt;GetConnectionInfo( dwID, strInfo );</P>
    ' v8 t5 |! G  _  ^! ~<P>    ConsolePrintf( SLINE_LOG, TEXT("Displaying connection info for %0.8x"), dwID );
    3 {  s& m7 J8 h; ]    ConsolePrintf( SLINE_LOG, TEXT("(Key: G=Guaranteed NG=Non-Guaranteed B=Bytes P=Packets)") );</P>
    9 Y& V( o; _% x<P>    // Display each line seperately* i  g9 P6 R# D6 }4 P
        strStartOfLine = strInfo;) ~4 f9 Q6 T" E& ^6 X
        while( TRUE )
    ) i! z# j9 |% U    {# D: _- u- M) l& R
            strEndOfLine = _tcschr( strStartOfLine, '\n' );0 c. V9 o; ^6 Y8 c) p6 ]5 A
            if( strEndOfLine == NULL )# a1 g8 _$ k% E; K- o/ d  p1 _
                break;</P>/ l% }. @$ @8 x- e9 y' ^
    <P>        *strEndOfLine = 0;
    % n6 c9 {" O- N4 k# Z' x! C8 y        ConsolePrintf( SLINE_LOG, strStartOfLine );9 Z9 K: `! y! D
            strStartOfLine = strEndOfLine + 1;
    4 ~( f, c7 n9 n' O    }! Q3 c+ w6 \- i$ k9 J
    }</P>) M0 [0 w& F0 k6 K$ v) S8 z
    6 b3 s& ]& W9 I+ `/ R. q) A& t
    <P>
      T7 ?) A% I0 N) O/ b3 y//-----------------------------------------------------------------------------
    ! b9 ^6 @& a- \$ V// Name: # X  K4 {- f4 c5 }, q- N
    // Desc: $ I5 q3 ?* |8 i: s& B8 V
    //-----------------------------------------------------------------------------/ `5 i) T3 [* ]
    HRESULT CMazeServer::SendPacket( DWORD to, void* pData, : E2 B. q3 o; m8 ]% u/ F( d0 S
                                     DWORD size, BOOL reliable, DWORD dwTimeout )* k' U9 d: x' _  @1 o8 S
    {+ G: j8 E  E3 e+ q. A6 Y: E# H
        // Chance of forcing any packet to be delivered reliably- G6 D$ X' {) a" R
        if( m_Rand.Get( 100 ) &lt; m_dwServerReliableRate )
    / `3 R: ?+ l6 d4 k- i2 h1 m- E% U        reliable = TRUE;</P>
    3 s& U: ~# H6 l<P>    return m_pNet-&gt;SendPacket( to, pData, size, reliable, dwTimeout );7 ]- V- q: k% t6 f
    }</P>
    6 g# r8 e! P; L/ z0 B8 D. n5 E; s
    <P>
    8 V4 g, ~. F3 {6 S3 \* H7 C3 e; J  O//-----------------------------------------------------------------------------
    0 Y3 l4 d" Y" X9 A// Name:
    ) {" a1 G" z; u2 a5 V. l! w8 j// Desc:
    ; r* w' p5 E' ~2 o8 b//-----------------------------------------------------------------------------% D# ?; w2 T5 W8 D: F4 W
    void CMazeServer::SendConfigPacketToAll( ServerConfigPacket* pPacket )$ i* ]+ u) O9 f9 W: c
    {
      d$ K  w. G; [* y7 x    // If we're up and running, then send this new information to all clients8 F1 i8 H& ?9 P7 a0 ]8 p
        if( m_pNet )
    + R; r- Q* w( a: C7 _+ m. A0 `    {
    ) F. ?# f! k$ M8 E/ C        //Use the AllPlayers ID
    ( U* G8 Z, s# v$ r, R( b        SendPacket( DPNID_ALL_PLAYERS_GROUP, pPacket, sizeof(ServerConfigPacket), TRUE, 0 );& O1 G% g/ n& O
        }
    # `- F$ Z7 h4 G) D- v# W: z* L) O; s3 V}</P>
    ; p: b+ ?' z3 O
    7 \* ^" I8 U. d; ~<P>  {& y! Y, g2 N8 \7 o7 E( h6 ?
    //-----------------------------------------------------------------------------
    , d) v* R* w& `. M" N: |) t// Name:
    8 [  Z5 A" f. ~5 \// Desc: 1 D8 u$ C" Y( B5 r/ X# B
    //-----------------------------------------------------------------------------+ ?; X0 x9 H: |2 O% }$ j
    void CMazeServer::SetClientReliableRate( DWORD percent )/ \/ d+ a3 L% t# l2 s9 R( ^
    {4 [: w$ C! K& c, y* _
        // Update client config, and build packet containing that data
    + Q1 I) Q7 P. F3 V$ M+ j$ P    m_ClientNetConfigLock.Enter();
    ! x8 D0 B* [, X3 h. _. I    m_ClientNetConfig.ubReliableRate = BYTE(percent);
    , C4 n! O* M/ P" |  [/ {    ServerConfigPacket packet( m_ClientNetConfig );
    # k( m5 z5 \3 n    m_ClientNetConfigLock.Leave();</P>
    ) d! u, T9 n! k: P2 U<P>    SendConfigPacketToAll( &amp;packet );
    ' |, g4 Q1 b* ?0 ?' m# `. T}</P>$ ^) P9 p8 c+ D
    + o* A3 z, Y) ]7 z9 o
    <P>1 P( ^8 a3 a( H
    //-----------------------------------------------------------------------------
    4 M- x; U% _  ?% U/ @: ^4 i// Name:
    * P) V, v9 b4 J) o* K3 ]2 R' G0 J// Desc:
    9 A3 h  k8 Y5 O& n. S! f/ ~0 H//-----------------------------------------------------------------------------
    , N6 N+ Z# i7 ^% @3 }void CMazeServer::SetClientUpdateRate( DWORD rate )
    . L# {1 T! Q& n& ?) c{  j- _8 f: L2 N# n# T1 V: A
        // Update client config, and build packet containing that data
    0 X# f" y2 ?( {! c5 T/ v    m_ClientNetConfigLock.Enter();
    8 n8 a# K- Z3 w    m_ClientNetConfig.wUpdateRate = WORD(rate);
    9 R3 \% q( I9 x0 [    ServerConfigPacket  packet( m_ClientNetConfig );3 j  S9 n8 _8 O2 e+ N2 W& r4 y
        m_ClientNetConfigLock.Leave();</P>$ y, r5 W) v  K" d
    <P>    SendConfigPacketToAll( &amp;packet );
    2 j) R, z0 d, X& ~' \}</P>
    & f1 a8 P0 E: K) ]* y. x
    1 o- t# a9 q4 U  u<P>
    * J% c: C/ h% d. d0 _1 \//-----------------------------------------------------------------------------0 Y& |) }3 c6 G
    // Name: 4 t+ N- q# I2 I
    // Desc: ; j5 u& V5 `& g7 v
    //-----------------------------------------------------------------------------
    8 N; s6 o6 O8 `8 gvoid CMazeServer::SetClientTimeout( DWORD timeout )( M* w4 s3 y: ]. a4 `9 J! W
    {7 R, g/ G) w3 K' V) H) B9 _
        // Update client config, and build packet containing that data
    3 B& J" Z) d1 d5 l    m_ClientNetConfigLock.Enter();" b$ M8 m; u: S, C5 G. I" \& T# Z
        m_ClientNetConfig.wTimeout = WORD(timeout);
    + z4 @- V9 ~9 ^    ServerConfigPacket  packet( m_ClientNetConfig );) u/ D) w* w* D7 C1 j( [9 v
        m_ClientNetConfigLock.Leave();</P>5 ~3 E, S  K6 j3 ^
    <P>    SendConfigPacketToAll( &amp;packet );6 C, D& O% f; r
    }</P>6 Z) i, i7 e/ {! v; k% J
    7 W* \" j0 {0 G, }  X8 @
    <P># H- ?: y& L9 d
    //-----------------------------------------------------------------------------
    6 R) s4 q1 L' B1 {  d; {5 P) b, e// Name: 8 F$ S1 }7 }7 g/ S$ a
    // Desc: : @, p8 x4 f( K% P, d
    //-----------------------------------------------------------------------------
    / L+ g# {! c6 G, ?( X' avoid CMazeServer::SetClientPackSize( DWORD size )5 K/ R; L& u; L) f' V6 t2 [$ [
    {2 |. @& `! t2 h) ]9 y
        // Update client config, and build packet containing that data% D8 q, ]& L' F0 A% ~  e/ h
        m_ClientNetConfigLock.Enter();3 Q9 m: f! y, y' k, f$ |( [! `
          r6 j( J; k, @' K
        m_ClientNetConfig.ubClientPackIndex++; //Increase index and verify location in array.
    8 K4 Y9 i" d9 v; r$ |7 }& K! M    if(m_ClientNetConfig.ubClientPackIndex &gt;= PACK_ARRAY_SIZE)   " h/ c5 H3 v6 }
            m_ClientNetConfig.ubClientPackIndex = 0;</P>" p4 I$ h  {0 R
    <P>    m_ClientNetConfig.wClientPackSizeArray[m_ClientNetConfig.ubClientPackIndex] = WORD(size);! X4 y2 A) u# o8 P. e. C
        ServerConfigPacket packet( m_ClientNetConfig );. n( Q7 ^5 W) v+ s" J/ H$ I9 f5 X: R
        m_ClientNetConfigLock.Leave();</P>% ]6 l- G5 |) P
    <P>    SendConfigPacketToAll( &amp;packet );8 w0 M8 K3 x9 s) i1 ^1 ]
    }</P>
    2 P, r3 `4 }. X6 a9 b, g5 k. F2 i8 R2 @% U, I2 ~
    <P>' n0 v0 [% Z2 @1 v- ~: H
    //-----------------------------------------------------------------------------
    4 J9 `) L0 ~; D6 X" r' x% i// Name: ; D+ z. n( v3 T
    // Desc: 0 b( D4 q4 i4 e& d3 \
    //-----------------------------------------------------------------------------6 d7 ?3 `! g7 Q" E! K, ~
    void CMazeServer::SetServerPackSize( DWORD size )) X& g  e% W9 u% x3 c, o  ]  l
    {
      p# b' a) p- C4 Y    // Update client config, and build packet containing that data
    9 p6 H: b! K) Y- s& m& \    m_ClientNetConfigLock.Enter();
    6 Q( j/ P  t8 T5 s) q    ( X9 L5 g9 }: S. b) V7 F
        m_ClientNetConfig.ubServerPackIndex++; //Increase index and verify location in array.2 O$ W, J6 X2 y2 A* o: ^4 X' F
        if(m_ClientNetConfig.ubServerPackIndex &gt;= PACK_ARRAY_SIZE)   
    . G% J% E/ H/ B# j        m_ClientNetConfig.ubServerPackIndex = 0;</P>
    : K0 [; P; J( P8 \$ G; }! ^. T<P>    m_ClientNetConfig.wServerPackSizeArray[m_ClientNetConfig.ubServerPackIndex] = WORD(size);
    3 h; ?& f2 t: J    ServerConfigPacket packet( m_ClientNetConfig );
    / Z$ n. h& e" b$ V& h/ ?) v* n    m_ClientNetConfigLock.Leave();</P>$ `- F. R! a' A/ N" W$ W
    <P>    SendConfigPacketToAll( &amp;packet );
    ; ~1 g2 v8 y  w: V9 v/ w}</P>8 D5 |  q' Q! R
    <P>
    . X2 C+ \! g- E4 m//-----------------------------------------------------------------------------
    6 d2 I; {: y) ?+ H5 z// Name:
    0 q. l! v( y6 J( K0 d// Desc: 9 @( h& y& V' W8 @5 d
    //-----------------------------------------------------------------------------9 _/ j% ]) A7 @
    void CMazeServer::SetClientThreadWait( DWORD dwThreadWait )
    $ W' y2 F( l5 q* e{
    & \9 p4 \; q3 D    // Update client config, and build packet containing that data
    5 T9 p6 o* l) A( t    m_ClientNetConfigLock.Enter();
    " S1 |' }, ~+ f6 _# h    - g% t$ }: Q, b  o! q4 @9 Y2 z$ V
        m_ClientNetConfig.dwThreadWait = dwThreadWait;' s, a6 K& k3 `0 z
        ServerConfigPacket packet( m_ClientNetConfig );
      d' x' s# i. J* ]- [    m_ClientNetConfigLock.Leave();</P>! C2 [$ g, X9 x  T7 _
    <P>    SendConfigPacketToAll( &amp;packet );+ J8 n$ J! }- q' g8 Y
    }</P></DIV>
    zan
    转播转播0 分享淘帖0 分享分享0 收藏收藏0 支持支持0 反对反对0 微信微信
    您需要登录后才可以回帖 登录 | 注册地址

    qq
    收缩
    • 电话咨询

    • 04714969085
    fastpost

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

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

    蒙公网安备 15010502000194号

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

    GMT+8, 2026-8-9 02:44 , Processed in 0.487241 second(s), 51 queries .

    回顶部