public static Response parseGameAction(MessageBuffer msg)
 {
     msg.reset();
       Int32 size = msg.popInt();
       Int16 action = msg.popShort();
       Int32 timeStep = msg.popInt();
       Int16 playerId = msg.popShort();
       Int32 xPos = msg.popInt();
       Int32 yPos = msg.popInt();
       switch (action)
       {
     case Constants.POINTER_LOCATION:
       return new PointerLocationResponse(timeStep, playerId, xPos, yPos);
     case Constants.SELECTED_CASTLE:
       return new SelectedCastleResponse(timeStep, playerId, xPos, yPos);
     case Constants.PLACED_CANNON:
       return new PlacedCannonResponse(timeStep, playerId, xPos, yPos);
     case Constants.FIRED_CANNON:
       return new FiredCannonResponse(timeStep, playerId, xPos, yPos);
     case Constants.ROTATED_WALL:
       return new RotatedWallResponse(timeStep, playerId, xPos, yPos);
     case Constants.PLACED_WALL:
       return new PlacedWallResponse(timeStep, playerId, xPos, yPos);
     default:
       return null;
       }
 }
 public static Response parseEndGame(MessageBuffer msg)
 {
     msg.reset();
       Int32 size = msg.popInt();
       Int16 action = msg.popShort();
       Int16 winnerID = msg.popShort();
       return new EndGameResponse(winnerID);
 }
 public static Response parseAuthAction(MessageBuffer msg)
 {
     msg.reset();
       Int32 size = msg.popInt();
       Int16 action = msg.popShort();
       Int16 result = msg.popShort();
       return new LoginResponse(result);
 }
 public static Response parseDenyJoinRoom(MessageBuffer msg)
 {
     msg.reset();
       Int32 size = msg.popInt();
       Int16 action = msg.popShort();
       string roomName = msg.popString();
       return new RoomNotJoinedResponse(roomName);
 }
 public byte[] makeDisconnectMessage(out int length, string username)
 {
     MessageBuffer msg = new MessageBuffer();
       msg.pushInt(0)
       .pushShort(Constants.DISCONNECT)
       .writeSize();
       length = msg.getPos();
       return msg.getData();
 }
 public static Response parseCreateRoom(MessageBuffer msg)
 {
     msg.reset();
       Int32 size = msg.popInt();
       Int16 action = msg.popShort();
       Int16 result = msg.popShort();
       string roomName = msg.popString();
       return new RoomCreatedResponse(result, roomName);
 }
 public byte[] makeGetAvailableRoomsMessage(out int length, string username)
 {
     MessageBuffer msg = new MessageBuffer();
       msg.pushInt(0)
       .pushShort(Constants.GET_AVAILABLE_ROOMS)
       .pushString(username)
       .writeSize();
       length = msg.getPos();
       return msg.getData();
 }
 public byte[] makeEndGameMessage(out int length, short player_id, short winner_id)
 {
     MessageBuffer msg = new MessageBuffer();
       msg.pushInt(0)
       .pushShort(Constants.END_GAME)
       .pushShort(player_id)
       .pushShort(winner_id)
       .writeSize();
       length = msg.getPos();
       return msg.getData();
 }
 public byte[] makeAuthorizationMessage(out int length, string username, string password)
 {
     MessageBuffer msg = new MessageBuffer();
       msg.pushInt(0)
       .pushShort(Constants.CLIENT_AUTH)
       .pushString(username)
       .pushString(password)
       .writeSize();
       length = msg.getPos();
       return msg.getData();
 }
 public byte[] makeCreateRoomMessage(out int length, string username, string roomname, Int16 capacity)
 {
     MessageBuffer msg = new MessageBuffer();
       msg.pushInt(0)
       .pushShort(Constants.CREATE_ROOM)
       .pushShort(capacity)
       .pushString(username)
       .pushString(roomname)
       .writeSize();
       length = msg.getPos();
       return msg.getData();
 }
 public static Response parseAllowJoinRoom(MessageBuffer msg)
 {
     msg.reset();
       Int32 size = msg.popInt();
       Int16 action = msg.popShort();
       Int16 numPlayers = msg.popShort();
       string roomName = msg.popString();
       List<string> playerNames = new List<string>(numPlayers);
       for (int i = 0; i < numPlayers; i++)
     playerNames.Add(msg.popString());
       return new RoomJoinedResponse(roomName, playerNames, numPlayers);
 }
 public byte[] makeGameActionMessage(out int length, Int16 action, Int32 timeStep, Int16 playerId, Int32 xPos, Int32 yPos)
 {
     MessageBuffer msg = new MessageBuffer();
       msg.pushInt(0)
       .pushShort(action)
       .pushInt(timeStep)
       .pushShort(playerId)
       .pushInt(xPos)
       .pushInt(yPos)
       .writeSize();
       length = msg.getPos();
       return msg.getData();
 }
 public byte[] makeStartGameMessage(out int length, string username, string map)
 {
     MessageBuffer msg = new MessageBuffer();
       msg.pushInt(0)
       .pushShort(Constants.START_GAME)
       .pushString(username)
       .pushString(map)
       .writeSize();
       length = msg.getPos();
       return msg.getData();
 }
 public static Response parseStartGame(MessageBuffer msg)
 {
     msg.reset();
       Int32 size = msg.popInt();
       Int16 action = msg.popShort();
       Int16 numPlayers = msg.popShort();
       List<Int16> playerIds = new List<Int16>(numPlayers);
       for (int i = 0; i < numPlayers; i++)
     playerIds.Add(msg.popShort());
       List<string> playerNames = new List<string>(numPlayers);
       for (int i = 0; i < numPlayers; i++)
     playerNames.Add(msg.popString());
       string map = msg.popString();
       return new StartGameResponse(playerNames, map);
 }
        public static Response parseSendAvailableRooms(MessageBuffer msg)
        {
            msg.reset();
              Int32 size = msg.popInt();
              Int16 action = msg.popShort();
              Int16 numRooms = msg.popShort();
              List<string> roomNames = new List<string>(numRooms);
              for (int i = 0; i < numRooms; i++)
            roomNames.Add(msg.popString());

              List<Room> rooms = new List<Room>(numRooms);
              for (int i = 0; i < numRooms; i++)
            rooms.Add(new Room(roomNames[i], 2));
              return new RoomsAvailableResponse(rooms);
        }
 public static Response parseLeaveRoom(MessageBuffer msg)
 {
     msg.reset();
       Int32 size = msg.popInt();
       Int16 action = msg.popShort();
       string userName = msg.popString();
       string roomName = msg.popString();
       return new PlayerLeftRoomResponse(userName, roomName);
 }
 public byte[] makeJoinRoomMessage(out int length, string username, string roomname)
 {
     MessageBuffer msg = new MessageBuffer();
       msg.pushInt(0)
       .pushShort(Constants.JOIN_ROOM)
       .pushString(username)
       .pushString(roomname)
       .writeSize();
       length = msg.getPos();
       return msg.getData();
 }
        /**
         * @brief Parse the given packet, transforming it into an instance of the appropriate Response-derived class
         * @param packet the entire packet buffer, including the header consisting of the size and action
         * @return Response represetnting response to message parsed.
         */
        public static Response parsePacket(byte[] packet)
        {
            MessageBuffer msg = new MessageBuffer(packet);
              Response resp = null;

              Int32 size = msg.popInt();
              Int16 action = msg.popShort();
              switch (action)
              {
            case Constants.SERVER_AUTH_ACTION:
              resp = parseAuthAction(msg);
              break;

            case Constants.SERVER_SEND_AVAILABLE_ROOMS_ACTION:
              resp = parseSendAvailableRooms(msg);
              break;

            case Constants.SERVER_CREATE_ROOM_ACTION:
              resp = parseCreateRoom(msg);
              break;

            case Constants.SERVER_ALLOW_JOIN_ROOM_ACTION:
              resp = parseAllowJoinRoom(msg);
              break;

            case Constants.SERVER_DENY_JOIN_ROOM_ACTION:
              resp = parseDenyJoinRoom(msg);
              break;

            case Constants.SERVER_PLAYER_JOINED_ROOM_ACTION:
              resp = parsePlayerJoinedRoom(msg);
              break;

            case Constants.SERVER_LEAVE_ROOM_ACTION:
              resp = parseLeaveRoom(msg);
              break;

            case Constants.SERVER_OWNER_LEFT_ROOM_ACTION:
              resp = parseOwnerLeftRoom(msg);
              break;

            case Constants.SERVER_START_GAME_ACTION:
              resp = parseStartGame(msg);
              break;
            case Constants.END_GAME:
              resp = parseEndGame(msg);
              break;
            case Constants.POINTER_LOCATION:
              resp = parseGameAction(msg);
              break;
            case Constants.SELECTED_CASTLE:
              resp = parseGameAction(msg);
              break;
            case Constants.PLACED_CANNON:
              resp = parseGameAction(msg);
              break;
            case Constants.FIRED_CANNON:
              resp = parseGameAction(msg);
              break;
            case Constants.ROTATED_WALL:
              resp = parseGameAction(msg);
              break;
            case Constants.PLACED_WALL:
              resp = parseGameAction(msg);
              break;
            default:
              resp = null;
              break;
              }
              return resp;
        }