// 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; }
// 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; }