bool hook_doUntilFalse(const char* hookID, ...) { bool result = false; va_list argList; va_start(argList, hookID); runCallbackUntilFalse(hookID,argList); result = callbackReturnValue; va_end(argList); return result; }
int PacketHandler::player_digging(User* user) { int8_t status; int32_t x; int16_t y; int8_t temp_y; int32_t z; int8_t direction; uint8_t block; uint8_t meta; BlockBasicPtr blockcb; BlockDefault blockD; user->buffer >> status >> x >> temp_y >> z >> direction; y = (uint8_t)temp_y; if (!user->buffer) { return PACKET_NEED_MORE_DATA; } user->buffer.removePacket(); if (!ServerInstance->map(user->pos.map)->getBlock(x, y, z, &block, &meta)) { blockD.revertBlock(user, x, y, z, user->pos.map); return PACKET_OK; } // Blocks that break with first hit if(status == BLOCK_STATUS_STARTED_DIGGING) { if( user->creative || (block == BLOCK_SNOW || block == BLOCK_REED || block == BLOCK_TORCH || block == BLOCK_REDSTONE_WIRE || block == BLOCK_RED_ROSE || block == BLOCK_YELLOW_FLOWER || block == BLOCK_BROWN_MUSHROOM || block == BLOCK_RED_MUSHROOM || block == BLOCK_REDSTONE_TORCH_OFF || block == BLOCK_REDSTONE_TORCH_ON)) { status = BLOCK_STATUS_BLOCK_BROKEN; } } switch (status) { case BLOCK_STATUS_STARTED_DIGGING: { runAllCallback("PlayerDiggingStarted",user->nick.c_str(), x, y, z, direction); for (uint32_t i = 0 ; i < ServerInstance->plugin()->getBlockCB().size(); i++) { blockcb = ServerInstance->plugin()->getBlockCB()[i]; if (blockcb != NULL && blockcb->affectedBlock(block)) { blockcb->onStartedDigging(user, status, x, y, z, user->pos.map, direction); } } break; } case BLOCK_STATUS_BLOCK_BROKEN: { //Player tool usage calculation etc bool rightUse; int16_t itemSlot = user->currentItemSlot() + 36; int16_t itemHealth = ServerInstance->inventory()->itemHealth(user->inv[itemSlot].getType(), block, rightUse); if (itemHealth > 0) { user->inv[itemSlot].incHealth(); if (!rightUse) { user->inv[itemSlot].incHealth(); } if (itemHealth <= user->inv[itemSlot].getHealth()) { user->inv[itemSlot].decCount(); if (user->inv[itemSlot].getCount() == 0) { user->inv[itemSlot].setHealth(0); user->inv[itemSlot].setType(-1); } } ServerInstance->inventory()->setSlot(user, WINDOW_PLAYER, itemSlot, user->inv[itemSlot].getType(), user->inv[itemSlot].getCount(), user->inv[itemSlot].getHealth()); } runCallbackUntilFalse("BlockBreakPre",user->nick.c_str(), x, y, z); if (callbackReturnValue) { blockD.revertBlock(user, x, y, z, user->pos.map); return PACKET_OK; } runAllCallback("BlockBreakPost",user->nick.c_str(), x, y, z); for (uint32_t i = 0 ; i < ServerInstance->plugin()->getBlockCB().size(); i++) { blockcb = ServerInstance->plugin()->getBlockCB()[i]; if (blockcb != NULL && blockcb->affectedBlock(block)) { if (blockcb->onBroken(user, status, x, y, z, user->pos.map, direction)) { // Do not break return PACKET_OK; } else { break; } } } /* notify neighbour blocks of the broken block */ status = block; if (ServerInstance->map(user->pos.map)->getBlock(x + 1, y, z, &block, &meta) && block != BLOCK_AIR) { runAllCallback("BlockNeighbourBreak",user->nick.c_str(), x + 1, y, z, x, int8_t(y), z); for (uint32_t i = 0 ; i < ServerInstance->plugin()->getBlockCB().size(); i++) { blockcb = ServerInstance->plugin()->getBlockCB()[i]; if (blockcb != NULL && (blockcb->affectedBlock(status) || blockcb->affectedBlock(block))) { blockcb->onNeighbourBroken(user, status, x + 1, y, z, user->pos.map, BLOCK_SOUTH); } } } if (ServerInstance->map(user->pos.map)->getBlock(x - 1, y, z, &block, &meta) && block != BLOCK_AIR) { runAllCallback("BlockNeighbourBreak",user->nick.c_str(), x - 1, y, z, x, int8_t(y), z); for (uint32_t i = 0 ; i < ServerInstance->plugin()->getBlockCB().size(); i++) { blockcb = ServerInstance->plugin()->getBlockCB()[i]; if (blockcb != NULL && (blockcb->affectedBlock(status) || blockcb->affectedBlock(block))) { blockcb->onNeighbourBroken(user, status, x - 1, y, z, user->pos.map, BLOCK_NORTH); } } } if (ServerInstance->map(user->pos.map)->getBlock(x, y + 1, z, &block, &meta) && block != BLOCK_AIR) { runAllCallback("BlockNeighbourBreak",user->nick.c_str(), x, y + 1, z, x, int8_t(y), z); for (uint32_t i = 0 ; i < ServerInstance->plugin()->getBlockCB().size(); i++) { blockcb = ServerInstance->plugin()->getBlockCB()[i]; if (blockcb != NULL && (blockcb->affectedBlock(status) || blockcb->affectedBlock(block))) { blockcb->onNeighbourBroken(user, status, x, y + 1, z, user->pos.map, BLOCK_TOP); } } } if (ServerInstance->map(user->pos.map)->getBlock(x, y - 1, z, &block, &meta) && block != BLOCK_AIR) { runAllCallback("BlockNeighbourBreak",user->nick.c_str(), x, y - 1, z, x, int8_t(y), z); for (uint32_t i = 0 ; i < ServerInstance->plugin()->getBlockCB().size(); i++) { blockcb = ServerInstance->plugin()->getBlockCB()[i]; if (blockcb != NULL && (blockcb->affectedBlock(status) || blockcb->affectedBlock(block))) { blockcb->onNeighbourBroken(user, status, x, y - 1, z, user->pos.map, BLOCK_BOTTOM); } } } if (ServerInstance->map(user->pos.map)->getBlock(x, y, z + 1, &block, &meta) && block != BLOCK_AIR) { runAllCallback("BlockNeighbourBreak",user->nick.c_str(), x, y, z + 1, x, int8_t(y), z); for (uint32_t i = 0 ; i < ServerInstance->plugin()->getBlockCB().size(); i++) { blockcb = ServerInstance->plugin()->getBlockCB()[i]; if (blockcb != NULL && (blockcb->affectedBlock(status) || blockcb->affectedBlock(block))) { blockcb->onNeighbourBroken(user, status, x, y, z + 1, user->pos.map, BLOCK_WEST); } } } if (ServerInstance->map(user->pos.map)->getBlock(x, y, z - 1, &block, &meta) && block != BLOCK_AIR) { runAllCallback("BlockNeighbourBreak",user->nick.c_str(), x, y, z - 1, x, int8_t(y), z); for (uint32_t i = 0 ; i < ServerInstance->plugin()->getBlockCB().size(); i++) { blockcb = ServerInstance->plugin()->getBlockCB()[i]; if (blockcb != NULL && (blockcb->affectedBlock(status) || blockcb->affectedBlock(block))) { blockcb->onNeighbourBroken(user, status, x, y, z - 1, user->pos.map, BLOCK_EAST); } } } break; } case BLOCK_STATUS_PICKUP_SPAWN: { //ToDo: handle #define itemSlot (36+user->currentItemSlot()) if (user->inv[itemSlot].getType() > 0) { ServerInstance->map(user->pos.map)->createPickupSpawn(int(user->pos.x), int(user->pos.y), int(user->pos.z), int(user->inv[itemSlot].getType()), 1, int(user->inv[itemSlot].getHealth()), user); user->inv[itemSlot].decCount(); } break; #undef itemSlot } } return PACKET_OK; }
int PacketHandler::handshake(User* user) { if (!user->buffer.haveData(9)) { return PACKET_NEED_MORE_DATA; } std::string player, host; int8_t version; int32_t port; user->buffer >> version >> player >> host >> port; // Check for data if (!user->buffer) { return PACKET_NEED_MORE_DATA; } // Remove package from buffer user->buffer.removePacket(); LOG(INFO, "Packets", "Player " + dtos(user->UID) + " login v." + dtos(version) + " : " + player); user->nick = player; // If version is not the current version if (version != PROTOCOL_VERSION) { user->kick(ServerInstance->config()->sData("strings.wrong_protocol")); return PACKET_OK; } // If userlimit is reached if ((int)User::all().size() > ServerInstance->config()->iData("system.user_limit")) { user->kick(ServerInstance->config()->sData("strings.server_full")); return PACKET_OK; } char* kickMessage = NULL; runCallbackUntilFalse("PlayerLoginPre",player.c_str(), &kickMessage); if (callbackReturnValue) { user->kick(std::string(kickMessage)); } else { //We can skip the protocol encryption if(!ServerInstance->config()->bData("system.protocol_encryption")) { user->sendLoginInfo(); } else { user->buffer << Protocol::encryptionRequest(); } runAllCallback("PlayerLoginPost",player.c_str()); } // TODO: Add support for prompting user for Server password return PACKET_OK; }