context: /*
   * Copyright (c) 2010 Jopirop
   * 
   * All rights reserved.
   * 
   */
  
  using System;
  using System.Collections.Generic;
  using System.Linq;
  using System.Text;
  using System.Net.Sockets;
  
  namespace Cyclops {
      /// <summary>
      ///  This is the class that handles all of the protocol receving
      ///  related information. It must encapsulate protocol receving
      ///  and therefore any protocol receving related information 
      ///  should only be stored here.
      /// </summary>
      public class ProtocolReceive65 : ProtocolReceive {
          private delegate void ProcessMessage(Player player, GameWorld world);
          private ProcessMessage[] messageDecoder;
          private const byte HEADER_MAX_VAL = 0xFF;
          private const byte MAX_STRING_LENGTH = 140;
          private Object lockThis;
  
          /// <summary>
          /// Checks to make sure a direction is valid.
          /// </summary>
          /// <param name="rawDirection">The direction as a byte.</param>
          /// <returns>True if the direction is valid, false otherwise.</returns>
          private bool IsDirectionValid(byte rawDirection) {
              return (Enum.IsDefined(typeof(Direction), rawDirection));
          }
  
          /// <summary>
          /// Process when a player closes a container.
          /// </summary>
          /// <param name="player">The player who closes the container.</param>
          /// <param name="world">A reference to the gameworld.</param>
          private void ProcessCloseContainer(Player player, GameWorld world) {
              byte localID = netmsg.GetByte();
              if (localID > Constants.MAX_CONTAINERS) {
                  return;
              }
              world.HandleCloseContainer(player, localID);
          }
  
          /// <summary>
          /// Process when a player auto walks.
          /// </summary>
          /// <param name="player">The player who auto walked.</param>
          /// <param name="world">A reference to the gameworld.</param>
          private void ProcessAutoWalk(Player player, GameWorld world) {
              Position pos = netmsg.GetPosition();
  #if DEBUG
              Log.WriteDebug("In ProcessAutoWalk()");
              Log.WriteDebug("pos: " + pos);
  #endif
              world.HandleAutoWalk(player, pos);
          }
  
          /// <summary>
          /// Process when a player looks at something.
          /// </summary>
          /// <param name="player">The player who is looking.</param>
          /// <param name="world">A reference to the gameworld.</param>
          private void ProcessLookAt(Player player, GameWorld world) {
              //Position player is looking at
              Position pos = netmsg.GetPosition();
  #if DEBUG
              Log.WriteDebug("In ProcessLookAt()");
              Log.WriteDebug("pos: " + pos);
  #endif
              world.HandleLookAt(player, pos);
          }
  
          /// <summary>
          /// Process when a player changes fightMode or fightStance.
          /// </summary>
          /// <param name="player">The player changing the mode.</param>
          /// <param name="world">A reference to the gameworld.</param>
          private void ProcessChangeMode(Player player, GameWorld world) {
              byte rawFightMode = netmsg.GetByte(); //Agressive, normal, defensive
              byte rawFightStance = netmsg.GetByte(); //Follow, run away, stand still
              bool isFightModeValid = Enum.IsDefined(typeof(FightMode), rawFightMode);
              bool isFightStanceValid = Enum.IsDefined(typeof(FightStance), rawFightStance);
  
              //Make sure modes are valid
              if (!isFightModeValid || !isFightStanceValid) {
                  return;
              }
  
              FightMode fightMode = (FightMode)rawFightMode;
              FightStance fightStance = (FightStance)rawFightStance;
  #if DEBUG
              Log.WriteDebug("In ProcessChangeMode()");
              Log.WriteDebug("fightMode: " + fightMode);
              Log.WriteDebug("fightStance: " + fightStance);
  #endif
              world.HandleChangeMode(player, fightMode, fightStance);
          }
  
          /// <summary>
          /// Process when a player leaves his battle screen.
          /// </summary>
          /// <param name="player">The player who exits his battle screen.</param>
          /// <param name="world">A reference to the gameworld.</param>
          private void ProcessExitBattle(Player player, GameWorld world) {
  #if DEBUG
              Log.WriteDebug("In ProcessExitBattle()");
  #endif
              world.HandleExitBattle(player);
          }
  
          /// <summary>
          /// Process when a player uses an item.
          /// </summary>
          /// <param name="player">The player who uses the item.</param>
          /// <param name="world">A reference to the gameworld.</param>
          private void ProcessUseItem(Player player, GameWorld world) {
              byte itemType = netmsg.GetByte(); //1 = regular, 2 = usable with
              Position pos = netmsg.GetPosition();
              ushort itemID = netmsg.GetU16();
              byte stackpos = netmsg.GetByte();
  
              byte unknownByte = netmsg.GetByte(); //unknown?? TODO: Figure out
  
  #if DEBUG
              Log.WriteDebug("In ProcessUseItem()");
              Log.WriteDebug("itemType: " + itemType);
              Log.WriteDebug("pos: " + pos);
              Log.WriteDebug("itemID: " + itemID);
              Log.WriteDebug("stackpos: " + stackpos);
              Log.WriteDebug("unknownbyte: " + unknownByte);
  #endif
  
              if (itemType == Constants.ITEM_TYPE_USE) {
                  world.HandleUseItem(player, itemType, pos, itemID, stackpos);
              } else if (itemType == Constants.ITEM_TYPE_USE_WITH) {
                  Position posWith = netmsg.GetPosition();
                  ushort spriteIDWith = netmsg.GetU16();
                  byte stackposWith = netmsg.GetByte();
  #if DEBUG
                  Log.WriteDebug("posWith: " + posWith);
                  Log.WriteDebug("spriteid with: " + spriteIDWith);
                  Log.WriteDebug("stackPos: " + stackposWith);
  
  #endif
                  world.HandleUseItemWith(player, itemType, pos, itemID,
                      stackpos, posWith, stackposWith);
              }
  
  
  
              /*if (Item.CreateItem(itemID).IsOfType(Constants.TYPE_USEABLE_WITH)) {
                  Position posWith = netmsg.GetPosition();
                  world.SendPlayerUseItem(p, pos, itemID, stackpos, posWith);
              } else {
                  world.SendPlayerUseItem(p, pos, itemID, stackpos, null);
              }*/
          }
  
          /// <summary>
          /// Process when a player says something.
          /// </summary>
          /// <param name="player">The player who is talking.</param>
          /// <param name="world">A reference to the gameworld.</param>
          private void ProcessChat(Player player, GameWorld world) {
              string msg; //Thing that the player is saying
              msg = netmsg.GetStringL();
  
              //Test for acceptable string length
              if (msg.Length > MAX_STRING_LENGTH) {
                  return;
              }
  #if DEBUG
              Log.WriteDebug("In ProcessChat()");
              Log.WriteDebug("msg: " + msg);
  #endif
              world.HandleChat(player, msg);
          }
  
          /// <summary>
          /// Processes a client "bounce back" message.
          /// </summary>
          /// <param name="player">The client's player who sent the message.</param>
          /// <param name="world">A reference to the gameworld.</param>
          private void ProcessBounceBack(Player player, GameWorld world) {
  #if DEBUG
              Log.WriteDebug("In ProcessBounceBack()");
  #endif
              world.HandleBounceBack(player);
          }
  
          /// <summary>
          /// Process a player's push.
          /// </summary>
          /// <param name="player">The player doing the action.</param>
          /// <param name="world">A reference to the gameworld.</param>
          private void ProcessPush(Player player, GameWorld world) {
              Position posFrom = netmsg.GetPosition();
              ushort thingID = netmsg.GetU16();
              byte stackpos = netmsg.GetByte();
              Position posTo = netmsg.GetPosition();
              byte count = netmsg.GetByte();
  #if DEBUG
              Log.WriteDebug("In ProcessPush()");
              Log.WriteDebug("posFrom: " + posFrom);
              Log.WriteDebug("thingID: " + thingID);
              Log.WriteDebug("stackpos: " + stackpos);
              Log.WriteDebug("posTo: " + posTo);
              Log.WriteDebug("count: " + count);
  #endif
              if (count == 0) {
                  return;
              }
              world.HandlePush(player, posFrom, thingID, stackpos, posTo, count);
          }
  
          /// <summary>
          /// Process a player's walk.
          /// </summary>
          /// <param name="player">The player doing the action.</param>
          /// <param name="world">A reference to the gameworld.</param>
          private void ProcessWalk(Player player, GameWorld world) {
              byte rawDirection = netmsg.GetByte();
  
              //Validate direction
              if (!IsDirectionValid(rawDirection))
                  return;
  
              Direction direction; //direction to move
  
              direction = (Direction)rawDirection;
  #if DEBUG
              Log.WriteDebug("In ProcessWalk()");
              Log.WriteDebug("direction: " + direction);
  #endif
              world.HandleManualWalk(player, direction);
  
              /* p.SetTargetPosition(null);
  
  
gt:              if (p.GetLastWalk().Elapsed()) //Enough time passed