예제 #1
0
// Login request (http://mc.kev009.com/wiki/Protocol#Login_Request_.280x01.29)
int PacketHandler::login_request(User *user)
{
  //Check that we have enought data in the buffer
  if(user->buffer.size() < 12)
    return PACKET_NEED_MORE_DATA;

  uint32 curpos = 0;
  int i;

  //Client protocol version
  uint8 tmpIntArray[4] = {0};
  for(i = 0; i < 4; i++)
    tmpIntArray[i] = user->buffer[curpos+i];
  int version = getUint32(&tmpIntArray[0]);
  curpos += 4;

  //Player name length
  uint8 tmpShortArray[2] = {0};
  for(i = 0; i < 2; i++)
    tmpShortArray[i] = user->buffer[curpos+i];
  int len = getUint16(&tmpShortArray[0]);
  curpos += 2;

  //Check for data
  if(user->buffer.size() < curpos+len+2)
    return PACKET_NEED_MORE_DATA;


  std::string player;
  //Read player name
  for(int pos = 0; pos < len; pos++)
  {
    player += user->buffer[curpos+pos];
  }
  curpos += len;


  //Password length
  for(i = 0; i < 2; i++)
    tmpShortArray[i] = user->buffer[curpos+i];
  len     = getUint16(&tmpShortArray[0]);
  curpos += 2;

  std::string passwd;
  //Check for data
  if(user->buffer.size() < curpos+len)
    return PACKET_NEED_MORE_DATA;


  //Read password
  for(int pos = 0; pos < len; pos++)
  {
    passwd += user->buffer[curpos+pos];
  }
  curpos += len;

  //Package completely received, remove from buffer
  user->buffer.erase(user->buffer.begin(), user->buffer.begin()+curpos);

  std::cout << "Player " << user->UID << " login v." << version <<" : " << player <<":"<<
  passwd << std::endl;

  // If version is not 2 or 3
  if(version != 4 && version != 3 && version != 2)
  {
    user->kick(Conf::get().sValue("wrong_protocol_message"));
    return curpos;
  }

  // If userlimit is reached
  if((int)Users.size() >= Conf::get().iValue("userlimit"))
  {
    user->kick(Conf::get().sValue("server_full_message"));
    return curpos;
  }

  user->changeNick(player);

  //Load user data
  user->loadData();

  //Login OK package
  char data[9] = {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
  putSint32((uint8 *)&data[1], user->UID);
  bufferevent_write(user->buf_ev, (char *)&data[0], 9);

  //Send server time (after dawn)
  uint8 data3[9] = {0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00};
  bufferevent_write(user->buf_ev, (char *)&data3[0], 9);

  //Inventory
  uint8 data4[7+36*5];
  data4[0] = 0x05;
  putSint32(&data4[1], -1);
  data4[5] = 0;
  data4[6] = 36;
  int curpos2 = 7;
  //Send main inventory
  for(i = 0; i < 36; i++)
  {
    if(user->inv.main[i].count)
    {
      putSint16(&data4[curpos2], user->inv.main[i].type);     //Type
      curpos2       += 2;
      data4[curpos2] = user->inv.main[i].count;               //Count
      curpos2++;
      putSint16(&data4[curpos2], user->inv.main[i].health); //Health
      curpos2 += 2;
    }
    else
    {
      //Empty slot
      putSint16(&data4[curpos2], -1);
      curpos2 += 2;
    }
  }
  bufferevent_write(user->buf_ev, (char *)&data4[0], curpos2);


  //Send equipped inventory
  putSint32(&data4[1], -3);
  data4[6] = 4;
  curpos2  = 7;
  for(i = 0; i < 4; i++)
  {
    if(user->inv.equipped[i].count)
    {
      putSint16(&data4[curpos2], user->inv.equipped[i].type);     //Type
      curpos2       += 2;
      data4[curpos2] = user->inv.equipped[i].count;               //Count
      curpos2++;
      putSint16(&data4[curpos2], user->inv.equipped[i].health); //Health
      curpos2 += 2;
    }
    else
    {
      //Empty slot
      putSint16(&data4[curpos2], -1);
      curpos2 += 2;
    }
  }
  bufferevent_write(user->buf_ev, (char *)&data4[0], curpos2);

  //Send crafting inventory
  putSint32(&data4[1], -2);
  data4[6] = 4;
  curpos2  = 7;
  for(i = 0; i < 4; i++)
  {
    if(user->inv.crafting[i].count)
    {
      putSint16(&data4[curpos2], user->inv.crafting[i].type);     //Type
      curpos2       += 2;
      data4[curpos2] = user->inv.crafting[i].count;               //Count
      curpos2++;
      putSint16(&data4[curpos2], user->inv.crafting[i].health); //Health
      curpos2 += 2;
    }
    else
    {
      //Empty slot
      putSint16(&data4[curpos2], -1);
      curpos2 += 2;
    }
  }
  bufferevent_write(user->buf_ev, (char *)&data4[0], curpos2);

  // Send motd
  std::ifstream motdfs( MOTDFILE.c_str());

  std::string temp;

  while(getline( motdfs, temp ))
  {
    // If not commentline
    if(temp[0] != COMMENTPREFIX)
      Chat::get().sendMsg(user, temp, Chat::USER);
  }
  motdfs.close();

  //Teleport player
  user->teleport(user->pos.x, user->pos.y+2, user->pos.z);

  //Put nearby chunks to queue
  for(int x = -user->viewDistance; x <= user->viewDistance; x++)
  {
    for(int z = -user->viewDistance; z <= user->viewDistance; z++)
    {
      user->addQueue((sint32)user->pos.x/16+x, (sint32)user->pos.z/16+z);
    }
  }
  // Push chunks to user
  user->pushMap();

  //Spawn this user to others
  user->spawnUser((sint32)user->pos.x*32, ((sint32)user->pos.y+2)*32, (sint32)user->pos.z*32);
  //Spawn other users for connected user
  user->spawnOthers();


  //Send "On Ground" signal
  char data6[2] = {0x0A, 0x01};
  bufferevent_write(user->buf_ev, (char *)&data6[0], 2);

  user->logged = true;

  Chat::get().sendMsg(user, player+" connected!", Chat::ALL);

  return curpos;
}
예제 #2
0
// Login request (http://mc.kev009.com/wiki/Protocol#Login_Request_.280x01.29)
int PacketHandler::login_request(User *user)
{
  //Check that we have enought data in the buffer
  if(!user->buffer.haveData(12))
    return PACKET_NEED_MORE_DATA;

  sint32 version;
  std::string player, passwd;
  sint64 mapseed;
  sint8 dimension;

  user->buffer >> version >> player >> passwd >> mapseed >> dimension;

  if(!user->buffer)
    return PACKET_NEED_MORE_DATA;

  user->buffer.removePacket();

  std::cout << "Player " << user->UID << " login v." << version <<" : " << player <<":"<< passwd << std::endl;

  // If version is not 2 or 3
  if(version != 5)
  {
    user->kick(Conf::get().sValue("wrong_protocol_message"));
    return PACKET_OK;
  }

  // If userlimit is reached
  if((int)Users.size() >= Conf::get().iValue("userlimit"))
  {
    user->kick(Conf::get().sValue("server_full_message"));
    return PACKET_OK;
  }

  user->changeNick(player);

  //Load user data
  user->loadData();

  //Login OK package
  user->buffer << (sint8)PACKET_LOGIN_RESPONSE 
    << (sint32)user->UID << std::string("") << std::string("") << (sint64)0 << (sint8)0;

  //Send server time (after dawn)
  user->buffer << (sint8)PACKET_TIME_UPDATE << (sint64) 0x0e00;

  //Inventory
  for(sint32 invType=-1; invType != -4; invType--)
  {
    Item *inventory = NULL;
  sint16 inventoryCount = 0;

  if(invType == -1)
  {
    inventory = user->inv.main;
    inventoryCount = 36;
  }
  else if(invType == -2)
  {
    inventory = user->inv.equipped;
    inventoryCount = 4;
  }
  else if(invType == -3)
  {
    inventory = user->inv.crafting;
    inventoryCount = 4;
  }
  user->buffer << (sint8)PACKET_PLAYER_INVENTORY << invType << inventoryCount;

  for(int i=0; i<inventoryCount; i++)
  {
    if(inventory[i].count)
    {
      user->buffer << (sint16)inventory[i].type << (sint8)inventory[i].count << (sint16)inventory[i].health;
    }
    else
    {
      user->buffer << (sint16)-1;
    }
  }
  }

  // Send motd
  std::ifstream motdfs( MOTDFILE.c_str());

  std::string temp;

  while(getline( motdfs, temp ))
  {
    // If not commentline
    if(temp[0] != COMMENTPREFIX)
  {
      user->buffer << (sint8)PACKET_CHAT_MESSAGE << temp;
  }
  }
  motdfs.close();

  //Teleport player
  user->teleport(user->pos.x, user->pos.y+2, user->pos.z);

  //Put nearby chunks to queue
  for(int x = -user->viewDistance; x <= user->viewDistance; x++)
  {
    for(int z = -user->viewDistance; z <= user->viewDistance; z++)
    {
      user->addQueue((sint32)user->pos.x/16+x, (sint32)user->pos.z/16+z);
    }
  }
  // Push chunks to user
  user->pushMap();

  //Spawn this user to others
  user->spawnUser((sint32)user->pos.x*32, ((sint32)user->pos.y+2)*32, (sint32)user->pos.z*32);
  //Spawn other users for connected user
  user->spawnOthers();

  user->logged = true;

  Chat::get().sendMsg(user, player+" connected!", Chat::ALL);

  return PACKET_OK;
}