readSingleUser :: IO Word8 -> (Int -> IO [Word8]) -> IO Word16 -> IO Int -> (Int -> IO String) -> IO Inbound.UserData
readSingleUser readByte readBytes readShort readInt readText =
  do
    let toPairs (propId:propCrc:xs) = (propId,propCrc) : toPairs xs
        toPairs _ = []
        
    userId <- readInt
    y <- fromIntegral <$> readShort
    x <- fromIntegral <$> readShort
    propInfos <- sequence $ replicate 18 readInt  -- 9 slots for prop images - pairs of prop ID and propCrc (PalaceProtocol specific?)
    roomId <- fromIntegral <$> readShort
    face <- fromIntegral <$> readShort
    color <- fromIntegral <$> readShort
    _ <- readShort -- 0?
    _ <- readShort -- 0?
    numberOfProps <- fromIntegral <$> readShort
    userNameLength <- fromIntegral <$> readByte
    userName <- readText userNameLength
    _ <- readBytes $ 31 - userNameLength

    let propsList = toPairs propInfos
        propInfo = Inbound.PropInfo {
            Inbound.numberOfProps = numberOfProps
          , Inbound.props = take numberOfProps propsList
          }
    return $ Inbound.UserData { 
        Inbound.userId = userId
      , Inbound.userName = userName
      , Inbound.userRoomId = roomId
      , Inbound.userCoordinates = Inbound.CartesianCoordinates { Inbound.xPos = x, Inbound.yPos = y }
      , Inbound.userFaceInfo = Inbound.UserFaceInfo { Inbound.userFace = face, Inbound.userColor = color }
      , Inbound.userPropInfo = propInfo
      }
readSingleUser :: IO Word8 -> (Int -> IO [Word8]) -> IO Word16 -> IO Int -> (Int -> IO String) -> IO Inbound.UserData
readSingleUser readByte readBytes readShort readInt readText =
  do
    let toPairs (propId:propCrc:xs) = (propId,propCrc) : toPairs xs
        toPairs _ = []
        
    userId <- readInt
    y <- fromIntegral <$> readShort
    x <- fromIntegral <$> readShort
    propInfos <- sequence $ replicate 18 readInt  -- 9 slots for prop images - pairs of prop ID and propCrc (PalaceProtocol specific?)
    roomId <- fromIntegral <$> readShort
    face <- fromIntegral <$> readShort
    color <- fromIntegral <$> readShort
    _ <- readShort -- 0?
    _ <- readShort -- 0?
    numberOfProps <- fromIntegral <$> readShort
    userNameLength <- fromIntegral <$> readByte
    userName <- readText userNameLength
    _ <- readBytes $ 31 - userNameLength

    let propsList = toPairs propInfos
        propInfo = Inbound.PropInfo {
            Inbound.numberOfProps = numberOfProps
          , Inbound.props = take numberOfProps propsList
          }
    return $ Inbound.UserData { 
        Inbound.userId = userId
      , Inbound.userName = userName
      , Inbound.userRoomId = roomId
      , Inbound.userCoordinates = Inbound.CartesianCoordinates { Inbound.xPos = x, Inbound.yPos = y }
      , Inbound.userFaceInfo = Inbound.UserFaceInfo { Inbound.userFace = face, Inbound.userColor = color }
      , Inbound.userPropInfo = propInfo
      }
readSingleUser readByte readBytes readShort readInt readText =
  do
    let toPairs (propId:propCrc:xs) = (propId,propCrc) : toPairs xs
        toPairs _ = []
        
    userId <- readInt
    y <- fromIntegral <$> readShort
    x <- fromIntegral <$> readShort
    propInfos <- sequence $ replicate 18 readInt  -- 9 slots for prop images - pairs of prop ID and propCrc (PalaceProtocol specific?)
    roomId <- fromIntegral <$> readShort
    face <- fromIntegral <$> readShort
    color <- fromIntegral <$> readShort
    _ <- readShort -- 0?
    _ <- readShort -- 0?
    numberOfProps <- fromIntegral <$> readShort
    userNameLength <- fromIntegral <$> readByte
    userName <- readText userNameLength
    _ <- readBytes $ 31 - userNameLength

    let propsList = toPairs propInfos
        propInfo = Inbound.PropInfo {
            Inbound.numberOfProps = numberOfProps
          , Inbound.props = take numberOfProps propsList
          }
    return $ Inbound.UserData { 
        Inbound.userId = userId
      , Inbound.userName = userName
      , Inbound.userRoomId = roomId
      , Inbound.userCoordinates = Inbound.CartesianCoordinates { Inbound.xPos = x, Inbound.yPos = y }
      , Inbound.userFaceInfo = Inbound.UserFaceInfo { Inbound.userFace = face, Inbound.userColor = color }
      , Inbound.userPropInfo = propInfo
      }