mirror of
https://gitea.sffempire.ru/Kolyah35/minecraft-pe-0.6.1.git
synced 2026-03-20 06:53:30 +00:00
the whole game
This commit is contained in:
925
src/network/ClientSideNetworkHandler.cpp
Executable file
925
src/network/ClientSideNetworkHandler.cpp
Executable file
@@ -0,0 +1,925 @@
|
||||
|
||||
#include "ClientSideNetworkHandler.h"
|
||||
#include "packet/PacketInclude.h"
|
||||
#include "RakNetInstance.h"
|
||||
#include "../world/level/chunk/ChunkSource.h"
|
||||
#include "../world/level/Level.h"
|
||||
#include "../world/level/storage/LevelStorageSource.h"
|
||||
#include "../world/entity/player/Player.h"
|
||||
#include "../world/entity/player/Inventory.h"
|
||||
#include "../client/Minecraft.h"
|
||||
#include "../client/gamemode/GameMode.h"
|
||||
#ifndef STANDALONE_SERVER
|
||||
#include "../client/gui/screens/DisconnectionScreen.h"
|
||||
#endif
|
||||
#include "../client/player/LocalPlayer.h"
|
||||
#include "../client/multiplayer/MultiPlayerLevel.h"
|
||||
#include "../client/player/input/KeyboardInput.h"
|
||||
#include "../client/sound/SoundEngine.h"
|
||||
#include "../world/entity/MobFactory.h"
|
||||
#include "../raknet/RakPeerInterface.h"
|
||||
#include "../world/level/Explosion.h"
|
||||
#include "../world/level/tile/entity/FurnaceTileEntity.h"
|
||||
#include "../world/inventory/BaseContainerMenu.h"
|
||||
#ifndef STANDALONE_SERVER
|
||||
#include "../client/particle/TakeAnimationParticle.h"
|
||||
#endif
|
||||
#include "../world/entity/EntityFactory.h"
|
||||
#include "../world/entity/item/PrimedTnt.h"
|
||||
#include "../world/entity/projectile/Arrow.h"
|
||||
#include "../world/level/tile/entity/ChestTileEntity.h"
|
||||
#include "../client/player/RemotePlayer.h"
|
||||
#include "../world/level/tile/LevelEvent.h"
|
||||
#include "../world/entity/item/FallingTile.h"
|
||||
|
||||
static MultiPlayerLevel* mpcast(Level* l) { return (MultiPlayerLevel*) l; }
|
||||
|
||||
ClientSideNetworkHandler::ClientSideNetworkHandler(Minecraft* minecraft, IRakNetInstance* raknetInstance)
|
||||
: minecraft(minecraft),
|
||||
raknetInstance(raknetInstance),
|
||||
level(NULL),
|
||||
requestNextChunkPosition(0),
|
||||
requestNextChunkIndex(0)
|
||||
{
|
||||
rakPeer = raknetInstance->getPeer();
|
||||
}
|
||||
|
||||
ClientSideNetworkHandler::~ClientSideNetworkHandler()
|
||||
{
|
||||
}
|
||||
|
||||
void ClientSideNetworkHandler::requestNextChunk()
|
||||
{
|
||||
if (requestNextChunkIndex < NumRequestChunks)
|
||||
{
|
||||
IntPair& chunk = requestNextChunkIndexList[requestNextChunkIndex];
|
||||
RequestChunkPacket packet(chunk.x, chunk.y);
|
||||
raknetInstance->send(packet);
|
||||
|
||||
//LOGI("requesting chunks @ (%d, %d)\n", chunk.x, chunk.y);
|
||||
|
||||
//raknetInstance->send(new RequestChunkPacket(requestNextChunkPosition % CHUNK_CACHE_WIDTH, requestNextChunkPosition / CHUNK_CACHE_WIDTH));
|
||||
requestNextChunkIndex++;
|
||||
requestNextChunkPosition++;
|
||||
}
|
||||
}
|
||||
|
||||
bool ClientSideNetworkHandler::areAllChunksLoaded()
|
||||
{
|
||||
return (requestNextChunkPosition >= (CHUNK_CACHE_WIDTH * CHUNK_CACHE_WIDTH));
|
||||
}
|
||||
|
||||
bool ClientSideNetworkHandler::isChunkLoaded(int x, int z)
|
||||
{
|
||||
if (x < 0 || x >= CHUNK_CACHE_WIDTH || z < 0 || z >= CHUNK_CACHE_WIDTH) {
|
||||
LOGE("Error: Tried to request chunk (%d, %d)\n", x, z);
|
||||
return true;
|
||||
}
|
||||
return chunksLoaded[x * CHUNK_CACHE_WIDTH + z];
|
||||
//return areAllChunksLoaded();
|
||||
}
|
||||
|
||||
void ClientSideNetworkHandler::onConnect(const RakNet::RakNetGUID& hostGuid)
|
||||
{
|
||||
LOGI("onConnect, server guid: %s, local guid: %s\n", hostGuid.ToString(), rakPeer->GetMyGUID().ToString());
|
||||
serverGuid = hostGuid;
|
||||
|
||||
clearChunksLoaded();
|
||||
LoginPacket packet(minecraft->user->name.c_str(), SharedConstants::NetworkProtocolVersion);
|
||||
raknetInstance->send(packet);
|
||||
}
|
||||
|
||||
void ClientSideNetworkHandler::onUnableToConnect()
|
||||
{
|
||||
LOGI("onUnableToConnect\n");
|
||||
}
|
||||
|
||||
void ClientSideNetworkHandler::onDisconnect(const RakNet::RakNetGUID& guid)
|
||||
{
|
||||
LOGI("onDisconnect\n");
|
||||
if (level)
|
||||
{
|
||||
level->isClientSide = false;
|
||||
for (int i = (int)level->players.size()-1; i >= 0; --i ) {
|
||||
Player* p = level->players[i];
|
||||
if (p != minecraft->player) {
|
||||
p->reallyRemoveIfPlayer = true;
|
||||
level->removeEntity(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifndef STANDALONE_SERVER
|
||||
minecraft->gui.addMessage("Disconnected from server");
|
||||
#endif
|
||||
}
|
||||
|
||||
void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& source, LoginStatusPacket* packet) {
|
||||
if (packet->status == LoginStatus::Success) {
|
||||
raknetInstance->setIsLoggedIn(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (packet->status == LoginStatus::Failed_ClientOld) {
|
||||
LOGI("Disconnect! Client is outdated!\n");
|
||||
#ifndef STANDALONE_SERVER
|
||||
minecraft->setScreen(new DisconnectionScreen("Could not connect: Outdated client!"));
|
||||
#endif
|
||||
}
|
||||
if (packet->status == LoginStatus::Failed_ServerOld) {
|
||||
LOGI("Disconnect! Server is outdated!\n");
|
||||
#ifndef STANDALONE_SERVER
|
||||
minecraft->setScreen(new DisconnectionScreen("Could not connect: Outdated server!"));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& source, StartGamePacket* packet)
|
||||
{
|
||||
LOGI("StartGamePacket\n");
|
||||
|
||||
#ifdef RPI
|
||||
if (packet->gameType != GameType::Creative) {
|
||||
minecraft->setScreen(new DisconnectionScreen("Could not connect: Incompatible server!"));
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
const std::string& levelId = LevelStorageSource::TempLevelId;
|
||||
LevelStorageSource* storageSource = minecraft->getLevelSource();
|
||||
storageSource->deleteLevel(levelId);
|
||||
//level = new Level(storageSource->selectLevel(levelId, true), "temp", packet->levelSeed, SharedConstants::StorageVersion);
|
||||
MultiPlayerLevel* level = new MultiPlayerLevel(
|
||||
storageSource->selectLevel(levelId, true),
|
||||
"temp",
|
||||
LevelSettings(packet->levelSeed, LevelSettings::validateGameType(packet->gameType)),
|
||||
SharedConstants::StorageVersion);
|
||||
level->isClientSide = true;
|
||||
|
||||
bool isCreative = (packet->gameType == GameType::Creative);
|
||||
LocalPlayer* player = new LocalPlayer(minecraft, level, minecraft->user, level->dimension->id, isCreative);
|
||||
player->owner = rakPeer->GetMyGUID();
|
||||
player->entityId = packet->entityId;
|
||||
player->moveTo(packet->x, packet->y, packet->z, player->yRot, player->xRot);
|
||||
|
||||
LOGI("new pos: %f, %f [%f - %f]\n", player->x, player->z, player->bb.y0, player->bb.y1);
|
||||
|
||||
minecraft->setLevel(level, "ClientSideNetworkHandler -> setLevel", player);
|
||||
minecraft->setIsCreativeMode(isCreative);
|
||||
}
|
||||
|
||||
void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& source, MessagePacket* packet)
|
||||
{
|
||||
LOGI("MessagePacket\n");
|
||||
#ifndef STANDALONE_SERVER
|
||||
minecraft->gui.addMessage(packet->message.C_String());
|
||||
#endif
|
||||
}
|
||||
|
||||
void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& source, SetTimePacket* packet)
|
||||
{
|
||||
if (!level)
|
||||
return;
|
||||
|
||||
LOGI("SetTimePacket\n");
|
||||
level->setTime(packet->time);
|
||||
}
|
||||
|
||||
void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& source, AddEntityPacket* packet)
|
||||
{
|
||||
if (!level)
|
||||
return;
|
||||
|
||||
Entity* e = EntityFactory::CreateEntity(packet->type, level);
|
||||
if (!e)
|
||||
return;
|
||||
|
||||
e->entityId = packet->entityId;
|
||||
e->setPos(packet->x, packet->y, packet->z);
|
||||
|
||||
// Entity Specific stuff here
|
||||
switch (packet->type)
|
||||
{
|
||||
case EntityTypes::IdFallingTile: {
|
||||
int data = -packet->data();
|
||||
FallingTile* ft = (FallingTile*) e;
|
||||
ft->tile = data & 0xff;
|
||||
ft->data = data >> 16;
|
||||
}
|
||||
case EntityTypes::IdArrow: {
|
||||
Entity* owner = level->getEntity(packet->data());
|
||||
if (owner && owner->isMob())
|
||||
((Arrow*)e)->ownerId = owner->entityId;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (packet->hasMovementData()) {
|
||||
/*
|
||||
e->xd = packet->xd;
|
||||
e->yd = packet->yd;
|
||||
e->zd = packet->zd;
|
||||
*/
|
||||
e->lerpMotion(packet->xd, packet->yd, packet->zd);
|
||||
//LOGI("Client: reading entity with %f, %f, %f\n", e->xd, e->yd, e->zd);
|
||||
}
|
||||
|
||||
mpcast(level)->putEntity(packet->entityId, e);
|
||||
}
|
||||
void ClientSideNetworkHandler::handle( const RakNet::RakNetGUID& source, AddPaintingPacket* packet ) {
|
||||
if (!level)
|
||||
return;
|
||||
|
||||
Painting* painting = new Painting(level, packet->xTile, packet->yTile, packet->zTile, packet->dir, packet->motive);
|
||||
mpcast(level)->putEntity(packet->entityId, painting);
|
||||
}
|
||||
void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& source, AddMobPacket* packet)
|
||||
{
|
||||
LOGI("AddMobPacket (%p)\n", level);
|
||||
|
||||
if (!level) {
|
||||
LOGW("Trying to add a mob with no level!\n");
|
||||
//we skip this since we will get this player anyway when we request level
|
||||
return;
|
||||
}
|
||||
if (!packet->type) {
|
||||
LOGE("Trying to add a mob without a type id\n");
|
||||
return;
|
||||
}
|
||||
|
||||
Mob* mob = MobFactory::CreateMob(packet->type, level);
|
||||
if (!mob) {
|
||||
LOGE("Server tried to add an unknown mob type! :%d\n", packet->type);
|
||||
return;
|
||||
}
|
||||
|
||||
mob->entityId = packet->entityId;
|
||||
mob->moveTo(packet->x, packet->y, packet->z, packet->yRot, packet->xRot);
|
||||
mob->getEntityData()->assignValues(&packet->unpack);
|
||||
level->addEntity(mob);
|
||||
}
|
||||
|
||||
void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& source, AddPlayerPacket* packet)
|
||||
{
|
||||
if (!level) {
|
||||
//we skip this since we will get this player anyway when we request level
|
||||
return;
|
||||
}
|
||||
LOGI("AddPlayerPacket\n");
|
||||
|
||||
Player* player = new RemotePlayer(level, minecraft->isCreativeMode());
|
||||
minecraft->gameMode->initAbilities(player->abilities);
|
||||
player->entityId = packet->entityId;
|
||||
level->addEntity(player);
|
||||
|
||||
player->moveTo(packet->x, packet->y, packet->z, packet->yRot, packet->xRot);
|
||||
player->name = packet->name.C_String();
|
||||
player->owner = packet->owner;
|
||||
player->getEntityData()->assignValues(&packet->unpack);
|
||||
int slot = Inventory::MAX_SELECTION_SIZE;
|
||||
if (packet->carriedItemId == 0) {
|
||||
player->inventory->clearSlot(slot);
|
||||
} else {
|
||||
ItemInstance newItem(packet->carriedItemId, 1, packet->carriedItemAuxValue);
|
||||
player->inventory->replaceSlot(slot, &newItem);
|
||||
}
|
||||
player->inventory->moveToSelectedSlot(slot, true);
|
||||
//player->resetPos();
|
||||
|
||||
std::string message = packet->name.C_String();
|
||||
message += " joined the game";
|
||||
#ifndef STANDALONE_SERVER
|
||||
minecraft->gui.addMessage(message);
|
||||
#endif
|
||||
}
|
||||
|
||||
void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& source, RemovePlayerPacket* packet) {
|
||||
if (!level || source == minecraft->player->owner) return;
|
||||
|
||||
if (Player* player = findPlayer(level, packet->entityId, &packet->owner)) {
|
||||
player->reallyRemoveIfPlayer = true;
|
||||
level->removeEntity(player);
|
||||
}
|
||||
|
||||
//for (int i = (int)level->players.size()-1; i >= 0; --i) {
|
||||
// if (level->players[i]->owner == source) {
|
||||
// level->players[i]->reallyRemoveIfPlayer = true;
|
||||
// level->players.erase(level->players.begin() + i);
|
||||
// break;
|
||||
// }
|
||||
//}
|
||||
|
||||
//if (!player) return;
|
||||
|
||||
//std::string message = packet->name.C_String();
|
||||
//message += " joined the game";
|
||||
//minecraft->gui.addMessage(message);
|
||||
}
|
||||
|
||||
void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& source, RemoveEntityPacket* packet)
|
||||
{
|
||||
if (!level) return;
|
||||
|
||||
Entity* entity = level->getEntity(packet->entityId);
|
||||
LOGI("RemoveEntityPacket %p %p, %d\n", entity, minecraft->player, entity?(int)(entity->isPlayer()): -1);
|
||||
if (!entity) return;
|
||||
|
||||
level->removeEntity(entity);
|
||||
}
|
||||
|
||||
void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& source, AddItemEntityPacket* packet)
|
||||
{
|
||||
if (!level) return;
|
||||
|
||||
ItemEntity* entity = new ItemEntity(level, packet->x, packet->y, packet->z, ItemInstance(packet->itemId, packet->itemCount, packet->auxValue));
|
||||
entity->xd = packet->xa();
|
||||
entity->yd = packet->ya();
|
||||
entity->zd = packet->za();
|
||||
//LOGI("item-entity @ client: %f, %f, %f\n", entity->xd, entity->yd, entity->zd);
|
||||
|
||||
mpcast(level)->putEntity(packet->id, entity);
|
||||
}
|
||||
|
||||
void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& source, TakeItemEntityPacket* packet) {
|
||||
if (!level) return;
|
||||
|
||||
Entity* e = level->getEntity(packet->itemId);
|
||||
if (!e)
|
||||
return;
|
||||
|
||||
ItemInstance item;
|
||||
if (e->isItemEntity()) {
|
||||
item = ((ItemEntity*) e)->item;
|
||||
#ifndef STANDALONE_SERVER
|
||||
if (Entity* to = level->getEntity(packet->playerId))
|
||||
minecraft->particleEngine->add(new TakeAnimationParticle(level, (ItemEntity*)e, to, -0.5f));
|
||||
#endif
|
||||
}
|
||||
else if (e->getEntityTypeId() == EntityTypes::IdArrow)
|
||||
item = ItemInstance(Item::arrow);
|
||||
|
||||
if (item.isNull())
|
||||
return;
|
||||
|
||||
// try take it and if we don't have space; re-throw it
|
||||
if (minecraft->player->entityId == packet->playerId
|
||||
&& !minecraft->player->inventory->add(&item)) {
|
||||
DropItemPacket dropPacket(packet->playerId, item);
|
||||
minecraft->raknetInstance->send(dropPacket);
|
||||
}
|
||||
level->playSound(e, "random.pop", 0.2f, 1.0f * 2.f);
|
||||
}
|
||||
|
||||
void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& source, MovePlayerPacket* packet)
|
||||
{
|
||||
if (!level)
|
||||
return;
|
||||
|
||||
//printf("MovePlayerPacket\n");
|
||||
Entity* entity = level->getEntity(packet->entityId);
|
||||
if (entity)
|
||||
{
|
||||
entity->lerpTo(packet->x, packet->y, packet->z, packet->yRot, packet->xRot, 3);
|
||||
}
|
||||
}
|
||||
|
||||
void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& source, MoveEntityPacket* packet)
|
||||
{
|
||||
if (!level)
|
||||
return;
|
||||
|
||||
//printf("MovePlayerPacket\n");
|
||||
Entity* entity = level->getEntity(packet->entityId);
|
||||
if (entity)
|
||||
{
|
||||
float xRot = packet->hasRot? packet->xRot : entity->xRot;
|
||||
float yRot = packet->hasRot? packet->yRot : entity->yRot;
|
||||
entity->lerpTo(packet->x, packet->y, packet->z, yRot, xRot, 3);
|
||||
}
|
||||
}
|
||||
|
||||
void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& source, UpdateBlockPacket* packet)
|
||||
{
|
||||
if (!level) return;
|
||||
|
||||
//LOGI("UpdateBlockPacket @ %d, %d, %d\n", packet->x, packet->y, packet->z);
|
||||
|
||||
int x = packet->x, z = packet->z;
|
||||
|
||||
if (isChunkLoaded(x >> 4, z >> 4))
|
||||
{
|
||||
//LOGI("chunk is loaded - UPDATE @ %d, %d, %d -- %d, %d\n", x, packet->y, z, packet->blockId, packet->blockData);
|
||||
|
||||
int y = packet->y;
|
||||
int tileId = Tile::transformToValidBlockId(packet->blockId, x, y, z);
|
||||
level->setTileAndData(x, y, z, tileId, packet->blockData);
|
||||
} else {
|
||||
SBufferedBlockUpdate update;
|
||||
update.blockId = packet->blockId;
|
||||
update.blockData = packet->blockData;
|
||||
update.setData = true;
|
||||
update.x = packet->x;
|
||||
update.y = packet->y;
|
||||
update.z = packet->z;
|
||||
bufferedBlockUpdates.push_back(update);
|
||||
}
|
||||
}
|
||||
|
||||
void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& source, ExplodePacket* packet) {
|
||||
if (!level) return;
|
||||
Explosion explosion(level, NULL, packet->x, packet->y, packet->z, packet->r);
|
||||
explosion.toBlow.insert(packet->toBlow.begin(), packet->toBlow.end());
|
||||
explosion.finalizeExplosion();
|
||||
}
|
||||
|
||||
void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& source, LevelEventPacket* packet) {
|
||||
if (!level) return;
|
||||
if(packet->eventId == LevelEvent::ALL_PLAYERS_SLEEPING) {
|
||||
minecraft->player->setAllPlayersSleeping();
|
||||
}
|
||||
else {
|
||||
minecraft->level->levelEvent(NULL, packet->eventId, packet->x, packet->y, packet->z, packet->data);
|
||||
}
|
||||
}
|
||||
|
||||
void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& source, TileEventPacket* packet) {
|
||||
if (!level) return;
|
||||
minecraft->level->tileEvent(packet->x, packet->y, packet->z, packet->b0, packet->b1);
|
||||
}
|
||||
|
||||
void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& source, EntityEventPacket* packet) {
|
||||
if (!level) return;
|
||||
|
||||
Entity* e = level->getEntity(packet->entityId);
|
||||
if (e) e->handleEntityEvent(packet->eventId);
|
||||
}
|
||||
|
||||
void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& source, ChunkDataPacket* packet)
|
||||
{
|
||||
if (!level) {
|
||||
LOGI("level @ handle ChunkDataPacket is 0\n");
|
||||
return;
|
||||
}
|
||||
//LOGI("ChunkDataPacket\n");
|
||||
|
||||
LevelChunk* chunk = level->getChunkSource()->create(packet->x, packet->z);
|
||||
if (!chunk || chunk->isEmpty())
|
||||
{
|
||||
LOGI("Failed to find write-able chunk\n");
|
||||
return;
|
||||
}
|
||||
|
||||
//unsigned char* blockIds = chunk->getBlockData();
|
||||
DataLayer& blockData = chunk->data;
|
||||
|
||||
const int setSize = LEVEL_HEIGHT / 8;
|
||||
const int setShift = 4; // power of LEVEL_HEIGHT / 8
|
||||
|
||||
bool recalcHeight = false;
|
||||
|
||||
int x0 = 16, x1 = 0, z0 = 16, z1 = 0, y0 = LEVEL_HEIGHT, y1 = 0;
|
||||
int rx = packet->x << 4;
|
||||
int rz = packet->z << 4;
|
||||
|
||||
unsigned char readBlockBuffer[setSize];
|
||||
unsigned char readDataBuffer[setSize / 2];
|
||||
|
||||
for (int i = 0; i < CHUNK_COLUMNS; i++)
|
||||
{
|
||||
unsigned char updateBits = 0;
|
||||
packet->chunkData.Read(updateBits);
|
||||
|
||||
if (updateBits > 0)
|
||||
{
|
||||
recalcHeight = true;
|
||||
|
||||
int colX = (i % CHUNK_WIDTH);
|
||||
int colZ = (i / CHUNK_WIDTH);
|
||||
int colDataPosition = colX << 11 | colZ << 7;
|
||||
|
||||
for (int set = 0; set < 8; set++)
|
||||
{
|
||||
if ((updateBits & (1 << set)) != 0)
|
||||
{
|
||||
packet->chunkData.Read((char*)readBlockBuffer, setSize);
|
||||
packet->chunkData.Read((char*)readDataBuffer, setSize / 2);
|
||||
|
||||
for (int part = 0; part < setSize; part++)
|
||||
{
|
||||
//if (readBlockBuffer[part] == ((Tile*)Tile::grass)->id)
|
||||
// readBlockBuffer[part] = 255;
|
||||
int x = rx + colX;
|
||||
int y = (set << setShift) + part;
|
||||
int z = rz + colZ;
|
||||
|
||||
int tileId = Tile::transformToValidBlockId(readBlockBuffer[part], x, y, z);
|
||||
level->setTileNoUpdate(x, y, z, tileId);
|
||||
}
|
||||
// ((part & 1) == 0) ? readDataBuffer[part >> 1] & 0xf : (readDataBuffer[part >> 1] & 0xf0) >> 4
|
||||
|
||||
//packet->chunkData.Read((char*)(&blockIds[colDataPosition + (set << setShift)]), setSize);
|
||||
// block data is only 4 bits per block
|
||||
//packet->chunkData.Read((char*)(&blockData.data[(colDataPosition + (set << setShift)) >> 1]), setSize >> 1);
|
||||
|
||||
memcpy(&blockData.data[(colDataPosition + (set << setShift)) >> 1], readDataBuffer, setSize >> 1);
|
||||
}
|
||||
|
||||
if (((1 << set) << setShift) < y0)
|
||||
{
|
||||
y0 = ((1 << set) << setShift);
|
||||
}
|
||||
if (((1 << set) << setShift) + (LEVEL_HEIGHT / 8) - 1 > y1)
|
||||
{
|
||||
y1 = ((1 << set) << setShift) + (LEVEL_HEIGHT / 8) - 1;
|
||||
}
|
||||
}
|
||||
if ((i % CHUNK_WIDTH) < x0)
|
||||
{
|
||||
x0 = (i % CHUNK_WIDTH);
|
||||
}
|
||||
if ((i % CHUNK_WIDTH) > x1)
|
||||
{
|
||||
x1 = (i % CHUNK_WIDTH);
|
||||
}
|
||||
if ((i / CHUNK_WIDTH) < z0)
|
||||
{
|
||||
z0 = (i / CHUNK_WIDTH);
|
||||
}
|
||||
if ((i / CHUNK_WIDTH) > z1)
|
||||
{
|
||||
z1 = (i / CHUNK_WIDTH);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (recalcHeight)
|
||||
{
|
||||
// chunk->recalcHeightmap();
|
||||
// //chunk->recalcBlockLights();
|
||||
level->setTilesDirty((packet->x << 4) + x0, y0, (packet->z << 4) + z0, (packet->x << 4) + x1, y1, (packet->z << 4) + z1);
|
||||
// int rx = packet->x << 4;
|
||||
// int rz = packet->z << 4;
|
||||
// level->updateLight(LightLayer::Block, x0 + rx - 1, y0, z0 + rz - 1, x1 + rx + 1, y1, z1 + rz + 1);
|
||||
// //for (int cx = x0; cx < x1; cx++)
|
||||
// //{
|
||||
// // for (int cz = z0; cz < z1; cz++)
|
||||
// // {
|
||||
// // for (int cy = y0; cy < y1; cy++)
|
||||
// // {
|
||||
// //level->updateLight(LightLayer::Sky, cx + rx, cy, cz + rz, cx + rx, cy, cz + rz);
|
||||
// // level->updateLight(LightLayer::Block, cx + rx - 1, cy, cz + rz - 1, cx + rx + 1, cy, cz + rz + 1);
|
||||
// // }
|
||||
// // }
|
||||
// //}
|
||||
//
|
||||
}
|
||||
//chunk->terrainPopulated = true;
|
||||
chunk->unsaved = false;
|
||||
|
||||
chunksLoaded[packet->x * CHUNK_CACHE_WIDTH + packet->z] = true;
|
||||
|
||||
if (areAllChunksLoaded())
|
||||
{
|
||||
ReadyPacket packet(ReadyPacket::READY_REQUESTEDCHUNKS);
|
||||
raknetInstance->send(packet);
|
||||
|
||||
for (unsigned int i = 0; i < bufferedBlockUpdates.size(); i++)
|
||||
{
|
||||
const SBufferedBlockUpdate& update = bufferedBlockUpdates[i];
|
||||
int tileId = Tile::transformToValidBlockId( update.blockId, update.x, update.y, update.z );
|
||||
if (update.setData)
|
||||
level->setTileAndData(update.x, update.y, update.z, tileId, update.blockData);
|
||||
else
|
||||
level->setTile(update.x, update.y, update.z, tileId);
|
||||
}
|
||||
bufferedBlockUpdates.clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
requestNextChunk();
|
||||
}
|
||||
}
|
||||
|
||||
class _ChunkSorter
|
||||
{
|
||||
public:
|
||||
_ChunkSorter(int x, int z)
|
||||
: x(x),
|
||||
y(z)
|
||||
{
|
||||
}
|
||||
|
||||
bool operator() (const IntPair& a, const IntPair& b) {
|
||||
const int ax = a.x - x, ay = a.y - y;
|
||||
const int bx = b.x - x, by = b.y - y;
|
||||
return (ax*ax + ay*ay) < (bx*bx + by*by);
|
||||
}
|
||||
private:
|
||||
int x;
|
||||
int y;
|
||||
};
|
||||
|
||||
|
||||
void ClientSideNetworkHandler::arrangeRequestChunkOrder() {
|
||||
clearChunksLoaded();
|
||||
|
||||
// Default sort is around center of the world
|
||||
int cx = CHUNK_CACHE_WIDTH / 2;
|
||||
int cz = CHUNK_CACHE_WIDTH / 2;
|
||||
|
||||
// If player exists, let's sort around him
|
||||
Player* p = minecraft? minecraft->player : NULL;
|
||||
if (p) {
|
||||
cx = Mth::floor(p->x / (float)CHUNK_WIDTH);
|
||||
cz = Mth::floor(p->z / (float)CHUNK_DEPTH);
|
||||
}
|
||||
|
||||
_ChunkSorter sorter(cx, cz);
|
||||
std::sort(requestNextChunkIndexList, requestNextChunkIndexList + NumRequestChunks, sorter);
|
||||
}
|
||||
|
||||
void ClientSideNetworkHandler::levelGenerated(Level* level)
|
||||
{
|
||||
this->level = level;
|
||||
ReadyPacket packet(ReadyPacket::READY_CLIENTGENERATION);
|
||||
raknetInstance->send(packet);
|
||||
|
||||
arrangeRequestChunkOrder();
|
||||
requestNextChunk();
|
||||
}
|
||||
|
||||
void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& source, PlayerEquipmentPacket* packet)
|
||||
{
|
||||
if (!level)
|
||||
return;
|
||||
|
||||
Entity* entity = level->getEntity(packet->entityId);
|
||||
if (!entity || !entity->isPlayer())
|
||||
return;
|
||||
|
||||
Player* player = (Player*)entity;
|
||||
// make sure it's not our local player
|
||||
if (player->owner == rakPeer->GetMyGUID())
|
||||
{
|
||||
printf("Attempted to modify local player's inventory\n");
|
||||
return;
|
||||
}
|
||||
// override the player's inventory
|
||||
//int slot = player->inventory->getSlot(packet->itemId, packet->itemAuxValue);
|
||||
//if (slot >= 0) {
|
||||
// player->inventory->moveToSelectedSlot(slot, true);
|
||||
//item->id = packet->itemId;
|
||||
//item->setAuxValue(packet->itemAuxValue);
|
||||
//item->count = 63;
|
||||
int slot = Inventory::MAX_SELECTION_SIZE;
|
||||
if (slot >= 0) {
|
||||
if (packet->itemId == 0) {
|
||||
player->inventory->clearSlot(slot);
|
||||
} else {
|
||||
ItemInstance newItem(packet->itemId, 63, packet->itemAuxValue);
|
||||
player->inventory->replaceSlot(slot, &newItem);
|
||||
}
|
||||
player->inventory->moveToSelectedSlot(slot, true);
|
||||
} else {
|
||||
LOGW("Warning: Remote player doesn't have his thing, Odd!\n");
|
||||
}
|
||||
}
|
||||
|
||||
void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& source, PlayerArmorEquipmentPacket* packet) {
|
||||
if (!level)
|
||||
return;
|
||||
|
||||
Entity* entity = level->getEntity(packet->entityId);
|
||||
if (!entity || !entity->isPlayer())
|
||||
return;
|
||||
|
||||
Player* player = (Player*)entity;
|
||||
// make sure it's not our local player, since that should be UpdateArmorPacket
|
||||
if (player->owner == rakPeer->GetMyGUID()) {
|
||||
printf("Attempted to modify local player's armor visually\n");
|
||||
return;
|
||||
}
|
||||
|
||||
packet->fillIn(player);
|
||||
}
|
||||
|
||||
void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& source, InteractPacket* packet)
|
||||
{
|
||||
if (!level)
|
||||
return;
|
||||
|
||||
Entity* src = level->getEntity(packet->sourceId);
|
||||
Entity* entity = level->getEntity(packet->targetId);
|
||||
if (src && entity && src->isPlayer())
|
||||
{
|
||||
Player* player = (Player*) src;
|
||||
if (InteractPacket::Attack == packet->action)
|
||||
minecraft->gameMode->attack(player, entity);
|
||||
if (InteractPacket::Interact == packet->action)
|
||||
minecraft->gameMode->interact(player, entity);
|
||||
}
|
||||
}
|
||||
|
||||
void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& source, SetEntityDataPacket* packet)
|
||||
{
|
||||
if (!level)
|
||||
return;
|
||||
|
||||
LOGI("SetEntityDataPacket\n");
|
||||
|
||||
Entity* e = level->getEntity(packet->id);
|
||||
if (e) {
|
||||
SynchedEntityData* data = e->getEntityData();
|
||||
if (data)
|
||||
data->assignValues(&packet->getUnpackedData());
|
||||
}
|
||||
}
|
||||
|
||||
void ClientSideNetworkHandler::handle( const RakNet::RakNetGUID& source, SetEntityMotionPacket* packet )
|
||||
{
|
||||
if (!level)
|
||||
return;
|
||||
|
||||
if (Entity* e = level->getEntity(packet->id)) {
|
||||
/*
|
||||
e->xd = packet->xd;
|
||||
e->yd = packet->yd;
|
||||
e->zd = packet->zd;
|
||||
*/
|
||||
e->lerpMotion(packet->xd, packet->yd, packet->zd);
|
||||
}
|
||||
}
|
||||
|
||||
void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& source, AnimatePacket* packet)
|
||||
{
|
||||
if (!level)
|
||||
return;
|
||||
|
||||
// Own player - Then don't play... :
|
||||
if (minecraft->player->entityId == packet->entityId) {
|
||||
if (packet->action == AnimatePacket::Swing) return;
|
||||
}
|
||||
|
||||
Entity* entity = level->getEntity(packet->entityId);
|
||||
if (!entity || !entity->isPlayer())
|
||||
return;
|
||||
|
||||
Player* player = (Player*) entity;
|
||||
|
||||
switch (packet->action) {
|
||||
case AnimatePacket::Swing:
|
||||
player->swing();
|
||||
break;
|
||||
case AnimatePacket::WAKE_UP:
|
||||
player->stopSleepInBed(false, false, false);
|
||||
break;
|
||||
default:
|
||||
LOGW("Unknown Animate action: %d\n", packet->action);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& source, UseItemPacket* packet)
|
||||
{
|
||||
}
|
||||
|
||||
void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& source, SetHealthPacket* packet)
|
||||
{
|
||||
if (!level || !minecraft->player)
|
||||
return;
|
||||
|
||||
minecraft->player->hurtTo(packet->health);
|
||||
}
|
||||
|
||||
void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& source, SetSpawnPositionPacket* packet) {
|
||||
if (!level || !minecraft || !minecraft->player) return;
|
||||
if (!level->inRange(packet->x, packet->y, packet->z)) return;
|
||||
|
||||
minecraft->player->setRespawnPosition(Pos(packet->x, packet->y, packet->z));
|
||||
level->getLevelData()->setSpawn(packet->x, packet->y, packet->z);
|
||||
}
|
||||
|
||||
void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& source, HurtArmorPacket* packet) {
|
||||
if (!level || !minecraft->player) {
|
||||
return;
|
||||
}
|
||||
|
||||
minecraft->player->hurtArmor(packet->dmg);
|
||||
}
|
||||
|
||||
void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& source, RespawnPacket* packet)
|
||||
{
|
||||
if (level) {
|
||||
//LOGI("RespawnPacket! %d\n", findPlayer(level, packet->entityId, NULL));
|
||||
NetEventCallback::handle(level, source, packet );
|
||||
}
|
||||
}
|
||||
|
||||
void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& source, ContainerOpenPacket* packet)
|
||||
{
|
||||
if (!level || !minecraft || !minecraft->player)
|
||||
return;
|
||||
|
||||
if (packet->type == ContainerType::FURNACE) {
|
||||
FurnaceTileEntity* te = new FurnaceTileEntity();
|
||||
te->clientSideOnly = true;
|
||||
minecraft->player->openFurnace(te);
|
||||
if (minecraft->player->containerMenu)
|
||||
minecraft->player->containerMenu->containerId = packet->containerId;
|
||||
}
|
||||
if (packet->type == ContainerType::CONTAINER) {
|
||||
ChestTileEntity* te = new ChestTileEntity();
|
||||
te->clientSideOnly = true;
|
||||
minecraft->player->openContainer(te);
|
||||
if (minecraft->player->containerMenu)
|
||||
minecraft->player->containerMenu->containerId = packet->containerId;
|
||||
}
|
||||
}
|
||||
|
||||
void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& source, ContainerClosePacket* packet)
|
||||
{
|
||||
if (minecraft && minecraft->player && minecraft->player->containerMenu)
|
||||
minecraft->player->closeContainer();
|
||||
}
|
||||
|
||||
void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& source, ContainerSetContentPacket* packet)
|
||||
{
|
||||
if (!minecraft || !minecraft->player)
|
||||
return;
|
||||
|
||||
if (packet->containerId == 0) {
|
||||
for (unsigned int i = 0; i < packet->items.size(); ++i) {
|
||||
minecraft->player->inventory->setItem(Inventory::MAX_SELECTION_SIZE + i, &packet->items[i]);
|
||||
}
|
||||
} else if (minecraft->player->containerMenu && minecraft->player->containerMenu->containerId == packet->containerId) {
|
||||
for (unsigned int i = 0; i < packet->items.size(); ++i) {
|
||||
minecraft->player->containerMenu->setSlot(i, &packet->items[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& source, ContainerSetSlotPacket* packet)
|
||||
{
|
||||
//LOGI("ContainerSetSlot\n");
|
||||
|
||||
if (!minecraft->player
|
||||
|| !minecraft->player->containerMenu
|
||||
|| minecraft->player->containerMenu->containerId != packet->containerId)
|
||||
return;
|
||||
|
||||
//minecraft->player->containerMenu->setSlot(packet->slot, packet->item.isNull()? NULL : &packet->item);
|
||||
minecraft->player->containerMenu->setSlot(packet->slot, &packet->item);
|
||||
}
|
||||
|
||||
void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& source, ContainerSetDataPacket* packet)
|
||||
{
|
||||
//LOGI("ContainerSetData\n");
|
||||
if (minecraft->player && minecraft->player->containerMenu && minecraft->player->containerMenu->containerId == packet->containerId) {
|
||||
//LOGI("client: SetData2 %d, %d\n", packet->id, packet->value);
|
||||
minecraft->player->containerMenu->setData(packet->id, packet->value);
|
||||
}
|
||||
}
|
||||
|
||||
void ClientSideNetworkHandler::handle( const RakNet::RakNetGUID& source, ChatPacket* packet )
|
||||
{
|
||||
#ifndef STANDALONE_SERVER
|
||||
minecraft->gui.displayClientMessage(packet->message);
|
||||
#endif
|
||||
}
|
||||
|
||||
void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& source, SignUpdatePacket* packet)
|
||||
{
|
||||
if (!level)
|
||||
return;
|
||||
|
||||
TileEntity* te = level->getTileEntity(packet->x, packet->y, packet->z);
|
||||
if (TileEntity::isType(te, TileEntityType::Sign)) {
|
||||
SignTileEntity* ste = (SignTileEntity*) te;
|
||||
if (ste->isEditable()) {
|
||||
for (int i = 0; i < SignTileEntity::NUM_LINES; i++) {
|
||||
ste->messages[i] = packet->lines[i];
|
||||
}
|
||||
//ste->setChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& source, AdventureSettingsPacket* packet) {
|
||||
if (!level)
|
||||
return;
|
||||
//assert(level != NULL && "level is NULL @ handle(AdventureSettingsPacket*)");
|
||||
|
||||
packet->fillIn(level->adventureSettings);
|
||||
}
|
||||
|
||||
void ClientSideNetworkHandler::clearChunksLoaded()
|
||||
{
|
||||
// Init the chunk positions
|
||||
for (int i = 0; i < NumRequestChunks; ++i) {
|
||||
requestNextChunkIndexList[i].x = i/CHUNK_WIDTH;
|
||||
requestNextChunkIndexList[i].y = i%CHUNK_WIDTH;
|
||||
chunksLoaded[i] = false;
|
||||
}
|
||||
}
|
||||
107
src/network/ClientSideNetworkHandler.h
Executable file
107
src/network/ClientSideNetworkHandler.h
Executable file
@@ -0,0 +1,107 @@
|
||||
#ifndef _MINECRAFT_NETWORK_CLIENTSIDENETWORKHANDLER_H_
|
||||
#define _MINECRAFT_NETWORK_CLIENTSIDENETWORKHANDLER_H_
|
||||
|
||||
|
||||
#include "NetEventCallback.h"
|
||||
#include "../raknet/RakNetTypes.h"
|
||||
#include "../world/level/LevelConstants.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
class Minecraft;
|
||||
class Level;
|
||||
class IRakNetInstance;
|
||||
|
||||
struct SBufferedBlockUpdate
|
||||
{
|
||||
int x, z;
|
||||
unsigned char y;
|
||||
unsigned char blockId;
|
||||
unsigned char blockData;
|
||||
bool setData;
|
||||
};
|
||||
typedef std::vector<SBufferedBlockUpdate> BlockUpdateList;
|
||||
|
||||
typedef struct IntPair {
|
||||
int x, y;
|
||||
} IntPair;
|
||||
|
||||
class ClientSideNetworkHandler : public NetEventCallback
|
||||
{
|
||||
public:
|
||||
ClientSideNetworkHandler(Minecraft* minecraft, IRakNetInstance* raknetInstance);
|
||||
virtual ~ClientSideNetworkHandler();
|
||||
|
||||
virtual void levelGenerated(Level* level);
|
||||
|
||||
virtual void onConnect(const RakNet::RakNetGUID& hostGuid);
|
||||
virtual void onUnableToConnect();
|
||||
virtual void onDisconnect(const RakNet::RakNetGUID& guid);
|
||||
|
||||
virtual void handle(const RakNet::RakNetGUID& source, LoginStatusPacket* packet);
|
||||
virtual void handle(const RakNet::RakNetGUID& source, StartGamePacket* packet);
|
||||
virtual void handle(const RakNet::RakNetGUID& source, MessagePacket* packet);
|
||||
virtual void handle(const RakNet::RakNetGUID& source, SetTimePacket* packet);
|
||||
virtual void handle(const RakNet::RakNetGUID& source, AddItemEntityPacket* packet);
|
||||
virtual void handle(const RakNet::RakNetGUID& source, AddPaintingPacket* packet);
|
||||
virtual void handle(const RakNet::RakNetGUID& source, TakeItemEntityPacket* packet);
|
||||
virtual void handle(const RakNet::RakNetGUID& source, AddEntityPacket* packet);
|
||||
virtual void handle(const RakNet::RakNetGUID& source, AddMobPacket* packet);
|
||||
virtual void handle(const RakNet::RakNetGUID& source, AddPlayerPacket* packet);
|
||||
virtual void handle(const RakNet::RakNetGUID& source, RemoveEntityPacket* packet);
|
||||
virtual void handle(const RakNet::RakNetGUID& source, RemovePlayerPacket* packet);
|
||||
virtual void handle(const RakNet::RakNetGUID& source, MovePlayerPacket* packet);
|
||||
virtual void handle(const RakNet::RakNetGUID& source, MoveEntityPacket* packet);
|
||||
virtual void handle(const RakNet::RakNetGUID& source, UpdateBlockPacket* packet);
|
||||
virtual void handle(const RakNet::RakNetGUID& source, ExplodePacket* packet);
|
||||
virtual void handle(const RakNet::RakNetGUID& source, LevelEventPacket* packet);
|
||||
virtual void handle(const RakNet::RakNetGUID& source, TileEventPacket* packet);
|
||||
virtual void handle(const RakNet::RakNetGUID& source, EntityEventPacket* packet);
|
||||
virtual void handle(const RakNet::RakNetGUID& source, ChunkDataPacket* packet);
|
||||
virtual void handle(const RakNet::RakNetGUID& source, PlayerEquipmentPacket* packet);
|
||||
virtual void handle(const RakNet::RakNetGUID& source, PlayerArmorEquipmentPacket* packet);
|
||||
virtual void handle(const RakNet::RakNetGUID& source, InteractPacket* packet);
|
||||
virtual void handle(const RakNet::RakNetGUID& source, SetEntityDataPacket* packet);
|
||||
virtual void handle(const RakNet::RakNetGUID& source, SetEntityMotionPacket* packet);
|
||||
virtual void handle(const RakNet::RakNetGUID& source, SetHealthPacket* packet);
|
||||
virtual void handle(const RakNet::RakNetGUID& source, SetSpawnPositionPacket* packet);
|
||||
virtual void handle(const RakNet::RakNetGUID& source, AnimatePacket* packet);
|
||||
virtual void handle(const RakNet::RakNetGUID& source, UseItemPacket* packet);
|
||||
virtual void handle(const RakNet::RakNetGUID& source, HurtArmorPacket* packet);
|
||||
virtual void handle(const RakNet::RakNetGUID& source, RespawnPacket* packet);
|
||||
virtual void handle(const RakNet::RakNetGUID& source, ContainerOpenPacket* packet);
|
||||
virtual void handle(const RakNet::RakNetGUID& source, ContainerClosePacket* packet);
|
||||
virtual void handle(const RakNet::RakNetGUID& source, ContainerSetContentPacket* packet);
|
||||
virtual void handle(const RakNet::RakNetGUID& source, ContainerSetSlotPacket* packet);
|
||||
virtual void handle(const RakNet::RakNetGUID& source, ContainerSetDataPacket* packet);
|
||||
virtual void handle(const RakNet::RakNetGUID& source, ChatPacket* packet);
|
||||
virtual void handle(const RakNet::RakNetGUID& source, AdventureSettingsPacket* packet);
|
||||
virtual void handle(const RakNet::RakNetGUID& source, SignUpdatePacket* packet);
|
||||
private:
|
||||
|
||||
void requestNextChunk();
|
||||
void arrangeRequestChunkOrder();
|
||||
|
||||
bool isChunkLoaded(int x, int z);
|
||||
bool areAllChunksLoaded();
|
||||
void clearChunksLoaded();
|
||||
private:
|
||||
|
||||
Minecraft* minecraft;
|
||||
Level* level;
|
||||
IRakNetInstance* raknetInstance;
|
||||
RakNet::RakPeerInterface* rakPeer;
|
||||
|
||||
RakNet::RakNetGUID serverGuid;
|
||||
|
||||
BlockUpdateList bufferedBlockUpdates;
|
||||
int requestNextChunkPosition;
|
||||
|
||||
static const int NumRequestChunks = CHUNK_CACHE_WIDTH * CHUNK_CACHE_WIDTH;
|
||||
|
||||
int requestNextChunkIndex;
|
||||
IntPair requestNextChunkIndexList[NumRequestChunks];
|
||||
bool chunksLoaded[NumRequestChunks];
|
||||
};
|
||||
|
||||
#endif
|
||||
33
src/network/NATPunchHandler.cpp
Executable file
33
src/network/NATPunchHandler.cpp
Executable file
@@ -0,0 +1,33 @@
|
||||
#include "NATPunchHandler.h"
|
||||
#include "../raknet/TCPInterface.h"
|
||||
#include "../raknet/HTTPConnection.h"
|
||||
#include "PHPDirectoryServer2.h"
|
||||
|
||||
using namespace RakNet;
|
||||
NATPuchHandler::NATPuchHandler() {
|
||||
tcpInterface = new TCPInterface;
|
||||
}
|
||||
NATPuchHandler::~NATPuchHandler() {
|
||||
delete tcpInterface;
|
||||
}
|
||||
|
||||
void NATPuchHandler::initialize() {
|
||||
tcpInterface->Start(0, 64);
|
||||
}
|
||||
|
||||
void NATPuchHandler::registerToGameList(const RakNet::RakString& serverName, int port) {
|
||||
HTTPConnection httpConnection;
|
||||
httpConnection.Init(tcpInterface, "johanbernhardsson.se");
|
||||
PHPDirectoryServer2 directoryServer;
|
||||
directoryServer.Init(&httpConnection, "/DirectoryServer.php");
|
||||
directoryServer.UploadTable("", serverName, port, true);
|
||||
}
|
||||
|
||||
void NATPuchHandler::removeFromGameList() {
|
||||
|
||||
}
|
||||
|
||||
void NATPuchHandler::close() {
|
||||
|
||||
}
|
||||
|
||||
24
src/network/NATPunchHandler.h
Executable file
24
src/network/NATPunchHandler.h
Executable file
@@ -0,0 +1,24 @@
|
||||
#ifndef _MINECRAFT_NETWORK_NATPUNCHHANDLER_H_
|
||||
#define _MINECRAFT_NETWORK_NATPUNCHHANDLER_H_
|
||||
#include "../raknet/TCPInterface.h"
|
||||
#include "../raknet/RakString.h"
|
||||
class NATPuchHandler {
|
||||
public:
|
||||
enum NATPuchHandlerStatus {
|
||||
NATPuchInitilized = 0,
|
||||
NATPuchFetchingServerList = 1,
|
||||
NATPuchConnecting = 2,
|
||||
NATPuchConnected = 3,
|
||||
NATPuchDissconnected = 4
|
||||
};
|
||||
NATPuchHandler();
|
||||
~NATPuchHandler();
|
||||
void initialize();
|
||||
void registerToGameList(const RakNet::RakString& serverName, int port);
|
||||
void removeFromGameList();
|
||||
void close();
|
||||
private:
|
||||
RakNet::TCPInterface *tcpInterface;
|
||||
};
|
||||
|
||||
#endif /* _MINECRAFT_NETWORK_NATPUNCHHANDLER_H_ */
|
||||
59
src/network/NetEventCallback.cpp
Executable file
59
src/network/NetEventCallback.cpp
Executable file
@@ -0,0 +1,59 @@
|
||||
#include "NetEventCallback.h"
|
||||
#include "../world/level/Level.h"
|
||||
#include "packet/RespawnPacket.h"
|
||||
|
||||
//
|
||||
// Common packet handling implementation for Client and Server
|
||||
//
|
||||
/*
|
||||
void NetEventCallback::handle( const RakNet::RakNetGUID& source, AnimatePacket* packet )
|
||||
{
|
||||
Entity* entity = level->getEntity(packet->entityId);
|
||||
if (entity && entity->isPlayer()) {
|
||||
Player* player = (Player*) entity;
|
||||
|
||||
switch (packet->action) {
|
||||
case AnimatePacket::Swing:
|
||||
player->swing();
|
||||
break;
|
||||
default:
|
||||
LOGW("Unknown Animate action: %d\n", packet->action);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
Player* NetEventCallback::findPlayer(Level* level, int entityId) {
|
||||
Entity* e = level->getEntity(entityId);
|
||||
if (e) {
|
||||
if (e->isPlayer()) return (Player*) e;
|
||||
LOGE("Entity: %p is supposed to be a player but is not (type %d)!\n", e, e->getEntityTypeId());
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Player* NetEventCallback::findPlayer(Level* level, const RakNet::RakNetGUID* source) {
|
||||
for (unsigned int i = 0; i < level->players.size(); ++i)
|
||||
if (level->players[i]->owner == *source) return level->players[i];
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Player* NetEventCallback::findPlayer( Level* level, int entityId, const RakNet::RakNetGUID* source )
|
||||
{
|
||||
if (entityId != -1)
|
||||
if (Player* p = findPlayer(level, entityId)) return p;
|
||||
if (source != NULL)
|
||||
if (Player* p = findPlayer(level, source)) return p;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void NetEventCallback::handle( Level* level, const RakNet::RakNetGUID& source, RespawnPacket* packet )
|
||||
{
|
||||
if (Player* p = findPlayer(level, packet->entityId, NULL)) {
|
||||
p->moveTo(packet->x, packet->y, packet->z, p->yRot, p->xRot);
|
||||
p->reset();
|
||||
p->resetPos(true);
|
||||
}
|
||||
}
|
||||
134
src/network/NetEventCallback.h
Executable file
134
src/network/NetEventCallback.h
Executable file
@@ -0,0 +1,134 @@
|
||||
#ifndef _MINECRAFT_NETWORK_NETEVENTCALLBACK_H_
|
||||
#define _MINECRAFT_NETWORK_NETEVENTCALLBACK_H_
|
||||
|
||||
class AddItemEntityPacket;
|
||||
class AddPaintingPacket;
|
||||
class AdventureSettingsPacket;
|
||||
class TakeItemEntityPacket;
|
||||
class LoginPacket;
|
||||
class ReadyPacket;
|
||||
class LoginStatusPacket;
|
||||
class MessagePacket;
|
||||
class SetTimePacket;
|
||||
class StartGamePacket;
|
||||
class AddEntityPacket;
|
||||
class AddMobPacket;
|
||||
class AddPlayerPacket;
|
||||
class RemovePlayerPacket;
|
||||
class RemoveEntityPacket;
|
||||
class MoveEntityPacket;
|
||||
//class TeleportEntityPacket;
|
||||
class MovePlayerPacket;
|
||||
class PlaceBlockPacket;
|
||||
class RemoveBlockPacket;
|
||||
class UpdateBlockPacket;
|
||||
class ExplodePacket;
|
||||
class LevelEventPacket;
|
||||
class TileEventPacket;
|
||||
class EntityEventPacket;
|
||||
class RequestChunkPacket;
|
||||
class ChunkDataPacket;
|
||||
class PlayerEquipmentPacket;
|
||||
class PlayerArmorEquipmentPacket;
|
||||
class InteractPacket;
|
||||
class SetEntityDataPacket;
|
||||
class SetEntityMotionPacket;
|
||||
class SetHealthPacket;
|
||||
class SetSpawnPositionPacket;
|
||||
class SendInventoryPacket;
|
||||
class DropItemPacket;
|
||||
class AnimatePacket;
|
||||
class UseItemPacket;
|
||||
class PlayerActionPacket;
|
||||
class HurtArmorPacket;
|
||||
class RespawnPacket;
|
||||
class ContainerAckPacket;
|
||||
class ContainerOpenPacket;
|
||||
class ContainerClosePacket;
|
||||
class ContainerSetSlotPacket;
|
||||
class ContainerSetDataPacket;
|
||||
class ContainerSetContentPacket;
|
||||
class ChatPacket;
|
||||
class SignUpdatePacket;
|
||||
class Minecraft;
|
||||
class Level;
|
||||
|
||||
#include "../world/level/tile/Tile.h"
|
||||
|
||||
namespace RakNet
|
||||
{
|
||||
struct RakNetGUID;
|
||||
}
|
||||
|
||||
class NetEventCallback
|
||||
{
|
||||
public:
|
||||
virtual void levelGenerated(Level* level) {}
|
||||
virtual ~NetEventCallback() {}
|
||||
|
||||
virtual void onConnect(const RakNet::RakNetGUID& hostGuid) {};
|
||||
virtual void onUnableToConnect() {};
|
||||
virtual void onNewClient(const RakNet::RakNetGUID& clientGuid) {};
|
||||
virtual void onDisconnect(const RakNet::RakNetGUID& guid) {};
|
||||
|
||||
virtual void handle(const RakNet::RakNetGUID& source, LoginPacket* packet) {}
|
||||
virtual void handle(const RakNet::RakNetGUID& source, ReadyPacket* packet) {}
|
||||
virtual void handle(const RakNet::RakNetGUID& source, LoginStatusPacket* packet) {}
|
||||
virtual void handle(const RakNet::RakNetGUID& source, SetTimePacket* packet) {}
|
||||
virtual void handle(const RakNet::RakNetGUID& source, MessagePacket* packet) {}
|
||||
virtual void handle(const RakNet::RakNetGUID& source, StartGamePacket* packet) {}
|
||||
virtual void handle(const RakNet::RakNetGUID& source, AddItemEntityPacket* packet) {}
|
||||
virtual void handle(const RakNet::RakNetGUID& source, AddPaintingPacket* packet) {}
|
||||
virtual void handle(const RakNet::RakNetGUID& source, TakeItemEntityPacket* packet) {}
|
||||
virtual void handle(const RakNet::RakNetGUID& source, AddEntityPacket* packet) {}
|
||||
virtual void handle(const RakNet::RakNetGUID& source, AddMobPacket* packet) {}
|
||||
virtual void handle(const RakNet::RakNetGUID& source, AddPlayerPacket* packet) {}
|
||||
virtual void handle(const RakNet::RakNetGUID& source, RemovePlayerPacket* packet) {}
|
||||
virtual void handle(const RakNet::RakNetGUID& source, RemoveEntityPacket* packet) {}
|
||||
virtual void handle(const RakNet::RakNetGUID& source, MoveEntityPacket* packet) {}
|
||||
//virtual void handle(const RakNet::RakNetGUID& source, TeleportEntityPacket* packet) {}
|
||||
virtual void handle(const RakNet::RakNetGUID& source, MovePlayerPacket* packet) {}
|
||||
virtual void handle(const RakNet::RakNetGUID& source, PlaceBlockPacket* packet) {}
|
||||
virtual void handle(const RakNet::RakNetGUID& source, RemoveBlockPacket* packet) {}
|
||||
virtual void handle(const RakNet::RakNetGUID& source, UpdateBlockPacket* packet) {}
|
||||
virtual void handle(const RakNet::RakNetGUID& source, ExplodePacket* packet) {}
|
||||
virtual void handle(const RakNet::RakNetGUID& source, LevelEventPacket* packet) {}
|
||||
virtual void handle(const RakNet::RakNetGUID& source, TileEventPacket* packet) {}
|
||||
virtual void handle(const RakNet::RakNetGUID& source, EntityEventPacket* packet) {}
|
||||
virtual void handle(const RakNet::RakNetGUID& source, RequestChunkPacket* packet) {}
|
||||
virtual void handle(const RakNet::RakNetGUID& source, ChunkDataPacket* packet) {}
|
||||
virtual void handle(const RakNet::RakNetGUID& source, PlayerEquipmentPacket* packet) {}
|
||||
virtual void handle(const RakNet::RakNetGUID& source, PlayerArmorEquipmentPacket* packet) {}
|
||||
virtual void handle(const RakNet::RakNetGUID& source, SetEntityDataPacket* packet) {}
|
||||
virtual void handle(const RakNet::RakNetGUID& source, SetEntityMotionPacket* packet) {}
|
||||
virtual void handle(const RakNet::RakNetGUID& source, SetHealthPacket* packet) {}
|
||||
virtual void handle(const RakNet::RakNetGUID& source, SetSpawnPositionPacket* packet) {}
|
||||
virtual void handle(const RakNet::RakNetGUID& source, InteractPacket* packet) {}
|
||||
virtual void handle(const RakNet::RakNetGUID& source, UseItemPacket* packet) {}
|
||||
virtual void handle(const RakNet::RakNetGUID& source, PlayerActionPacket* packet) {}
|
||||
virtual void handle(const RakNet::RakNetGUID& source, HurtArmorPacket* packet) {}
|
||||
virtual void handle(const RakNet::RakNetGUID& source, SendInventoryPacket* packet) {}
|
||||
virtual void handle(const RakNet::RakNetGUID& source, DropItemPacket* packet) {}
|
||||
virtual void handle(const RakNet::RakNetGUID& source, ContainerOpenPacket* packet) {}
|
||||
virtual void handle(const RakNet::RakNetGUID& source, ContainerClosePacket* packet) {}
|
||||
virtual void handle(const RakNet::RakNetGUID& source, ContainerAckPacket* packet) {}
|
||||
virtual void handle(const RakNet::RakNetGUID& source, ContainerSetDataPacket* packet) {}
|
||||
virtual void handle(const RakNet::RakNetGUID& source, ContainerSetSlotPacket* packet) {}
|
||||
virtual void handle(const RakNet::RakNetGUID& source, ContainerSetContentPacket* packet) {}
|
||||
virtual void handle(const RakNet::RakNetGUID& source, ChatPacket* packet) {}
|
||||
virtual void handle(const RakNet::RakNetGUID& source, SignUpdatePacket* packet) {}
|
||||
virtual void handle(const RakNet::RakNetGUID& source, AdventureSettingsPacket* packet) {}
|
||||
virtual void handle(const RakNet::RakNetGUID& source, AnimatePacket* packet) {}
|
||||
|
||||
//
|
||||
// Common implementation for Client and Server
|
||||
//
|
||||
virtual void handle(const RakNet::RakNetGUID& source, RespawnPacket* packet) {}
|
||||
virtual void handle(Level* level, const RakNet::RakNetGUID& source, RespawnPacket* packet);
|
||||
|
||||
Player* findPlayer(Level* level, int entityId);
|
||||
Player* findPlayer(Level* level, const RakNet::RakNetGUID* source);
|
||||
Player* findPlayer(Level* level, int entityId, const RakNet::RakNetGUID* source);
|
||||
};
|
||||
|
||||
#endif
|
||||
293
src/network/PHPDirectoryServer2.cpp
Executable file
293
src/network/PHPDirectoryServer2.cpp
Executable file
@@ -0,0 +1,293 @@
|
||||
/// \file
|
||||
/// \brief Contains WebGameList, a client for communicating with a HTTP list of game servers
|
||||
///
|
||||
/// This file is part of RakNet Copyright 2008 Kevin Jenkins.
|
||||
///
|
||||
/// Usage of RakNet is subject to the appropriate license agreement.
|
||||
/// Creative Commons Licensees are subject to the
|
||||
/// license found at
|
||||
/// http://creativecommons.org/licenses/by-nc/2.5/
|
||||
/// Single application licensees are subject to the license found at
|
||||
/// http://www.jenkinssoftware.com/SingleApplicationLicense.html
|
||||
/// Custom license users are subject to the terms therein.
|
||||
/// GPL license users are subject to the GNU General Public
|
||||
/// License as published by the Free
|
||||
/// Software Foundation
|
||||
|
||||
#include "PHPDirectoryServer2.h"
|
||||
#include "../raknet/HTTPConnection.h"
|
||||
#include "../raknet/RakSleep.h"
|
||||
#include "../raknet/RakString.h"
|
||||
#include "../raknet/RakNetTypes.h"
|
||||
#include "../raknet/GetTime.h"
|
||||
#include "../raknet/RakAssert.h"
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
#include <cstdio>
|
||||
#include "../raknet/Itoa.h"
|
||||
|
||||
// Column with this header contains the name of the game, passed to UploadTable()
|
||||
static const char *GAME_NAME_COMMAND="__GAME_NAME";
|
||||
// Column with this header contains the port of the game, passed to UploadTable()
|
||||
static const char *GAME_PORT_COMMAND="__GAME_PORT";
|
||||
// Column with this header contains the IP address of the game, passed to UploadTable()
|
||||
static const char *SYSTEM_ADDRESS_COMMAND="_System_Address";
|
||||
// Returned from the PHP server indicating when this row was last updated.
|
||||
static const char *LAST_UPDATE_COMMAND="__SEC_AFTER_EPOCH_SINCE_LAST_UPDATE";
|
||||
|
||||
using namespace RakNet;
|
||||
using namespace DataStructures;
|
||||
|
||||
PHPDirectoryServer2::PHPDirectoryServer2()
|
||||
: nextRepost(0)
|
||||
{
|
||||
Map<RakString, RakString>::IMPLEMENT_DEFAULT_COMPARISON();
|
||||
}
|
||||
PHPDirectoryServer2::~PHPDirectoryServer2()
|
||||
{
|
||||
}
|
||||
void PHPDirectoryServer2::Init(HTTPConnection *_http, const char *_path)
|
||||
{
|
||||
http=_http;
|
||||
pathToPHP=_path;
|
||||
}
|
||||
|
||||
void PHPDirectoryServer2::SetField( RakNet::RakString columnName, RakNet::RakString value )
|
||||
{
|
||||
if (columnName.IsEmpty())
|
||||
return;
|
||||
|
||||
if (columnName==GAME_NAME_COMMAND ||
|
||||
columnName==GAME_PORT_COMMAND ||
|
||||
columnName==LAST_UPDATE_COMMAND)
|
||||
{
|
||||
RakAssert("PHPDirectoryServer2::SetField attempted to set reserved column name" && 0);
|
||||
return;
|
||||
}
|
||||
|
||||
fields.Set(columnName, value);
|
||||
}
|
||||
unsigned int PHPDirectoryServer2::GetFieldCount(void) const
|
||||
{
|
||||
return fields.Size();
|
||||
}
|
||||
void PHPDirectoryServer2::GetField(unsigned int index, RakNet::RakString &columnName, RakNet::RakString &value)
|
||||
{
|
||||
RakAssert(index < fields.Size());
|
||||
columnName=fields.GetKeyAtIndex(index);
|
||||
value=fields[index];
|
||||
}
|
||||
void PHPDirectoryServer2::SetFields(DataStructures::Table *table)
|
||||
{
|
||||
ClearFields();
|
||||
|
||||
unsigned columnIndex, rowIndex;
|
||||
DataStructures::Table::Row *row;
|
||||
|
||||
for (rowIndex=0; rowIndex < table->GetRowCount(); rowIndex++)
|
||||
{
|
||||
row = table->GetRowByIndex(rowIndex, 0);
|
||||
for (columnIndex=0; columnIndex < table->GetColumnCount(); columnIndex++)
|
||||
{
|
||||
SetField( table->ColumnName(columnIndex), row->cells[columnIndex]->ToString(table->GetColumnType(columnIndex)) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PHPDirectoryServer2::ClearFields(void)
|
||||
{
|
||||
fields.Clear();
|
||||
nextRepost=0;
|
||||
}
|
||||
|
||||
void PHPDirectoryServer2::UploadTable(RakNet::RakString uploadPassword, RakNet::RakString gameName, unsigned short gamePort, bool autoRepost)
|
||||
{
|
||||
gameNameParam=gameName;
|
||||
gamePortParam=gamePort;
|
||||
currentOperation="";
|
||||
currentOperation="?query=upload&uploadPassword=";
|
||||
currentOperation+=uploadPassword;
|
||||
SendOperation();
|
||||
|
||||
if (autoRepost)
|
||||
nextRepost=RakNet::GetTimeMS()+50000;
|
||||
else
|
||||
nextRepost=0;
|
||||
}
|
||||
void PHPDirectoryServer2::DownloadTable(RakNet::RakString downloadPassword)
|
||||
{
|
||||
currentOperation="?query=download&downloadPassword=";
|
||||
currentOperation+=downloadPassword;
|
||||
SendOperation();
|
||||
}
|
||||
void PHPDirectoryServer2::UploadAndDownloadTable(RakNet::RakString uploadPassword, RakNet::RakString downloadPassword, RakNet::RakString gameName, unsigned short gamePort, bool autoRepost)
|
||||
{
|
||||
gameNameParam=gameName;
|
||||
gamePortParam=gamePort;
|
||||
currentOperation="?query=upDown&downloadPassword=";
|
||||
currentOperation+=downloadPassword;
|
||||
currentOperation+="&uploadPassword=";
|
||||
currentOperation+=uploadPassword;
|
||||
|
||||
SendOperation();
|
||||
|
||||
if (autoRepost)
|
||||
nextRepost=RakNet::GetTimeMS()+50000;
|
||||
else
|
||||
nextRepost=0;
|
||||
}
|
||||
|
||||
HTTPReadResult PHPDirectoryServer2::ProcessHTTPRead(RakNet::RakString httpRead)
|
||||
{
|
||||
const char *c = (const char*) httpRead.C_String(); // current position
|
||||
HTTPReadResult resultCode=HTTP_RESULT_EMPTY;
|
||||
|
||||
lastDownloadedTable.Clear();
|
||||
|
||||
|
||||
if (*c=='\n')
|
||||
c++;
|
||||
char buff[256];
|
||||
int buffIndex;
|
||||
bool isCommand=true;
|
||||
DataStructures::List<RakNet::RakString> columns;
|
||||
DataStructures::List<RakNet::RakString> values;
|
||||
RakNet::RakString curString;
|
||||
bool isComment=false;
|
||||
buffIndex=0;
|
||||
while(c && *c)
|
||||
{
|
||||
// 3 is comment
|
||||
if (*c=='\003')
|
||||
{
|
||||
isComment=!isComment;
|
||||
c++;
|
||||
continue;
|
||||
}
|
||||
if (isComment)
|
||||
{
|
||||
c++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// 1 or 2 separates fields
|
||||
// 4 separates rows
|
||||
if (*c=='\001')
|
||||
{
|
||||
if (isCommand)
|
||||
{
|
||||
buff[buffIndex]=0;
|
||||
columns.Push(RakString::NonVariadic(buff), _FILE_AND_LINE_);
|
||||
isCommand=false;
|
||||
if (buff[0]!=0)
|
||||
resultCode=HTTP_RESULT_GOT_TABLE;
|
||||
}
|
||||
else
|
||||
{
|
||||
buff[buffIndex]=0;
|
||||
values.Push(RakString::NonVariadic(buff), _FILE_AND_LINE_);
|
||||
isCommand=true;
|
||||
}
|
||||
buffIndex=0;
|
||||
}
|
||||
else if (*c=='\002')
|
||||
{
|
||||
buff[buffIndex]=0;
|
||||
buffIndex=0;
|
||||
values.Push(RakString::NonVariadic(buff), _FILE_AND_LINE_);
|
||||
isCommand=true;
|
||||
PushColumnsAndValues(columns, values);
|
||||
columns.Clear(true, _FILE_AND_LINE_);
|
||||
values.Clear(true, _FILE_AND_LINE_);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
if (buffIndex<256-1)
|
||||
buff[buffIndex++]=*c;
|
||||
}
|
||||
c++;
|
||||
}
|
||||
if (buff[0] && columns.Size()==values.Size()+1)
|
||||
{
|
||||
buff[buffIndex]=0;
|
||||
values.Push(RakString::NonVariadic(buff), _FILE_AND_LINE_);
|
||||
}
|
||||
|
||||
PushColumnsAndValues(columns, values);
|
||||
|
||||
return resultCode;
|
||||
}
|
||||
void PHPDirectoryServer2::PushColumnsAndValues(DataStructures::List<RakNet::RakString> &columns, DataStructures::List<RakNet::RakString> &values)
|
||||
{
|
||||
DataStructures::Table::Row *row=0;
|
||||
|
||||
unsigned int i;
|
||||
for (i=0; i < columns.Size() && i < values.Size(); i++)
|
||||
{
|
||||
if (columns[i].IsEmpty()==false)
|
||||
{
|
||||
unsigned col = lastDownloadedTable.ColumnIndex(columns[i]);
|
||||
if(col == (unsigned)-1)
|
||||
{
|
||||
col = lastDownloadedTable.AddColumn(columns[i], DataStructures::Table::STRING);
|
||||
}
|
||||
|
||||
if (row==0)
|
||||
{
|
||||
row = lastDownloadedTable.AddRow(lastDownloadedTable.GetAvailableRowId());
|
||||
}
|
||||
row->UpdateCell(col,values[i].C_String());
|
||||
}
|
||||
}
|
||||
}
|
||||
const DataStructures::Table *PHPDirectoryServer2::GetLastDownloadedTable(void) const
|
||||
{
|
||||
return &lastDownloadedTable;
|
||||
}
|
||||
void PHPDirectoryServer2::SendOperation(void)
|
||||
{
|
||||
RakString outgoingMessageBody;
|
||||
char buff[64];
|
||||
|
||||
outgoingMessageBody += GAME_PORT_COMMAND;
|
||||
outgoingMessageBody += '\001';
|
||||
outgoingMessageBody += Itoa(gamePortParam,buff,10);
|
||||
outgoingMessageBody += '\001';
|
||||
outgoingMessageBody += GAME_NAME_COMMAND;
|
||||
outgoingMessageBody += '\001';
|
||||
outgoingMessageBody += gameNameParam;
|
||||
|
||||
for (unsigned i = 0; i < fields.Size(); i++)
|
||||
{
|
||||
RakString value = fields[i];
|
||||
value.URLEncode();
|
||||
outgoingMessageBody += RakString("\001%s\001%s",
|
||||
fields.GetKeyAtIndex(i).C_String(),
|
||||
value.C_String());
|
||||
}
|
||||
|
||||
RakString postURL;
|
||||
postURL+=pathToPHP;
|
||||
postURL+=currentOperation;
|
||||
http->Post(postURL.C_String(), outgoingMessageBody, "application/x-www-form-urlencoded");
|
||||
|
||||
}
|
||||
void PHPDirectoryServer2::Update(void)
|
||||
{
|
||||
if (http->IsBusy())
|
||||
return;
|
||||
|
||||
|
||||
if (nextRepost==0 || fields.Size()==0)
|
||||
return;
|
||||
|
||||
RakNet::TimeMS time = GetTimeMS();
|
||||
|
||||
// Entry deletes itself after 60 seconds, so keep reposting if set to do so
|
||||
if (time > nextRepost)
|
||||
{
|
||||
nextRepost=RakNet::GetTimeMS()+50000;
|
||||
SendOperation();
|
||||
}
|
||||
}
|
||||
137
src/network/PHPDirectoryServer2.h
Executable file
137
src/network/PHPDirectoryServer2.h
Executable file
@@ -0,0 +1,137 @@
|
||||
/// \file
|
||||
/// \brief Contains PHPDirectoryServer2, a client for communicating with a HTTP list of game servers
|
||||
///
|
||||
/// This file is part of RakNet Copyright 2008 Kevin Jenkins.
|
||||
///
|
||||
/// Usage of RakNet is subject to the appropriate license agreement.
|
||||
/// Creative Commons Licensees are subject to the
|
||||
/// license found at
|
||||
/// http://creativecommons.org/licenses/by-nc/2.5/
|
||||
/// Single application licensees are subject to the license found at
|
||||
/// http://www.jenkinssoftware.com/SingleApplicationLicense.html
|
||||
/// Custom license users are subject to the terms therein.
|
||||
/// GPL license users are subject to the GNU General Public
|
||||
/// License as published by the Free
|
||||
/// Software Foundation; either version 2 of the License, or (at your
|
||||
/// option) any later version.
|
||||
|
||||
#ifndef __PHP_DIRECTORY_SERVER_2
|
||||
#define __PHP_DIRECTORY_SERVER_2
|
||||
|
||||
#include "../raknet/RakString.h"
|
||||
#include "../raknet/HTTPConnection.h"
|
||||
#include "../raknet/RakNetTypes.h"
|
||||
#include "../raknet/DS_Queue.h"
|
||||
#include "../raknet/DS_Table.h"
|
||||
#include "../raknet/DS_Map.h"
|
||||
|
||||
namespace RakNet {
|
||||
|
||||
struct SystemAddress;
|
||||
|
||||
enum HTTPReadResult
|
||||
{
|
||||
HTTP_RESULT_GOT_TABLE,
|
||||
HTTP_RESULT_EMPTY
|
||||
};
|
||||
|
||||
/// \brief Use PHPDirectoryServer2 as a C++ client to DirectoryServer.php
|
||||
///
|
||||
/// PHPDirectoryServer2 works with the HTTPConnection class (which works with the TCPInterface class) in order to communiate with DirectoryServer.php found under Samples/PHPDirectoryServer2
|
||||
class PHPDirectoryServer2
|
||||
{
|
||||
public:
|
||||
PHPDirectoryServer2();
|
||||
virtual ~PHPDirectoryServer2();
|
||||
|
||||
/// Associate PHPDirectoryServer2 with the HTTPConnection class it will communicate through
|
||||
/// \param[in] _http The instance of HTTP connection we will communicate through
|
||||
/// \param[in] _path The path to the PHP file on the remote server. For example, if the path is mysite.com/raknet/DirectoryServer.php then you would enter raknet/DirectoryServer.php
|
||||
void Init(HTTPConnection *_http, const char *_path);
|
||||
|
||||
/// Set a parameter (these are passed to the server)
|
||||
/// To delete a column, just pass an empty string for value
|
||||
/// Store the game name and port with UploadTable, rather than SetField, as these columns are required and use reserved column names
|
||||
/// \param[in] columnName The name of the column to store
|
||||
/// \param[in] value What value to hold for the uploaded row (only one row can be uploaded at a time)
|
||||
void SetField(RakNet::RakString columnName, RakNet::RakString value);
|
||||
|
||||
/// Returns the number of fields set with SetField()
|
||||
unsigned int GetFieldCount(void) const;
|
||||
|
||||
/// Returns a field set with SetField()
|
||||
/// \param[in] index The 0 based index into the field list
|
||||
/// \param[out] columnName The \a columnName parameter passed to SetField()
|
||||
/// \param[out] value The \a value parameter passed to SetField()
|
||||
void GetField(unsigned int index, RakNet::RakString &columnName, RakNet::RakString &value);
|
||||
|
||||
/// Set all parameters at once from a table
|
||||
/// \param[in] table A table containing the values you want to send. Note that all values are stored as strings in PHP
|
||||
void SetFields(DataStructures::Table *table);
|
||||
|
||||
/// Clear all fields
|
||||
void ClearFields(void);
|
||||
|
||||
/// Upload the values set with SetFields() or SetField()
|
||||
/// On success:
|
||||
/// 1. HTTPConnection::HasRead() will return true.
|
||||
/// 2. Pass the value returned by HTTPConnection::Read() to PHPDirectoryServer2::ProcessHTTPRead().
|
||||
/// 3. The return value of PHPDirectoryServer2::ProcessHTTPRead() will be HTTP_RESULT_EMPTY
|
||||
/// \param[in] uploadPassword The upload password set in the PHP page itself when you first uploaded and viewed it in the webpage.
|
||||
/// \param[in] gameName Every entry must have a game name. Pass it here.
|
||||
/// \param[in] gamePort Every entry must have a game port. Pass it here. The IP address will be stored automatically, or you can manually set it by passing a field named _System_Address
|
||||
/// \param[in] autoRepost Tables must be uploaded every 60 seconds or they get dropped. Set autoRepost to true to automatically reupload the most recent table.
|
||||
void UploadTable(RakNet::RakString uploadPassword, RakNet::RakString gameName, unsigned short gamePort, bool autoRepost);
|
||||
|
||||
/// Send a download request to the PHP server.
|
||||
/// On success:
|
||||
/// 1. HTTPConnection::HasRead() will return true.
|
||||
/// 2. Pass the value returned by HTTPConnection::Read() to PHPDirectoryServer2::ProcessHTTPRead().
|
||||
/// 3. The return value of PHPDirectoryServer2::ProcessHTTPRead() will be HTTP_RESULT_GOT_TABLE or HTTP_RESULT_EMPTY
|
||||
/// 4. On HTTP_RESULT_GOT_TABLE, use GetLastDownloadedTable() to read the results.
|
||||
/// \param[in] downloadPassword The download password set in the PHP page itself when you first uploaded and viewed it in the webpage.
|
||||
void DownloadTable(RakNet::RakString downloadPassword);
|
||||
|
||||
/// Same as calling DownloadTable immediately followed by UploadTable, except only the download result is returned
|
||||
/// \param[in] uploadPassword The upload password set in the PHP page itself when you first uploaded and viewed it in the webpage.
|
||||
/// \param[in] downloadPassword The download password set in the PHP page itself when you first uploaded and viewed it in the webpage.
|
||||
/// \param[in] gameName Every entry must have a game name. Pass it here.
|
||||
/// \param[in] gamePort Every entry must have a game port. Pass it here. The IP address will be stored automatically, or you can manually set it by passing a field named _System_Address
|
||||
/// \param[in] autoRepost Tables must be uploaded every 60 seconds or they get dropped. Set autoRepost to true to automatically reupload the most recent table.
|
||||
void UploadAndDownloadTable(RakNet::RakString uploadPassword, RakNet::RakString downloadPassword, RakNet::RakString gameName, unsigned short gamePort, bool autoRepost);
|
||||
|
||||
/// When HTTPConnection::ProcessDataPacket() returns true, and not an error, pass HTTPConnection::Read() to this function
|
||||
/// The message will be parsed into DataStructures::Table, and a copy stored internally which can be retrieved by GetLastDownloadedTable();
|
||||
/// \param[in] packetData Returned from HTTPInterface::Read()
|
||||
/// \return One of the values for HTTPReadResult
|
||||
HTTPReadResult ProcessHTTPRead(RakNet::RakString httpRead);
|
||||
|
||||
/// Returns the last value returned from ProcessHTTPString
|
||||
/// Default columns are "__GAME_NAME", "__GAME_PORT", "_System_Address"
|
||||
/// \return The table created by parsing httpString
|
||||
const DataStructures::Table *GetLastDownloadedTable(void) const;
|
||||
|
||||
/// Call this periodically - it will handle connection states and refreshing updates to the server
|
||||
void Update(void);
|
||||
|
||||
private:
|
||||
HTTPConnection *http;
|
||||
RakNet::RakString pathToPHP;
|
||||
|
||||
RakNet::RakString gameNameParam;
|
||||
unsigned short gamePortParam;
|
||||
|
||||
void SendOperation(void);
|
||||
void PushColumnsAndValues(DataStructures::List<RakNet::RakString> &columns, DataStructures::List<RakNet::RakString> &values);
|
||||
|
||||
DataStructures::Table lastDownloadedTable;
|
||||
DataStructures::Map<RakNet::RakString, RakNet::RakString> fields;
|
||||
RakNet::RakString currentOperation;
|
||||
RakNet::TimeMS nextRepost;
|
||||
|
||||
};
|
||||
|
||||
} // namespace RakNet
|
||||
|
||||
#endif
|
||||
|
||||
212
src/network/Packet.cpp
Executable file
212
src/network/Packet.cpp
Executable file
@@ -0,0 +1,212 @@
|
||||
|
||||
#include "Packet.h"
|
||||
#include "../world/level/chunk/LevelChunk.h"
|
||||
|
||||
#include "packet/PacketInclude.h"
|
||||
|
||||
Packet::Packet()
|
||||
: priority(HIGH_PRIORITY),
|
||||
reliability(RELIABLE)
|
||||
{}
|
||||
|
||||
Packet* MinecraftPackets::createPacket(int id)
|
||||
{
|
||||
Packet* packet = NULL;
|
||||
|
||||
switch (id - ID_USER_PACKET_ENUM) {
|
||||
default:
|
||||
break;
|
||||
|
||||
case PACKET_LOGIN:
|
||||
packet = new LoginPacket();
|
||||
break;
|
||||
case PACKET_LOGINSTATUS:
|
||||
packet = new LoginStatusPacket();
|
||||
break;
|
||||
case PACKET_READY:
|
||||
packet = new ReadyPacket();
|
||||
break;
|
||||
case PACKET_SETTIME:
|
||||
packet = new SetTimePacket();
|
||||
break;
|
||||
case PACKET_MESSAGE:
|
||||
packet = new MessagePacket();
|
||||
break;
|
||||
case PACKET_STARTGAME:
|
||||
packet = new StartGamePacket();
|
||||
break;
|
||||
case PACKET_ADDENTITY:
|
||||
packet = new AddEntityPacket();
|
||||
break;
|
||||
case PACKET_ADDITEMENTITY:
|
||||
packet = new AddItemEntityPacket();
|
||||
break;
|
||||
case PACKET_TAKEITEMENTITY:
|
||||
packet = new TakeItemEntityPacket();
|
||||
break;
|
||||
case PACKET_ADDMOB:
|
||||
packet = new AddMobPacket();
|
||||
break;
|
||||
case PACKET_ADDPLAYER:
|
||||
packet = new AddPlayerPacket();
|
||||
break;
|
||||
case PACKET_REMOVEPLAYER:
|
||||
packet = new RemovePlayerPacket();
|
||||
break;
|
||||
case PACKET_MOVEENTITY:
|
||||
packet = new MoveEntityPacket();
|
||||
break;
|
||||
case PACKET_MOVEENTITY_POSROT:
|
||||
packet = new MoveEntityPacket_PosRot();
|
||||
break;
|
||||
//case PACKET_TELEPORTENTITY:
|
||||
// packet = new TeleportEntityPacket();
|
||||
// break;
|
||||
case PACKET_MOVEPLAYER:
|
||||
packet = new MovePlayerPacket();
|
||||
break;
|
||||
case PACKET_RESPAWN:
|
||||
packet = new RespawnPacket();
|
||||
break;
|
||||
case PACKET_REMOVEENTITY:
|
||||
packet = new RemoveEntityPacket();
|
||||
break;
|
||||
case PACKET_PLACEBLOCK:
|
||||
packet = new PlaceBlockPacket();
|
||||
break;
|
||||
case PACKET_REMOVEBLOCK:
|
||||
packet = new RemoveBlockPacket();
|
||||
break;
|
||||
case PACKET_UPDATEBLOCK:
|
||||
packet = new UpdateBlockPacket();
|
||||
break;
|
||||
case PACKET_EXPLODE:
|
||||
packet = new ExplodePacket();
|
||||
break;
|
||||
case PACKET_LEVELEVENT:
|
||||
packet = new LevelEventPacket();
|
||||
break;
|
||||
case PACKET_TILEEVENT:
|
||||
packet = new TileEventPacket();
|
||||
break;
|
||||
case PACKET_ENTITYEVENT:
|
||||
packet = new EntityEventPacket();
|
||||
break;
|
||||
case PACKET_REQUESTCHUNK:
|
||||
packet = new RequestChunkPacket();
|
||||
break;
|
||||
case PACKET_CHUNKDATA:
|
||||
packet = new ChunkDataPacket();
|
||||
break;
|
||||
case PACKET_PLAYEREQUIPMENT:
|
||||
packet = new PlayerEquipmentPacket();
|
||||
break;
|
||||
case PACKET_PLAYERARMOREQUIPMENT:
|
||||
packet = new PlayerArmorEquipmentPacket();
|
||||
break;
|
||||
case PACKET_INTERACT:
|
||||
packet = new InteractPacket();
|
||||
break;
|
||||
case PACKET_USEITEM:
|
||||
packet = new UseItemPacket();
|
||||
break;
|
||||
case PACKET_PLAYERACTION:
|
||||
packet = new PlayerActionPacket();
|
||||
break;
|
||||
case PACKET_HURTARMOR:
|
||||
packet = new HurtArmorPacket();
|
||||
break;
|
||||
case PACKET_SETENTITYDATA:
|
||||
packet = new SetEntityDataPacket();
|
||||
break;
|
||||
case PACKET_SETENTITYMOTION:
|
||||
packet = new SetEntityMotionPacket();
|
||||
break;
|
||||
case PACKET_SETHEALTH:
|
||||
packet = new SetHealthPacket();
|
||||
break;
|
||||
case PACKET_SETSPAWNPOSITION:
|
||||
packet = new SetSpawnPositionPacket();
|
||||
break;
|
||||
case PACKET_ANIMATE:
|
||||
packet = new AnimatePacket();
|
||||
break;
|
||||
case PACKET_SENDINVENTORY:
|
||||
packet = new SendInventoryPacket();
|
||||
break;
|
||||
case PACKET_DROPITEM:
|
||||
packet = new DropItemPacket();
|
||||
break;
|
||||
case PACKET_CONTAINERACK:
|
||||
packet = new ContainerAckPacket();
|
||||
break;
|
||||
case PACKET_CONTAINEROPEN:
|
||||
packet = new ContainerOpenPacket();
|
||||
break;
|
||||
case PACKET_CONTAINERCLOSE:
|
||||
packet = new ContainerClosePacket();
|
||||
break;
|
||||
case PACKET_CONTAINERSETDATA:
|
||||
packet = new ContainerSetDataPacket();
|
||||
break;
|
||||
case PACKET_CONTAINERSETSLOT:
|
||||
packet = new ContainerSetSlotPacket();
|
||||
break;
|
||||
case PACKET_CONTAINERSETCONTENT:
|
||||
packet = new ContainerSetContentPacket();
|
||||
break;
|
||||
case PACKET_CHAT:
|
||||
packet = new ChatPacket();
|
||||
break;
|
||||
case PACKET_SIGNUPDATE:
|
||||
packet = new SignUpdatePacket();
|
||||
break;
|
||||
case PACKET_ADDPAINTING:
|
||||
packet = new AddPaintingPacket();
|
||||
break;
|
||||
case PACKET_ADVENTURESETTINGS:
|
||||
packet = new AdventureSettingsPacket();
|
||||
break;
|
||||
}
|
||||
|
||||
return packet;
|
||||
}
|
||||
|
||||
|
||||
namespace PacketUtil
|
||||
{
|
||||
signed char Rot_degreesToChar(float rot) {
|
||||
return (signed char)(rot / 360.0f * 256.0f);
|
||||
}
|
||||
float Rot_charToDegrees(signed char rot) {
|
||||
return ((float)rot) / 256.0f * 360.0f;
|
||||
}
|
||||
|
||||
void Rot_entityToChar(const Entity* e, signed char& yRot, signed char& xRot) {
|
||||
xRot = Rot_degreesToChar(e->xRot);
|
||||
yRot = Rot_degreesToChar(e->yRot);
|
||||
}
|
||||
|
||||
void Rot_charToEntity(Entity* e, signed char yRot, signed char xRot) {
|
||||
e->xRot = e->xRotO = Rot_charToDegrees(xRot);
|
||||
e->yRot = e->yRotO = Rot_charToDegrees(yRot);
|
||||
}
|
||||
|
||||
void writeItemInstance(const ItemInstance& item, RakNet::BitStream* stream) {
|
||||
short id = item.id;
|
||||
unsigned char count = item.count;
|
||||
short aux = item.getAuxValue();
|
||||
stream->Write(id);
|
||||
stream->Write(count);
|
||||
stream->Write(aux);
|
||||
}
|
||||
|
||||
ItemInstance readItemInstance(RakNet::BitStream* stream) {
|
||||
short id, aux;
|
||||
unsigned char count;
|
||||
stream->Read(id);
|
||||
stream->Read(count);
|
||||
stream->Read(aux);
|
||||
return ItemInstance(id, count, aux);
|
||||
}
|
||||
}
|
||||
173
src/network/Packet.h
Executable file
173
src/network/Packet.h
Executable file
@@ -0,0 +1,173 @@
|
||||
#ifndef _MINECRAFT_NETWORK_PACKET_H_
|
||||
#define _MINECRAFT_NETWORK_PACKET_H_
|
||||
|
||||
#include "NetEventCallback.h"
|
||||
|
||||
#include "../raknet/MessageIdentifiers.h"
|
||||
#include "../raknet/RakNetTypes.h"
|
||||
#include "../raknet/BitStream.h"
|
||||
#include "../raknet/PacketPriority.h"
|
||||
|
||||
class LevelChunk;
|
||||
|
||||
|
||||
enum MinecraftPacketIds
|
||||
{
|
||||
PACKET_KEEPALIVE = 0,
|
||||
|
||||
PACKET_LOGIN,
|
||||
PACKET_LOGINSTATUS,
|
||||
PACKET_READY,
|
||||
|
||||
PACKET_MESSAGE,
|
||||
PACKET_SETTIME,
|
||||
|
||||
PACKET_STARTGAME,
|
||||
|
||||
PACKET_ADDMOB,
|
||||
PACKET_ADDPLAYER,
|
||||
PACKET_REMOVEPLAYER,
|
||||
PACKET_TELEPORTENTITY,
|
||||
|
||||
PACKET_ADDENTITY,
|
||||
PACKET_REMOVEENTITY,
|
||||
PACKET_ADDITEMENTITY,
|
||||
PACKET_TAKEITEMENTITY,
|
||||
|
||||
PACKET_MOVEENTITY,
|
||||
PACKET_MOVEENTITY_POS,
|
||||
PACKET_MOVEENTITY_ROT,
|
||||
PACKET_MOVEENTITY_POSROT,
|
||||
PACKET_MOVEPLAYER,
|
||||
|
||||
PACKET_PLACEBLOCK,
|
||||
PACKET_REMOVEBLOCK,
|
||||
PACKET_UPDATEBLOCK,
|
||||
|
||||
PACKET_ADDPAINTING,
|
||||
|
||||
PACKET_EXPLODE,
|
||||
|
||||
PACKET_LEVELEVENT,
|
||||
PACKET_TILEEVENT,
|
||||
PACKET_ENTITYEVENT,
|
||||
|
||||
PACKET_REQUESTCHUNK,
|
||||
PACKET_CHUNKDATA,
|
||||
|
||||
PACKET_PLAYEREQUIPMENT,
|
||||
PACKET_PLAYERARMOREQUIPMENT,
|
||||
PACKET_INTERACT,
|
||||
PACKET_USEITEM,
|
||||
PACKET_PLAYERACTION,
|
||||
PACKET_UPDATEARMOR,
|
||||
PACKET_HURTARMOR,
|
||||
|
||||
PACKET_SETENTITYDATA,
|
||||
PACKET_SETENTITYMOTION,
|
||||
PACKET_SETHEALTH,
|
||||
PACKET_SETSPAWNPOSITION,
|
||||
|
||||
PACKET_ANIMATE,
|
||||
PACKET_RESPAWN,
|
||||
|
||||
PACKET_SENDINVENTORY,
|
||||
PACKET_DROPITEM,
|
||||
|
||||
PACKET_CONTAINEROPEN,
|
||||
PACKET_CONTAINERCLOSE,
|
||||
PACKET_CONTAINERSETSLOT,
|
||||
PACKET_CONTAINERSETDATA,
|
||||
PACKET_CONTAINERSETCONTENT,
|
||||
PACKET_CONTAINERACK,
|
||||
|
||||
PACKET_CHAT,
|
||||
PACKET_SIGNUPDATE,
|
||||
|
||||
PACKET_ADVENTURESETTINGS,
|
||||
/*
|
||||
PACKET_PRELOGIN,
|
||||
PACKET_CHAT,
|
||||
PACKET_SETEQUIPPEDITEM,
|
||||
PACKET_SETSPAWNPOSITION,
|
||||
|
||||
PACKET_PLAYERACTION,
|
||||
PACKET_SETCARRIEDITEM,
|
||||
PACKET_ENTITYACTIONATPOSITION,
|
||||
PACKET_PLAYERCOMMAND,
|
||||
|
||||
PACKET_ADDENTITY,
|
||||
PACKET_ADDMOB,
|
||||
PACKET_ADDPAINTING,
|
||||
PACKET_PLAYERINPUT,
|
||||
PACKET_SETENTITYMOTION,
|
||||
PACKET_REMOVEENTITY,
|
||||
|
||||
PACKET_MOVEENTITY,
|
||||
PACKET_SETRIDING,
|
||||
PACKET_ENTITYDATA,
|
||||
|
||||
PACKET_CHUNKVISIBILITY,
|
||||
PACKET_BLOCKREGIONUPDATE,
|
||||
PACKET_CHUNKBLOCKUPDATE,
|
||||
PACKET_BLOCKUPDATE,
|
||||
PACKET_BLOCKEVENT,
|
||||
|
||||
PACKET_GAMEEVENT,
|
||||
PACKET_ADDGLOBALENTITY,
|
||||
|
||||
PACKET_CONTAINEROPEN,
|
||||
PACKET_CONTAINERCLOSE,
|
||||
PACKET_CONTAINERCLICK,
|
||||
PACKET_CONTAINERSETSLOT,
|
||||
PACKET_CONTAINERSETCONTENT,
|
||||
PACKET_CONTAINERSETDATA,
|
||||
PACKET_CONTAINERACK,
|
||||
|
||||
PACKET_SIGNUPDATE,
|
||||
PACKET_AWARDSTAT,
|
||||
|
||||
PACKET_DISCONNECT,
|
||||
*/
|
||||
|
||||
PACKET_END_ID
|
||||
};
|
||||
|
||||
|
||||
const int NUM_PACKETS = PACKET_END_ID;
|
||||
|
||||
class Packet
|
||||
{
|
||||
public:
|
||||
Packet();
|
||||
virtual ~Packet() {}
|
||||
|
||||
virtual void write(RakNet::BitStream* bitStream) = 0;
|
||||
virtual void read(RakNet::BitStream* bitStream) = 0;
|
||||
|
||||
virtual void handle(const RakNet::RakNetGUID& source, NetEventCallback* callback) = 0;
|
||||
|
||||
PacketPriority priority;
|
||||
PacketReliability reliability;
|
||||
};
|
||||
|
||||
|
||||
class MinecraftPackets
|
||||
{
|
||||
public:
|
||||
|
||||
static Packet* createPacket(int id);
|
||||
|
||||
};
|
||||
|
||||
namespace PacketUtil {
|
||||
signed char Rot_degreesToChar(float rot);
|
||||
float Rot_charToDegrees(signed char rot);
|
||||
void Rot_entityToChar(const Entity* e, signed char& yRot, signed char& xRot);
|
||||
void Rot_charToEntity(Entity* e, signed char yRot, signed char xRot);
|
||||
|
||||
void writeItemInstance(const ItemInstance& item, RakNet::BitStream* stream);
|
||||
ItemInstance readItemInstance(RakNet::BitStream* stream);
|
||||
}
|
||||
|
||||
#endif
|
||||
740
src/network/RakNetInstance.cpp
Executable file
740
src/network/RakNetInstance.cpp
Executable file
@@ -0,0 +1,740 @@
|
||||
#include "RakNetInstance.h"
|
||||
#include "Packet.h"
|
||||
#include "NetEventCallback.h"
|
||||
#include "../raknet/RakPeerInterface.h"
|
||||
#include "../raknet/BitStream.h"
|
||||
#include "../raknet/MessageIdentifiers.h"
|
||||
#include "../raknet/GetTime.h"
|
||||
#include "../AppConstants.h"
|
||||
|
||||
#include "../platform/log.h"
|
||||
|
||||
#define APP_IDENTIFIER "MCCPP;" APP_VERSION_STRING ";"
|
||||
#define APP_IDENTIFIER_MINECON "MCCPP;MINECON;"
|
||||
|
||||
RakNetInstance::RakNetInstance()
|
||||
: rakPeer(NULL),
|
||||
_isServer(false),
|
||||
_isLoggedIn(false)
|
||||
{
|
||||
rakPeer = RakNet::RakPeerInterface::GetInstance();
|
||||
rakPeer->SetTimeoutTime(20000, RakNet::UNASSIGNED_SYSTEM_ADDRESS);
|
||||
rakPeer->SetOccasionalPing(true);
|
||||
}
|
||||
|
||||
RakNetInstance::~RakNetInstance()
|
||||
{
|
||||
if (rakPeer)
|
||||
{
|
||||
rakPeer->Shutdown(100, 0);
|
||||
RakNet::RakPeerInterface::DestroyInstance(rakPeer);
|
||||
rakPeer = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
bool RakNetInstance::host(const std::string& localName, int port, int maxConnections /* = 4 */)
|
||||
{
|
||||
if (rakPeer->IsActive())
|
||||
{
|
||||
rakPeer->Shutdown(500);
|
||||
}
|
||||
|
||||
RakNet::SocketDescriptor socket(port, 0);
|
||||
socket.socketFamily = AF_INET;
|
||||
|
||||
rakPeer->SetMaximumIncomingConnections(maxConnections);
|
||||
RakNet::StartupResult result = rakPeer->Startup(maxConnections, &socket, 1);
|
||||
|
||||
_isServer = true;
|
||||
isPingingForServers = false;
|
||||
|
||||
return (result == RakNet::RAKNET_STARTED);
|
||||
}
|
||||
|
||||
void RakNetInstance::announceServer(const std::string& localName)
|
||||
{
|
||||
if (_isServer && rakPeer->IsActive())
|
||||
{
|
||||
RakNet::RakString connectionData;
|
||||
|
||||
#if defined(MINECON)
|
||||
connectionData += APP_IDENTIFIER_MINECON;
|
||||
#else
|
||||
connectionData += APP_IDENTIFIER;
|
||||
#endif
|
||||
connectionData += localName.c_str();
|
||||
|
||||
RakNet::BitStream bitStream;
|
||||
bitStream.Write(connectionData);
|
||||
rakPeer->SetOfflinePingResponse((const char*)bitStream.GetData(), bitStream.GetNumberOfBytesUsed());
|
||||
}
|
||||
}
|
||||
|
||||
bool RakNetInstance::connect(const char* host, int port)
|
||||
{
|
||||
_isLoggedIn = false;
|
||||
RakNet::StartupResult result;
|
||||
|
||||
RakNet::SocketDescriptor socket(0, 0);
|
||||
socket.socketFamily = AF_INET;
|
||||
|
||||
if (rakPeer->IsActive())
|
||||
{
|
||||
rakPeer->Shutdown(500);
|
||||
}
|
||||
|
||||
result = rakPeer->Startup(4, &socket, 1);
|
||||
|
||||
_isServer = false;
|
||||
isPingingForServers = false;
|
||||
|
||||
if (result == RakNet::RAKNET_STARTED)
|
||||
{
|
||||
RakNet::ConnectionAttemptResult connectResult = rakPeer->Connect(host, port, NULL, 0, NULL, 0, 12, 500, 0);
|
||||
|
||||
return (connectResult == RakNet::CONNECTION_ATTEMPT_STARTED);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void RakNetInstance::disconnect()
|
||||
{
|
||||
if (rakPeer->IsActive())
|
||||
{
|
||||
rakPeer->Shutdown(500);
|
||||
}
|
||||
_isLoggedIn = false;
|
||||
_isServer = false;
|
||||
isPingingForServers = false;
|
||||
}
|
||||
|
||||
void RakNetInstance::pingForHosts(int basePort)
|
||||
{
|
||||
if (!rakPeer->IsActive())
|
||||
{
|
||||
RakNet::SocketDescriptor socket(0, 0);
|
||||
rakPeer->Startup(4, &socket, 1);
|
||||
}
|
||||
|
||||
isPingingForServers = true;
|
||||
pingPort = basePort;
|
||||
lastPingTime = RakNet::GetTimeMS();
|
||||
|
||||
for (int i = 0; i < 4; ++i)
|
||||
rakPeer->Ping("255.255.255.255", basePort + i, true);
|
||||
}
|
||||
|
||||
void RakNetInstance::stopPingForHosts()
|
||||
{
|
||||
if (isPingingForServers)
|
||||
{
|
||||
rakPeer->Shutdown(0);
|
||||
isPingingForServers = false;
|
||||
}
|
||||
}
|
||||
|
||||
const ServerList& RakNetInstance::getServerList()
|
||||
{
|
||||
return availableServers;
|
||||
}
|
||||
|
||||
void RakNetInstance::clearServerList()
|
||||
{
|
||||
availableServers.clear();
|
||||
/*
|
||||
for (int i = 0; i < 20; ++i) {
|
||||
PingedCompatibleServer ps;
|
||||
ps.isSpecial = false;
|
||||
ps.name = "Fake-Real";
|
||||
ps.address.FromString("192.168.1.236|19132");
|
||||
availableServers.push_back(ps);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
RakNet::RakPeerInterface* RakNetInstance::getPeer()
|
||||
{
|
||||
return rakPeer;
|
||||
}
|
||||
|
||||
bool RakNetInstance::isProbablyBroken() {
|
||||
return rakPeer->errorState < -100;
|
||||
}
|
||||
void RakNetInstance::resetIsBroken() {
|
||||
rakPeer->errorState = 0;
|
||||
}
|
||||
|
||||
bool RakNetInstance::isMyLocalGuid(const RakNet::RakNetGUID& guid)
|
||||
{
|
||||
return rakPeer->IsActive() && rakPeer->GetMyGUID() == guid;
|
||||
}
|
||||
|
||||
void RakNetInstance::runEvents(NetEventCallback* callback)
|
||||
{
|
||||
RakNet::Packet* currentEvent;
|
||||
|
||||
while ((currentEvent = rakPeer->Receive()) != NULL)
|
||||
{
|
||||
int packetId = currentEvent->data[0];
|
||||
int length = currentEvent->length;
|
||||
|
||||
RakNet::BitStream activeBitStream(currentEvent->data + 1, length - 1, false);
|
||||
|
||||
if (callback) {
|
||||
if (packetId < ID_USER_PACKET_ENUM)
|
||||
{
|
||||
//LOGI("Received event: %s\n", getPacketName(packetId));
|
||||
switch (packetId)
|
||||
{
|
||||
case ID_NEW_INCOMING_CONNECTION:
|
||||
callback->onNewClient(currentEvent->guid);
|
||||
break;
|
||||
case ID_CONNECTION_REQUEST_ACCEPTED:
|
||||
serverGuid = currentEvent->guid;
|
||||
callback->onConnect(currentEvent->guid);
|
||||
break;
|
||||
case ID_CONNECTION_ATTEMPT_FAILED:
|
||||
callback->onUnableToConnect();
|
||||
break;
|
||||
case ID_DISCONNECTION_NOTIFICATION:
|
||||
case ID_CONNECTION_LOST:
|
||||
callback->onDisconnect(currentEvent->guid);
|
||||
break;
|
||||
case ID_UNCONNECTED_PONG:
|
||||
{
|
||||
RakNet::TimeMS time;
|
||||
RakNet::RakString data;
|
||||
activeBitStream.Read(time);
|
||||
activeBitStream.Read(data);
|
||||
|
||||
int index = handleUnconnectedPong(data, currentEvent, APP_IDENTIFIER, false);
|
||||
if (index < 0) {
|
||||
// Check if it's an official Mojang MineCon server
|
||||
index = handleUnconnectedPong(data, currentEvent, APP_IDENTIFIER_MINECON, true);
|
||||
if (index >= 0) availableServers[index].isSpecial = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int userPacketId = packetId - ID_USER_PACKET_ENUM;
|
||||
bool isStatusPacket = userPacketId <= PACKET_READY;
|
||||
|
||||
if (isStatusPacket || _isServer || _isLoggedIn) {
|
||||
|
||||
if (Packet* packet = MinecraftPackets::createPacket(packetId)) {
|
||||
packet->read(&activeBitStream);
|
||||
packet->handle(currentEvent->guid, callback);
|
||||
delete packet;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rakPeer->DeallocatePacket(currentEvent);
|
||||
//delete activeBitStream;
|
||||
}
|
||||
|
||||
if (isPingingForServers)
|
||||
{
|
||||
if (RakNet::GetTimeMS() - lastPingTime > 1000)
|
||||
{
|
||||
// remove servers that hasn't responded for a while
|
||||
ServerList::iterator it = availableServers.begin();
|
||||
for (; it != availableServers.end(); )
|
||||
{
|
||||
if (RakNet::GetTimeMS() - it->pingTime > 3000)
|
||||
{
|
||||
it = availableServers.erase(it);
|
||||
}
|
||||
else
|
||||
{
|
||||
++it;
|
||||
}
|
||||
}
|
||||
|
||||
pingForHosts(pingPort);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void RakNetInstance::send(Packet& packet) {
|
||||
RakNet::BitStream bitStream;
|
||||
packet.write(&bitStream);
|
||||
if (_isServer)
|
||||
{
|
||||
// broadcast to all connected clients
|
||||
rakPeer->Send(&bitStream, packet.priority, packet.reliability, 0, RakNet::UNASSIGNED_SYSTEM_ADDRESS, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
// send to server
|
||||
rakPeer->Send(&bitStream, packet.priority, packet.reliability, 0, serverGuid, false);
|
||||
}
|
||||
}
|
||||
|
||||
void RakNetInstance::send(const RakNet::RakNetGUID& guid, Packet& packet) {
|
||||
RakNet::BitStream bitStream;
|
||||
packet.write(&bitStream);
|
||||
rakPeer->Send(&bitStream, packet.priority, packet.reliability, 0, guid, false);
|
||||
}
|
||||
|
||||
|
||||
void RakNetInstance::send(Packet* packet)
|
||||
{
|
||||
send(*packet);
|
||||
delete packet;
|
||||
}
|
||||
|
||||
void RakNetInstance::send(const RakNet::RakNetGUID& guid, Packet* packet)
|
||||
{
|
||||
send(guid, *packet);
|
||||
delete packet;
|
||||
}
|
||||
|
||||
#ifdef _DEBUG
|
||||
const char* RakNetInstance::getPacketName(int packetId)
|
||||
{
|
||||
|
||||
switch (packetId)
|
||||
{
|
||||
case ID_CONNECTED_PING:
|
||||
return "ID_CONNECTED_PING";
|
||||
|
||||
case ID_UNCONNECTED_PING:
|
||||
return "ID_UNCONNECTED_PING";
|
||||
|
||||
case ID_UNCONNECTED_PING_OPEN_CONNECTIONS:
|
||||
return "ID_UNCONNECTED_PING_OPEN_CONNECTIONS";
|
||||
|
||||
case ID_CONNECTED_PONG:
|
||||
return "ID_CONNECTED_PONG";
|
||||
|
||||
case ID_DETECT_LOST_CONNECTIONS:
|
||||
return "ID_DETECT_LOST_CONNECTIONS";
|
||||
|
||||
case ID_OPEN_CONNECTION_REQUEST_1:
|
||||
return "ID_OPEN_CONNECTION_REQUEST_1";
|
||||
|
||||
case ID_OPEN_CONNECTION_REPLY_1:
|
||||
return "ID_OPEN_CONNECTION_REPLY_1";
|
||||
|
||||
case ID_OPEN_CONNECTION_REQUEST_2:
|
||||
return "ID_OPEN_CONNECTION_REQUEST_2";
|
||||
|
||||
case ID_OPEN_CONNECTION_REPLY_2:
|
||||
return "ID_OPEN_CONNECTION_REPLY_2";
|
||||
|
||||
case ID_CONNECTION_REQUEST:
|
||||
return "ID_CONNECTION_REQUEST";
|
||||
|
||||
case ID_REMOTE_SYSTEM_REQUIRES_PUBLIC_KEY:
|
||||
return "ID_REMOTE_SYSTEM_REQUIRES_PUBLIC_KEY";
|
||||
|
||||
case ID_OUR_SYSTEM_REQUIRES_SECURITY:
|
||||
return "ID_OUR_SYSTEM_REQUIRES_SECURITY";
|
||||
|
||||
case ID_PUBLIC_KEY_MISMATCH:
|
||||
return "ID_PUBLIC_KEY_MISMATCH";
|
||||
|
||||
case ID_OUT_OF_BAND_INTERNAL:
|
||||
return "ID_OUT_OF_BAND_INTERNAL";
|
||||
|
||||
case ID_SND_RECEIPT_ACKED:
|
||||
return "ID_SND_RECEIPT_ACKED";
|
||||
|
||||
case ID_SND_RECEIPT_LOSS:
|
||||
return "ID_SND_RECEIPT_LOSS";
|
||||
|
||||
case ID_CONNECTION_REQUEST_ACCEPTED:
|
||||
return "ID_CONNECTION_REQUEST_ACCEPTED";
|
||||
|
||||
case ID_CONNECTION_ATTEMPT_FAILED:
|
||||
return "ID_CONNECTION_ATTEMPT_FAILED";
|
||||
|
||||
case ID_ALREADY_CONNECTED:
|
||||
return "ID_ALREADY_CONNECTED";
|
||||
|
||||
case ID_NEW_INCOMING_CONNECTION:
|
||||
return "ID_NEW_INCOMING_CONNECTION";
|
||||
|
||||
case ID_NO_FREE_INCOMING_CONNECTIONS:
|
||||
return "ID_NO_FREE_INCOMING_CONNECTIONS";
|
||||
|
||||
case ID_DISCONNECTION_NOTIFICATION:
|
||||
return "ID_DISCONNECTION_NOTIFICATION";
|
||||
|
||||
case ID_CONNECTION_LOST:
|
||||
return "ID_CONNECTION_LOST";
|
||||
|
||||
case ID_CONNECTION_BANNED:
|
||||
return "ID_CONNECTION_BANNED";
|
||||
|
||||
case ID_INVALID_PASSWORD:
|
||||
return "ID_INVALID_PASSWORD";
|
||||
|
||||
case ID_INCOMPATIBLE_PROTOCOL_VERSION:
|
||||
return "ID_INCOMPATIBLE_PROTOCOL_VERSION";
|
||||
|
||||
case ID_IP_RECENTLY_CONNECTED:
|
||||
return "ID_IP_RECENTLY_CONNECTED";
|
||||
|
||||
case ID_TIMESTAMP:
|
||||
return "ID_TIMESTAMP";
|
||||
|
||||
case ID_UNCONNECTED_PONG:
|
||||
return "ID_UNCONNECTED_PONG";
|
||||
|
||||
case ID_ADVERTISE_SYSTEM:
|
||||
return "ID_ADVERTISE_SYSTEM";
|
||||
|
||||
case ID_DOWNLOAD_PROGRESS:
|
||||
return "ID_DOWNLOAD_PROGRESS";
|
||||
|
||||
case ID_REMOTE_DISCONNECTION_NOTIFICATION:
|
||||
return "ID_REMOTE_DISCONNECTION_NOTIFICATION";
|
||||
|
||||
case ID_REMOTE_CONNECTION_LOST:
|
||||
return "ID_REMOTE_CONNECTION_LOST";
|
||||
|
||||
case ID_REMOTE_NEW_INCOMING_CONNECTION:
|
||||
return "ID_REMOTE_NEW_INCOMING_CONNECTION";
|
||||
|
||||
case ID_FILE_LIST_TRANSFER_HEADER:
|
||||
return "ID_FILE_LIST_TRANSFER_HEADER";
|
||||
|
||||
case ID_FILE_LIST_TRANSFER_FILE:
|
||||
return "ID_FILE_LIST_TRANSFER_FILE";
|
||||
|
||||
case ID_FILE_LIST_REFERENCE_PUSH_ACK:
|
||||
return "ID_FILE_LIST_REFERENCE_PUSH_ACK";
|
||||
|
||||
case ID_DDT_DOWNLOAD_REQUEST:
|
||||
return "ID_DDT_DOWNLOAD_REQUEST";
|
||||
|
||||
case ID_TRANSPORT_STRING:
|
||||
return "ID_TRANSPORT_STRING";
|
||||
|
||||
case ID_REPLICA_MANAGER_CONSTRUCTION:
|
||||
return "ID_REPLICA_MANAGER_CONSTRUCTION";
|
||||
|
||||
case ID_REPLICA_MANAGER_SCOPE_CHANGE:
|
||||
return "ID_REPLICA_MANAGER_SCOPE_CHANGE";
|
||||
|
||||
case ID_REPLICA_MANAGER_SERIALIZE:
|
||||
return "ID_REPLICA_MANAGER_SERIALIZE";
|
||||
|
||||
case ID_REPLICA_MANAGER_DOWNLOAD_STARTED:
|
||||
return "ID_REPLICA_MANAGER_DOWNLOAD_STARTED";
|
||||
|
||||
case ID_REPLICA_MANAGER_DOWNLOAD_COMPLETE:
|
||||
return "ID_REPLICA_MANAGER_DOWNLOAD_COMPLETE";
|
||||
|
||||
case ID_RAKVOICE_OPEN_CHANNEL_REQUEST:
|
||||
return "ID_RAKVOICE_OPEN_CHANNEL_REQUEST";
|
||||
|
||||
case ID_RAKVOICE_OPEN_CHANNEL_REPLY:
|
||||
return "ID_RAKVOICE_OPEN_CHANNEL_REPLY";
|
||||
|
||||
case ID_RAKVOICE_CLOSE_CHANNEL:
|
||||
return "ID_RAKVOICE_CLOSE_CHANNEL";
|
||||
|
||||
case ID_RAKVOICE_DATA:
|
||||
return "ID_RAKVOICE_DATA";
|
||||
|
||||
case ID_AUTOPATCHER_GET_CHANGELIST_SINCE_DATE:
|
||||
return "ID_AUTOPATCHER_GET_CHANGELIST_SINCE_DATE";
|
||||
|
||||
case ID_AUTOPATCHER_CREATION_LIST:
|
||||
return "ID_AUTOPATCHER_CREATION_LIST";
|
||||
|
||||
case ID_AUTOPATCHER_DELETION_LIST:
|
||||
return "ID_AUTOPATCHER_DELETION_LIST";
|
||||
|
||||
case ID_AUTOPATCHER_GET_PATCH:
|
||||
return "ID_AUTOPATCHER_GET_PATCH";
|
||||
|
||||
case ID_AUTOPATCHER_PATCH_LIST:
|
||||
return "ID_AUTOPATCHER_PATCH_LIST";
|
||||
|
||||
case ID_AUTOPATCHER_REPOSITORY_FATAL_ERROR:
|
||||
return "ID_AUTOPATCHER_REPOSITORY_FATAL_ERROR";
|
||||
|
||||
case ID_AUTOPATCHER_FINISHED_INTERNAL:
|
||||
return "ID_AUTOPATCHER_FINISHED_INTERNAL";
|
||||
|
||||
case ID_AUTOPATCHER_FINISHED:
|
||||
return "ID_AUTOPATCHER_FINISHED";
|
||||
|
||||
case ID_AUTOPATCHER_RESTART_APPLICATION:
|
||||
return "ID_AUTOPATCHER_RESTART_APPLICATION";
|
||||
|
||||
case ID_NAT_PUNCHTHROUGH_REQUEST:
|
||||
return "ID_NAT_PUNCHTHROUGH_REQUEST";
|
||||
|
||||
case ID_NAT_GROUP_PUNCHTHROUGH_REQUEST:
|
||||
return "ID_NAT_GROUP_PUNCHTHROUGH_REQUEST";
|
||||
|
||||
case ID_NAT_GROUP_PUNCHTHROUGH_REPLY:
|
||||
return "ID_NAT_GROUP_PUNCHTHROUGH_REPLY";
|
||||
|
||||
case ID_NAT_CONNECT_AT_TIME:
|
||||
return "ID_NAT_CONNECT_AT_TIME";
|
||||
|
||||
case ID_NAT_GET_MOST_RECENT_PORT:
|
||||
return "ID_NAT_GET_MOST_RECENT_PORT";
|
||||
|
||||
case ID_NAT_CLIENT_READY:
|
||||
return "ID_NAT_CLIENT_READY";
|
||||
|
||||
case ID_NAT_GROUP_PUNCHTHROUGH_FAILURE_NOTIFICATION:
|
||||
return "ID_NAT_GROUP_PUNCHTHROUGH_FAILURE_NOTIFICATION";
|
||||
|
||||
case ID_NAT_TARGET_NOT_CONNECTED:
|
||||
return "ID_NAT_TARGET_NOT_CONNECTED";
|
||||
|
||||
case ID_NAT_TARGET_UNRESPONSIVE:
|
||||
return "ID_NAT_TARGET_UNRESPONSIVE";
|
||||
|
||||
case ID_NAT_CONNECTION_TO_TARGET_LOST:
|
||||
return "ID_NAT_CONNECTION_TO_TARGET_LOST";
|
||||
|
||||
case ID_NAT_ALREADY_IN_PROGRESS:
|
||||
return "ID_NAT_ALREADY_IN_PROGRESS";
|
||||
|
||||
case ID_NAT_PUNCHTHROUGH_FAILED:
|
||||
return "ID_NAT_PUNCHTHROUGH_FAILED";
|
||||
|
||||
case ID_NAT_PUNCHTHROUGH_SUCCEEDED:
|
||||
return "ID_NAT_PUNCHTHROUGH_SUCCEEDED";
|
||||
|
||||
case ID_NAT_GROUP_PUNCH_FAILED:
|
||||
return "ID_NAT_GROUP_PUNCH_FAILED";
|
||||
|
||||
case ID_NAT_GROUP_PUNCH_SUCCEEDED:
|
||||
return "ID_NAT_GROUP_PUNCH_SUCCEEDED";
|
||||
|
||||
case ID_READY_EVENT_SET:
|
||||
return "ID_READY_EVENT_SET";
|
||||
|
||||
case ID_READY_EVENT_UNSET:
|
||||
return "ID_READY_EVENT_UNSET";
|
||||
|
||||
case ID_READY_EVENT_ALL_SET:
|
||||
return "ID_READY_EVENT_ALL_SET";
|
||||
|
||||
case ID_READY_EVENT_QUERY:
|
||||
return "ID_READY_EVENT_QUERY";
|
||||
|
||||
case ID_LOBBY_GENERAL:
|
||||
return "ID_LOBBY_GENERAL";
|
||||
|
||||
case ID_RPC_REMOTE_ERROR:
|
||||
return "ID_RPC_REMOTE_ERROR";
|
||||
|
||||
case ID_RPC_PLUGIN:
|
||||
return "ID_RPC_PLUGIN";
|
||||
|
||||
case ID_FILE_LIST_REFERENCE_PUSH:
|
||||
return "ID_FILE_LIST_REFERENCE_PUSH";
|
||||
|
||||
case ID_READY_EVENT_FORCE_ALL_SET:
|
||||
return "ID_READY_EVENT_FORCE_ALL_SET";
|
||||
|
||||
case ID_ROOMS_EXECUTE_FUNC:
|
||||
return "ID_ROOMS_EXECUTE_FUNC";
|
||||
|
||||
case ID_ROOMS_LOGON_STATUS:
|
||||
return "ID_ROOMS_LOGON_STATUS";
|
||||
|
||||
case ID_ROOMS_HANDLE_CHANGE:
|
||||
return "ID_ROOMS_HANDLE_CHANGE";
|
||||
|
||||
case ID_LOBBY2_SEND_MESSAGE:
|
||||
return "ID_LOBBY2_SEND_MESSAGE";
|
||||
|
||||
case ID_LOBBY2_SERVER_ERROR:
|
||||
return "ID_LOBBY2_SERVER_ERROR";
|
||||
|
||||
case ID_FCM2_NEW_HOST:
|
||||
return "ID_FCM2_NEW_HOST";
|
||||
|
||||
case ID_FCM2_REQUEST_FCMGUID:
|
||||
return "ID_FCM2_REQUEST_FCMGUID";
|
||||
|
||||
case ID_FCM2_RESPOND_CONNECTION_COUNT:
|
||||
return "ID_FCM2_RESPOND_CONNECTION_COUNT";
|
||||
|
||||
case ID_FCM2_INFORM_FCMGUID:
|
||||
return "ID_FCM2_INFORM_FCMGUID";
|
||||
|
||||
case ID_FCM2_UPDATE_MIN_TOTAL_CONNECTION_COUNT:
|
||||
return "ID_FCM2_UPDATE_MIN_TOTAL_CONNECTION_COUNT";
|
||||
|
||||
case ID_UDP_PROXY_GENERAL:
|
||||
return "ID_UDP_PROXY_GENERAL";
|
||||
|
||||
case ID_SQLite3_EXEC:
|
||||
return "ID_SQLite3_EXEC";
|
||||
|
||||
case ID_SQLite3_UNKNOWN_DB:
|
||||
return "ID_SQLite3_UNKNOWN_DB";
|
||||
|
||||
case ID_SQLLITE_LOGGER:
|
||||
return "ID_SQLLITE_LOGGER";
|
||||
|
||||
case ID_NAT_TYPE_DETECTION_REQUEST:
|
||||
return "ID_NAT_TYPE_DETECTION_REQUEST";
|
||||
|
||||
case ID_NAT_TYPE_DETECTION_RESULT:
|
||||
return "ID_NAT_TYPE_DETECTION_RESULT";
|
||||
|
||||
case ID_ROUTER_2_INTERNAL:
|
||||
return "ID_ROUTER_2_INTERNAL";
|
||||
|
||||
case ID_ROUTER_2_FORWARDING_NO_PATH:
|
||||
return "ID_ROUTER_2_FORWARDING_NO_PATH";
|
||||
|
||||
case ID_ROUTER_2_FORWARDING_ESTABLISHED:
|
||||
return "ID_ROUTER_2_FORWARDING_ESTABLISHED";
|
||||
|
||||
case ID_ROUTER_2_REROUTED:
|
||||
return "ID_ROUTER_2_REROUTED";
|
||||
|
||||
case ID_TEAM_BALANCER_INTERNAL:
|
||||
return "ID_TEAM_BALANCER_INTERNAL";
|
||||
|
||||
case ID_TEAM_BALANCER_REQUESTED_TEAM_CHANGE_PENDING:
|
||||
return "ID_TEAM_BALANCER_REQUESTED_TEAM_CHANGE_PENDING";
|
||||
|
||||
case ID_TEAM_BALANCER_TEAMS_LOCKED:
|
||||
return "ID_TEAM_BALANCER_TEAMS_LOCKED";
|
||||
|
||||
case ID_TEAM_BALANCER_TEAM_ASSIGNED:
|
||||
return "ID_TEAM_BALANCER_TEAM_ASSIGNED";
|
||||
|
||||
case ID_LIGHTSPEED_INTEGRATION:
|
||||
return "ID_LIGHTSPEED_INTEGRATION";
|
||||
|
||||
case ID_XBOX_LOBBY:
|
||||
return "ID_XBOX_LOBBY";
|
||||
|
||||
case ID_TWO_WAY_AUTHENTICATION_INCOMING_CHALLENGE_SUCCESS:
|
||||
return "ID_TWO_WAY_AUTHENTICATION_INCOMING_CHALLENGE_SUCCESS";
|
||||
|
||||
case ID_TWO_WAY_AUTHENTICATION_OUTGOING_CHALLENGE_SUCCESS:
|
||||
return "ID_TWO_WAY_AUTHENTICATION_OUTGOING_CHALLENGE_SUCCESS";
|
||||
|
||||
case ID_TWO_WAY_AUTHENTICATION_INCOMING_CHALLENGE_FAILURE:
|
||||
return "ID_TWO_WAY_AUTHENTICATION_INCOMING_CHALLENGE_FAILURE";
|
||||
|
||||
case ID_TWO_WAY_AUTHENTICATION_OUTGOING_CHALLENGE_FAILURE:
|
||||
return "ID_TWO_WAY_AUTHENTICATION_OUTGOING_CHALLENGE_FAILURE";
|
||||
|
||||
case ID_TWO_WAY_AUTHENTICATION_OUTGOING_CHALLENGE_TIMEOUT:
|
||||
return "ID_TWO_WAY_AUTHENTICATION_OUTGOING_CHALLENGE_TIMEOUT";
|
||||
|
||||
case ID_TWO_WAY_AUTHENTICATION_NEGOTIATION:
|
||||
return "ID_TWO_WAY_AUTHENTICATION_NEGOTIATION";
|
||||
|
||||
case ID_CLOUD_POST_REQUEST:
|
||||
return "ID_CLOUD_POST_REQUEST";
|
||||
|
||||
case ID_CLOUD_RELEASE_REQUEST:
|
||||
return "ID_CLOUD_RELEASE_REQUEST";
|
||||
|
||||
case ID_CLOUD_GET_REQUEST:
|
||||
return "ID_CLOUD_GET_REQUEST";
|
||||
|
||||
case ID_CLOUD_GET_RESPONSE:
|
||||
return "ID_CLOUD_GET_RESPONSE";
|
||||
|
||||
case ID_CLOUD_UNSUBSCRIBE_REQUEST:
|
||||
return "ID_CLOUD_UNSUBSCRIBE_REQUEST";
|
||||
|
||||
case ID_CLOUD_SERVER_TO_SERVER_COMMAND:
|
||||
return "ID_CLOUD_SERVER_TO_SERVER_COMMAND";
|
||||
|
||||
case ID_CLOUD_SUBSCRIPTION_NOTIFICATION:
|
||||
return "ID_CLOUD_SUBSCRIPTION_NOTIFICATION";
|
||||
|
||||
case ID_RESERVED_1:
|
||||
return "ID_RESERVED_1";
|
||||
|
||||
case ID_RESERVED_2:
|
||||
return "ID_RESERVED_2";
|
||||
|
||||
case ID_RESERVED_3:
|
||||
return "ID_RESERVED_3";
|
||||
|
||||
case ID_RESERVED_4:
|
||||
return "ID_RESERVED_4";
|
||||
|
||||
case ID_RESERVED_5:
|
||||
return "ID_RESERVED_5";
|
||||
|
||||
case ID_RESERVED_6:
|
||||
return "ID_RESERVED_6";
|
||||
|
||||
case ID_RESERVED_7:
|
||||
return "ID_RESERVED_7";
|
||||
|
||||
case ID_RESERVED_8:
|
||||
return "ID_RESERVED_8";
|
||||
|
||||
case ID_RESERVED_9:
|
||||
return "ID_RESERVED_9";
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return "Unknown or user-defined";
|
||||
}
|
||||
#endif
|
||||
|
||||
int RakNetInstance::handleUnconnectedPong(const RakNet::RakString& data, const RakNet::Packet* p, const char* appid, bool insertAtBeginning)
|
||||
{
|
||||
RakNet::RakString appIdentifier(appid);
|
||||
// This weird code is a result of RakString.Find being pretty useless
|
||||
bool emptyNameOrLonger = data.GetLength() >= appIdentifier.GetLength();
|
||||
|
||||
if ( !emptyNameOrLonger || appIdentifier.StrCmp(data.SubStr(0, appIdentifier.GetLength())) != 0)
|
||||
return -1;
|
||||
|
||||
bool found = false;
|
||||
for (unsigned int i = 0; i < availableServers.size(); i++) {
|
||||
if (availableServers[i].address == p->systemAddress) {
|
||||
availableServers[i].pingTime = RakNet::GetTimeMS();
|
||||
|
||||
bool emptyName = data.GetLength() == appIdentifier.GetLength();
|
||||
if (emptyName)
|
||||
availableServers[i].name = "";
|
||||
else {
|
||||
availableServers[i].name = data.SubStr(appIdentifier.GetLength(), data.GetLength() - appIdentifier.GetLength());
|
||||
}
|
||||
//LOGI("Swapping name: %s\n", availableServers[i].name.C_String());
|
||||
return i;
|
||||
}
|
||||
}
|
||||
PingedCompatibleServer server;
|
||||
server.address = p->systemAddress;
|
||||
server.pingTime = RakNet::GetTimeMS();
|
||||
server.isSpecial = false;
|
||||
server.name = data.SubStr(appIdentifier.GetLength(), data.GetLength() - appIdentifier.GetLength());
|
||||
|
||||
if (insertAtBeginning) {
|
||||
availableServers.insert(availableServers.begin(), server);
|
||||
return 0;
|
||||
} else {
|
||||
availableServers.push_back(server);
|
||||
return availableServers.size() - 1;
|
||||
}
|
||||
}
|
||||
|
||||
void RakNetInstance::setIsLoggedIn( bool status ) {
|
||||
_isLoggedIn = status;
|
||||
}
|
||||
118
src/network/RakNetInstance.h
Executable file
118
src/network/RakNetInstance.h
Executable file
@@ -0,0 +1,118 @@
|
||||
#ifndef _MINECRAFT_NETWORK_RAKNETINSTANCE_H_
|
||||
#define _MINECRAFT_NETWORK_RAKNETINSTANCE_H_
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include "../raknet/RakNetTypes.h"
|
||||
#include "../raknet/RakString.h"
|
||||
|
||||
namespace RakNet
|
||||
{
|
||||
class RakPeerInterface;
|
||||
}
|
||||
|
||||
class Packet;
|
||||
class NetEventCallback;
|
||||
|
||||
typedef struct PingedCompatibleServer
|
||||
{
|
||||
RakNet::RakString name;
|
||||
RakNet::SystemAddress address;
|
||||
RakNet::TimeMS pingTime;
|
||||
bool isSpecial;
|
||||
} PingedCompatibleServer;
|
||||
typedef std::vector<PingedCompatibleServer> ServerList;
|
||||
|
||||
class IRakNetInstance
|
||||
{
|
||||
public:
|
||||
virtual ~IRakNetInstance() {}
|
||||
|
||||
virtual bool host(const std::string& localName, int port, int maxConnections = 4) { return false; }
|
||||
virtual bool connect(const char* host, int port) { return false; }
|
||||
virtual void setIsLoggedIn(bool status) {}
|
||||
|
||||
virtual void pingForHosts(int port) {}
|
||||
virtual void stopPingForHosts() {}
|
||||
virtual const ServerList& getServerList() { static ServerList l; return l; }
|
||||
virtual void clearServerList() {}
|
||||
|
||||
virtual void disconnect() {}
|
||||
|
||||
virtual void announceServer(const std::string& localName) {}
|
||||
|
||||
virtual RakNet::RakPeerInterface* getPeer() { return NULL; }
|
||||
virtual bool isMyLocalGuid(const RakNet::RakNetGUID& guid) { return true; }
|
||||
|
||||
virtual void runEvents(NetEventCallback* callback) {}
|
||||
|
||||
virtual void send(Packet& packet) {}
|
||||
virtual void send(const RakNet::RakNetGUID& guid, Packet& packet) {}
|
||||
|
||||
// @attn: Those delete the packet
|
||||
virtual void send(Packet* packet) {}
|
||||
virtual void send(const RakNet::RakNetGUID& guid, Packet* packet) {}
|
||||
|
||||
virtual bool isServer() { return true; }
|
||||
virtual bool isProbablyBroken() { return false; }
|
||||
virtual void resetIsBroken() {}
|
||||
};
|
||||
|
||||
class RakNetInstance: public IRakNetInstance
|
||||
{
|
||||
public:
|
||||
|
||||
RakNetInstance();
|
||||
virtual ~RakNetInstance();
|
||||
|
||||
bool host(const std::string& localName, int port, int maxConnections = 4);
|
||||
bool connect(const char* host, int port);
|
||||
void setIsLoggedIn(bool status);
|
||||
|
||||
void pingForHosts(int basePort);
|
||||
void stopPingForHosts();
|
||||
const ServerList& getServerList();
|
||||
void clearServerList();
|
||||
|
||||
void disconnect();
|
||||
|
||||
void announceServer(const std::string& localName);
|
||||
|
||||
RakNet::RakPeerInterface* getPeer();
|
||||
bool isMyLocalGuid(const RakNet::RakNetGUID& guid);
|
||||
|
||||
void runEvents(NetEventCallback* callback);
|
||||
|
||||
void send(Packet& packet);
|
||||
void send(const RakNet::RakNetGUID& guid, Packet& packet);
|
||||
|
||||
// @attn: Those delete the packet
|
||||
void send(Packet* packet);
|
||||
void send(const RakNet::RakNetGUID& guid, Packet* packet);
|
||||
|
||||
bool isServer() { return _isServer; }
|
||||
bool isProbablyBroken();
|
||||
void resetIsBroken();
|
||||
|
||||
#ifdef _DEBUG
|
||||
const char* getPacketName(int packetId);
|
||||
#else
|
||||
const char* getPacketName(int packetId) { return ""; }
|
||||
#endif
|
||||
|
||||
private:
|
||||
int handleUnconnectedPong(const RakNet::RakString& data, const RakNet::Packet*, const char* appid, bool insertAtBeginning);
|
||||
|
||||
RakNet::RakPeerInterface* rakPeer;
|
||||
RakNet::RakNetGUID serverGuid;
|
||||
|
||||
ServerList availableServers;
|
||||
bool isPingingForServers;
|
||||
int pingPort;
|
||||
RakNet::TimeMS lastPingTime;
|
||||
|
||||
bool _isServer;
|
||||
bool _isLoggedIn;
|
||||
};
|
||||
|
||||
#endif /*_MINECRAFT_NETWORK_RAKNETINSTANCE_H_*/
|
||||
705
src/network/ServerSideNetworkHandler.cpp
Executable file
705
src/network/ServerSideNetworkHandler.cpp
Executable file
@@ -0,0 +1,705 @@
|
||||
|
||||
#include "ServerSideNetworkHandler.h"
|
||||
#include "../world/level/Level.h"
|
||||
#include "../world/entity/player/Player.h"
|
||||
#include "../world/entity/player/Inventory.h"
|
||||
#include "../world/Container.h"
|
||||
#include "../world/inventory/BaseContainerMenu.h"
|
||||
#include "packet/PacketInclude.h"
|
||||
|
||||
#include "RakNetInstance.h"
|
||||
#include "../client/Minecraft.h"
|
||||
#include "../client/player/LocalPlayer.h"
|
||||
#include "../client/gamemode/GameMode.h"
|
||||
#include "../raknet/RakPeerInterface.h"
|
||||
#include "../raknet/PacketPriority.h"
|
||||
#ifndef STANDALONE_SERVER
|
||||
#include "../client/sound/SoundEngine.h"
|
||||
#endif
|
||||
#include "../server/ServerPlayer.h"
|
||||
#include "../world/entity/item/FallingTile.h"
|
||||
|
||||
#define TIMES(x) for(int itc ## __LINE__ = 0; itc ## __LINE__ < x; ++ itc ## __LINE__)
|
||||
|
||||
ServerSideNetworkHandler::ServerSideNetworkHandler(Minecraft* minecraft, IRakNetInstance* raknetInstance)
|
||||
: minecraft(minecraft),
|
||||
raknetInstance(raknetInstance),
|
||||
level(NULL)
|
||||
{
|
||||
allowIncomingConnections(false);
|
||||
rakPeer = raknetInstance->getPeer();
|
||||
}
|
||||
|
||||
ServerSideNetworkHandler::~ServerSideNetworkHandler()
|
||||
{
|
||||
if (level) {
|
||||
level->removeListener(this);
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < _pendingPlayers.size(); ++i)
|
||||
delete _pendingPlayers[i];
|
||||
}
|
||||
|
||||
void ServerSideNetworkHandler::tileChanged(int x, int y, int z)
|
||||
{
|
||||
//LOGI("tileChanged(%d, %d, %d)\n", x, y, z);
|
||||
|
||||
// broadcast change event
|
||||
UpdateBlockPacket packet(x, y, z, level->getTile(x, y, z), level->getData(x, y, z));
|
||||
RakNet::BitStream bitStream;
|
||||
packet.write(&bitStream);
|
||||
rakPeer->Send(&bitStream, HIGH_PRIORITY, RELIABLE_ORDERED, 0, RakNet::UNASSIGNED_SYSTEM_ADDRESS, true);
|
||||
}
|
||||
|
||||
Packet* ServerSideNetworkHandler::getAddPacketFromEntity( Entity* entity ) {
|
||||
if (entity->isMob() && !entity->isPlayer()) { //@fix: This code is duplicated. See if it can be unified.
|
||||
if (minecraft->player) {
|
||||
// I guess this should always be true, but it crashed somewhere in this
|
||||
// function once and I only see this one as a potential problem
|
||||
return new AddMobPacket((Mob*)entity);
|
||||
}
|
||||
}
|
||||
else if (entity->isPlayer()) {
|
||||
|
||||
} else if (entity->isItemEntity()) {
|
||||
AddItemEntityPacket* packet = new AddItemEntityPacket((ItemEntity*)entity);
|
||||
entity->xd = packet->xa();
|
||||
entity->yd = packet->ya();
|
||||
entity->zd = packet->za();
|
||||
//LOGI("item-entity @ server: %f, %f, %f\n", e->xd, e->yd, e->zd);
|
||||
return packet;
|
||||
} else if(entity->isHangingEntity()) {
|
||||
return new AddPaintingPacket((Painting*) entity);
|
||||
} else {
|
||||
int type = entity->getEntityTypeId();
|
||||
int data = entity->getAuxData();
|
||||
|
||||
if (EntityTypes::IdFallingTile == type) {
|
||||
FallingTile* ft = (FallingTile*) entity;
|
||||
data = -(ft->tile | (ft->data << 16));
|
||||
}
|
||||
|
||||
//LOGI("Server: adding entity with %f, %f, %f\n", e->xd, e->yd, e->zd);
|
||||
AddEntityPacket* packet = new AddEntityPacket(entity, data);
|
||||
/*
|
||||
entity->xd = packet->xd;
|
||||
entity->yd = packet->yd;
|
||||
entity->zd = packet->zd;
|
||||
*/
|
||||
return packet;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
void ServerSideNetworkHandler::entityAdded(Entity* e) {
|
||||
Packet* packet = getAddPacketFromEntity(e);
|
||||
if(packet != NULL) {
|
||||
if (e->isMob() && !e->isPlayer()) {
|
||||
redistributePacket(packet, rakPeer->GetMyGUID());
|
||||
delete packet;
|
||||
} else {
|
||||
raknetInstance->send(packet);
|
||||
// raknetInstance->send always deletes package
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void ServerSideNetworkHandler::entityRemoved(Entity* e)
|
||||
{
|
||||
if (!e->isPlayer()) { //@fix: This code MIGHT be duplicated. See if it can be unified.
|
||||
RemoveEntityPacket packet(e->entityId);
|
||||
redistributePacket(&packet, rakPeer->GetMyGUID());
|
||||
} else { // Is a player
|
||||
RemovePlayerPacket packet((Player*) e);
|
||||
redistributePacket(&packet, rakPeer->GetMyGUID());
|
||||
}
|
||||
}
|
||||
|
||||
void ServerSideNetworkHandler::redistributePacket(Packet* packet, const RakNet::RakNetGUID& fromPlayer)
|
||||
{
|
||||
// broadcast the new player to all other players
|
||||
RakNet::BitStream bitStream;
|
||||
packet->write(&bitStream);
|
||||
rakPeer->Send(&bitStream, packet->priority, packet->reliability, 0, fromPlayer, true);
|
||||
}
|
||||
|
||||
void ServerSideNetworkHandler::displayGameMessage(const std::string& message)
|
||||
{
|
||||
#ifndef STANDALONE_SERVER
|
||||
minecraft->gui.addMessage(message);
|
||||
#else
|
||||
LOGI("%s\n", message.c_str());
|
||||
#endif
|
||||
MessagePacket packet(message.c_str());
|
||||
raknetInstance->send(packet);
|
||||
}
|
||||
|
||||
void ServerSideNetworkHandler::onNewClient(const RakNet::RakNetGUID& clientGuid)
|
||||
{
|
||||
LOGI("onNewClient, client guid: %s\n", clientGuid.ToString());
|
||||
}
|
||||
|
||||
void ServerSideNetworkHandler::onDisconnect(const RakNet::RakNetGUID& guid)
|
||||
{
|
||||
if (!level) return;
|
||||
LOGI("onDisconnect\n");
|
||||
|
||||
const PlayerList& players = level->players;
|
||||
for (unsigned int i = 0; i < players.size(); i++)
|
||||
{
|
||||
Player* player = players[i];
|
||||
|
||||
if (player->owner == guid)
|
||||
{
|
||||
std::string message = player->name;
|
||||
message += " disconnected from the game";
|
||||
displayGameMessage(message);
|
||||
|
||||
//RemoveEntityPacket packet(player->entityId);
|
||||
//raknetInstance->send(packet);
|
||||
player->reallyRemoveIfPlayer = true;
|
||||
level->removeEntity(player);
|
||||
//level->removePlayer(player);
|
||||
|
||||
LOGI("&e@disc: %p", player);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ServerSideNetworkHandler::handle(const RakNet::RakNetGUID& source, LoginPacket* packet)
|
||||
{
|
||||
if (!level) return;
|
||||
if (!_allowIncoming) return;
|
||||
|
||||
LOGI("LoginPacket\n");
|
||||
|
||||
int loginStatus = LoginStatus::Success;
|
||||
//
|
||||
// Bad/incompatible client version
|
||||
//
|
||||
bool oldClient = packet->clientNetworkVersion < SharedConstants::NetworkProtocolLowestSupportedVersion;
|
||||
bool oldServer = packet->clientNetworkLowestSupportedVersion > SharedConstants::NetworkProtocolVersion;
|
||||
if (oldClient || oldServer)
|
||||
loginStatus = oldClient? LoginStatus::Failed_ClientOld : LoginStatus::Failed_ServerOld;
|
||||
|
||||
RakNet::BitStream bitStream;
|
||||
LoginStatusPacket(loginStatus).write(&bitStream);
|
||||
rakPeer->Send(&bitStream, HIGH_PRIORITY, RELIABLE_ORDERED, 0, source, false);
|
||||
|
||||
if (LoginStatus::Success != loginStatus)
|
||||
return;
|
||||
|
||||
//
|
||||
// Valid client version
|
||||
//
|
||||
Player* newPlayer = new ServerPlayer(minecraft, level);
|
||||
|
||||
minecraft->gameMode->initAbilities(newPlayer->abilities);
|
||||
newPlayer->owner = source;
|
||||
newPlayer->name = packet->clientName.C_String();
|
||||
_pendingPlayers.push_back(newPlayer);
|
||||
|
||||
// Reset the player so he doesn't spawn inside blocks
|
||||
while (newPlayer->y > 0) {
|
||||
newPlayer->setPos(newPlayer->x, newPlayer->y, newPlayer->z);
|
||||
if (level->getCubes(newPlayer, newPlayer->bb).size() == 0) break;
|
||||
newPlayer->y += 1;
|
||||
}
|
||||
newPlayer->moveTo(newPlayer->x, newPlayer->y - newPlayer->heightOffset, newPlayer->z, newPlayer->yRot, newPlayer->xRot);
|
||||
|
||||
// send world seed
|
||||
{
|
||||
RakNet::BitStream bitStream;
|
||||
|
||||
// @todo: Read from LevelData?
|
||||
int gameType = minecraft->isCreativeMode()
|
||||
? GameType::Creative
|
||||
: GameType::Survival;
|
||||
|
||||
StartGamePacket(
|
||||
level->getSeed(),
|
||||
level->getLevelData()->getGeneratorVersion(),
|
||||
gameType,
|
||||
newPlayer->entityId,
|
||||
newPlayer->x, newPlayer->y - newPlayer->heightOffset, newPlayer->z
|
||||
).write(&bitStream);
|
||||
|
||||
rakPeer->Send(&bitStream, HIGH_PRIORITY, RELIABLE_ORDERED, 0, source, false);
|
||||
}
|
||||
}
|
||||
|
||||
void ServerSideNetworkHandler::handle(const RakNet::RakNetGUID& source, ReadyPacket* packet)
|
||||
{
|
||||
if (!level) return;
|
||||
|
||||
if (packet->type == ReadyPacket::READY_CLIENTGENERATION)
|
||||
onReady_ClientGeneration(source);
|
||||
|
||||
if (packet->type == ReadyPacket::READY_REQUESTEDCHUNKS)
|
||||
onReady_RequestedChunks(source);
|
||||
}
|
||||
|
||||
void ServerSideNetworkHandler::onReady_ClientGeneration(const RakNet::RakNetGUID& source)
|
||||
{
|
||||
Player* newPlayer = popPendingPlayer(source);
|
||||
if (!newPlayer) {
|
||||
for (int i = 0; i < 3; ++i)
|
||||
LOGE("We don't have a user associated with this player!\n");
|
||||
return;
|
||||
}
|
||||
// Create a bitstream that can be used by everyone (after ::reset() )
|
||||
RakNet::BitStream bitStream;
|
||||
|
||||
// send level info
|
||||
SetTimePacket(level->getTime()).write(&bitStream);
|
||||
rakPeer->Send(&bitStream, HIGH_PRIORITY, RELIABLE_ORDERED, 0, source, false);
|
||||
|
||||
// send all pre-existing players to the new player
|
||||
const PlayerList& players = level->players;
|
||||
for (unsigned int i = 0; i < players.size(); i++) {
|
||||
Player* player = players[i];
|
||||
|
||||
bitStream.Reset();
|
||||
AddPlayerPacket(player).write(&bitStream);
|
||||
rakPeer->Send(&bitStream, HIGH_PRIORITY, RELIABLE_ORDERED, 0, source, false);
|
||||
|
||||
if (player->getArmorTypeHash()) {
|
||||
bitStream.Reset();
|
||||
PlayerArmorEquipmentPacket(player).write(&bitStream);
|
||||
rakPeer->Send(&bitStream, HIGH_PRIORITY, RELIABLE_ORDERED, 0, source, false);
|
||||
}
|
||||
}
|
||||
|
||||
level->addEntity(newPlayer);
|
||||
#ifndef STANDALONE_SERVER
|
||||
minecraft->gui.addMessage(newPlayer->name + " joined the game");
|
||||
#else
|
||||
LOGW("%s joined the game\n", newPlayer->name.c_str());
|
||||
#endif
|
||||
|
||||
// Send all Entities to the new player
|
||||
for (unsigned int i = 0; i < level->entities.size(); ++i) {
|
||||
Entity* e = level->entities[i];
|
||||
Packet* packet = getAddPacketFromEntity(e);
|
||||
if(packet != NULL) {
|
||||
bitStream.Reset();
|
||||
packet->write(&bitStream);
|
||||
rakPeer->Send(&bitStream, HIGH_PRIORITY, RELIABLE_ORDERED, 0, source, false);
|
||||
delete packet;
|
||||
}
|
||||
}
|
||||
|
||||
// Additional packets
|
||||
// * set spawn
|
||||
/*
|
||||
bitStream.Reset();
|
||||
SetSpawnPositionPacket spawnPacket(level->getSharedSpawnPos());
|
||||
raknetInstance->send(source, spawnPacket);
|
||||
rakPeer->Send(&bitStream, HIGH_PRIORITY, RELIABLE_ORDERED, 0, source, false);
|
||||
*/
|
||||
|
||||
// broadcast the new player to all other players
|
||||
bitStream.Reset();
|
||||
AddPlayerPacket(newPlayer).write(&bitStream);
|
||||
rakPeer->Send(&bitStream, HIGH_PRIORITY, RELIABLE_ORDERED, 0, source, true);
|
||||
}
|
||||
|
||||
//
|
||||
// Messages to be sent after client has finished applying changes
|
||||
//
|
||||
void ServerSideNetworkHandler::onReady_RequestedChunks(const RakNet::RakNetGUID& source)
|
||||
{
|
||||
RakNet::BitStream bitStream;
|
||||
// Send all TileEntities to the new player
|
||||
for (unsigned int i = 0; i < level->tileEntities.size(); ++i) {
|
||||
TileEntity* e = level->tileEntities[i];
|
||||
Packet* packet = e->getUpdatePacket();
|
||||
if (packet != NULL) {
|
||||
bitStream.Reset();
|
||||
packet->write(&bitStream);
|
||||
rakPeer->Send(&bitStream, HIGH_PRIORITY, RELIABLE_ORDERED, 0, source, false);
|
||||
delete packet;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ServerSideNetworkHandler::handle(const RakNet::RakNetGUID& source, MovePlayerPacket* packet)
|
||||
{
|
||||
if (!level) return;
|
||||
|
||||
//LOGI("MovePlayerPacket\n");
|
||||
if (Entity* entity = level->getEntity(packet->entityId))
|
||||
{
|
||||
entity->xd = entity->yd = entity->zd = 0;
|
||||
entity->lerpTo(packet->x, packet->y, packet->z, packet->yRot, packet->xRot, 3);
|
||||
|
||||
// broadcast this packet to other clients
|
||||
redistributePacket(packet, source);
|
||||
}
|
||||
}
|
||||
|
||||
void ServerSideNetworkHandler::handle(const RakNet::RakNetGUID& source, RemoveBlockPacket* packet){
|
||||
if (!level) return;
|
||||
|
||||
Player* player = getPlayer(source);
|
||||
if (!player) return;
|
||||
|
||||
player->swing();
|
||||
|
||||
int x = packet->x, y = packet->y, z = packet->z;
|
||||
|
||||
// code copied from GameMode.cpp
|
||||
int oldId = level->getTile(x, y, z);
|
||||
int data = level->getData(x, y, z);
|
||||
Tile* oldTile = Tile::tiles[oldId];
|
||||
bool changed = level->setTile(x, y, z, 0);
|
||||
if (oldTile != NULL && changed) {
|
||||
level->playSound(x + 0.5f, y + 0.5f, z + 0.5f, oldTile->soundType->getBreakSound(), (oldTile->soundType->getVolume() + 1) / 2, oldTile->soundType->getPitch() * 0.8f);
|
||||
|
||||
if (minecraft->gameMode->isSurvivalType() && player->canDestroy(oldTile))
|
||||
//oldTile->spawnResources(level, x, y, z, data, 1); //@todo
|
||||
oldTile->playerDestroy(level, player, x, y, z, data);
|
||||
|
||||
oldTile->destroy(level, x, y, z, data);
|
||||
}
|
||||
}
|
||||
|
||||
void ServerSideNetworkHandler::handle(const RakNet::RakNetGUID& source, RequestChunkPacket* packet)
|
||||
{
|
||||
if (!level)
|
||||
return;
|
||||
|
||||
LevelChunk* chunk = level->getChunk(packet->x, packet->z);
|
||||
|
||||
if (!chunk)
|
||||
return;
|
||||
|
||||
ChunkDataPacket cpacket(chunk->x, chunk->z, chunk);
|
||||
|
||||
RakNet::BitStream bitStream;
|
||||
cpacket.write(&bitStream);
|
||||
rakPeer->Send(&bitStream, HIGH_PRIORITY, RELIABLE_ORDERED, 0, source, false);
|
||||
//LOGI("RequestChunkPacket @ (%d, %d). %d bytes\n", packet->x, packet->z, cpacket.chunkData.GetNumberOfBytesUsed());
|
||||
//LOGI("size: %d\n", bitStream.GetNumberOfBytesUsed());
|
||||
|
||||
const LevelChunk::TEMap& teMap = chunk->getTileEntityMap();
|
||||
for (LevelChunk::TEMapCIterator cit = teMap.begin(); cit != teMap.end(); ++cit) {
|
||||
TileEntity* te = cit->second;
|
||||
if (Packet* p = te->getUpdatePacket()) {
|
||||
bitStream.Reset();
|
||||
p->write(&bitStream);
|
||||
raknetInstance->send(source, p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ServerSideNetworkHandler::levelGenerated( Level* level )
|
||||
{
|
||||
this->level = level;
|
||||
|
||||
if (minecraft->player) {
|
||||
minecraft->player->owner = rakPeer->GetMyGUID();
|
||||
}
|
||||
|
||||
level->addListener(this);
|
||||
#ifndef STANDALONE_SERVER
|
||||
allowIncomingConnections(minecraft->options.serverVisible);
|
||||
#else
|
||||
allowIncomingConnections(true);
|
||||
#endif
|
||||
}
|
||||
|
||||
void ServerSideNetworkHandler::handle(const RakNet::RakNetGUID& source, PlayerEquipmentPacket* packet)
|
||||
{
|
||||
if (!level) return;
|
||||
|
||||
Player* player = getPlayer(source);
|
||||
if (!player) return;
|
||||
if (rakPeer->GetMyGUID() == player->owner) return;
|
||||
|
||||
// override the player's inventory
|
||||
//int slot = player->inventory->getSlot(packet->itemId, packet->itemAuxValue);
|
||||
int slot = Inventory::MAX_SELECTION_SIZE;
|
||||
if (slot >= 0) {
|
||||
if (packet->itemId == 0) {
|
||||
player->inventory->clearSlot(slot);
|
||||
} else {
|
||||
// @note: 128 is an ugly hack for depletable items.
|
||||
// @todo: fix
|
||||
ItemInstance newItem(packet->itemId, 128, packet->itemAuxValue);
|
||||
player->inventory->replaceSlot(slot, &newItem);
|
||||
}
|
||||
player->inventory->moveToSelectedSlot(slot, true);
|
||||
redistributePacket(packet, source);
|
||||
} else {
|
||||
LOGW("Warning: Remote player doesn't have his thing, Odd!\n");
|
||||
}
|
||||
}
|
||||
|
||||
void ServerSideNetworkHandler::handle(const RakNet::RakNetGUID& source, PlayerArmorEquipmentPacket* packet) {
|
||||
if (!level) return;
|
||||
|
||||
Player* player = getPlayer(source);
|
||||
if (!player) return;
|
||||
if (rakPeer->GetMyGUID() == player->owner) return;
|
||||
|
||||
packet->fillIn(player);
|
||||
redistributePacket(packet, source);
|
||||
}
|
||||
|
||||
void ServerSideNetworkHandler::handle(const RakNet::RakNetGUID& source, InteractPacket* packet) {
|
||||
if (!level) return;
|
||||
|
||||
Entity* src = level->getEntity(packet->sourceId);
|
||||
Entity* entity = level->getEntity(packet->targetId);
|
||||
if (src && entity && src->isPlayer())
|
||||
{
|
||||
Player* player = (Player*) src;
|
||||
if (InteractPacket::Attack == packet->action) {
|
||||
player->swing();
|
||||
minecraft->gameMode->attack(player, entity);
|
||||
}
|
||||
if (InteractPacket::Interact == packet->action) {
|
||||
player->swing();
|
||||
minecraft->gameMode->interact(player, entity);
|
||||
}
|
||||
|
||||
redistributePacket(packet, source);
|
||||
}
|
||||
}
|
||||
|
||||
void ServerSideNetworkHandler::handle(const RakNet::RakNetGUID& source, AnimatePacket* packet)
|
||||
{
|
||||
if (!level)
|
||||
return;
|
||||
|
||||
// Own player -> invalid
|
||||
if (minecraft->player && minecraft->player->entityId == packet->entityId) {
|
||||
return;
|
||||
}
|
||||
|
||||
Entity* entity = level->getEntity(packet->entityId);
|
||||
if (!entity || !entity->isPlayer())
|
||||
return;
|
||||
|
||||
Player* player = (Player*) entity;
|
||||
|
||||
switch (packet->action) {
|
||||
case AnimatePacket::Swing:
|
||||
player->swing();
|
||||
break;
|
||||
default:
|
||||
LOGW("Unknown Animate action: %d\n", packet->action);
|
||||
break;
|
||||
}
|
||||
redistributePacket(packet, source);
|
||||
}
|
||||
|
||||
void ServerSideNetworkHandler::handle(const RakNet::RakNetGUID& source, UseItemPacket* packet)
|
||||
{
|
||||
if (!level) return;
|
||||
|
||||
LOGI("UseItemPacket\n");
|
||||
Entity* entity = level->getEntity(packet->entityId);
|
||||
if (entity && entity->isPlayer()) {
|
||||
Player* player = (Player*) entity;
|
||||
int x = packet->x, y = packet->y, z = packet->z;
|
||||
Tile* t = Tile::tiles[level->getTile(x, y, z)];
|
||||
|
||||
if (t == Tile::invisible_bedrock) return;
|
||||
if (t && t->use(level, x, y, z, player)) return;
|
||||
if (packet->item.isNull()) return;
|
||||
|
||||
ItemInstance* item = &packet->item;
|
||||
|
||||
if(packet->face == 255) {
|
||||
// Special case: x,y,z means direction-of-action
|
||||
player->aimDirection.set(packet->x / 32768.0f, packet->y / 32768.0f, packet->z / 32768.0f);
|
||||
minecraft->gameMode->useItem(player, level, item);
|
||||
}
|
||||
else {
|
||||
minecraft->gameMode->useItemOn(player, level, item, packet->x, packet->y, packet->z, packet->face,
|
||||
Vec3(packet->clickX + packet->x, packet->clickY + packet->y, packet->clickZ + packet->z));
|
||||
}
|
||||
|
||||
//LOGW("Use Item not working! Out of synch?\n");
|
||||
|
||||
// Don't have to redistribute (ugg.. this will mess up), cause tileUpdated is sent
|
||||
//redistributePacket(packet, source);
|
||||
}
|
||||
}
|
||||
|
||||
void ServerSideNetworkHandler::handle(const RakNet::RakNetGUID& source, EntityEventPacket* packet) {
|
||||
if (!level) return;
|
||||
|
||||
if (Entity* e = level->getEntity(packet->entityId))
|
||||
e->handleEntityEvent(packet->eventId);
|
||||
}
|
||||
|
||||
void ServerSideNetworkHandler::handle(const RakNet::RakNetGUID& source, PlayerActionPacket* packet)
|
||||
{
|
||||
if (!level) return;
|
||||
LOGI("PlayerActionPacket\n");
|
||||
Entity* entity = level->getEntity(packet->entityId);
|
||||
if (entity && entity->isPlayer()) {
|
||||
Player* player = (Player*) entity;
|
||||
if(packet->action == PlayerActionPacket::RELEASE_USE_ITEM) {
|
||||
minecraft->gameMode->releaseUsingItem(player);
|
||||
return;
|
||||
}
|
||||
else if(packet->action == PlayerActionPacket::STOP_SLEEPING) {
|
||||
player->stopSleepInBed(true, true, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ServerSideNetworkHandler::handle( const RakNet::RakNetGUID& source, RespawnPacket* packet )
|
||||
{
|
||||
if (!level) return;
|
||||
|
||||
NetEventCallback::handle(level, source, packet );
|
||||
redistributePacket(packet, source);
|
||||
}
|
||||
|
||||
void ServerSideNetworkHandler::handle( const RakNet::RakNetGUID& source, SendInventoryPacket* packet )
|
||||
{
|
||||
if (!level) return;
|
||||
|
||||
Entity* entity = level->getEntity(packet->entityId);
|
||||
if (entity && entity->isPlayer()) {
|
||||
Player* p = (Player*)entity;
|
||||
p->inventory->replace(packet->items, packet->numItems);
|
||||
if ((packet->extra & SendInventoryPacket::ExtraDrop) != 0) {
|
||||
p->inventory->dropAll(false);
|
||||
//@todo @armor : Drop armor
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ServerSideNetworkHandler::handle( const RakNet::RakNetGUID& source, DropItemPacket* packet )
|
||||
{
|
||||
if (!level) return;
|
||||
|
||||
Entity* entity = level->getEntity(packet->entityId);
|
||||
if (entity && entity->isPlayer()) {
|
||||
Player* p = (Player*)entity;
|
||||
p->drop(new ItemInstance(packet->item), packet->dropType != 0);
|
||||
}
|
||||
}
|
||||
|
||||
void ServerSideNetworkHandler::handle(const RakNet::RakNetGUID& source, ContainerClosePacket* packet) {
|
||||
if (!level) return;
|
||||
|
||||
Player* p = findPlayer(level, &source);
|
||||
if (!p) return;
|
||||
|
||||
if (p != minecraft->player)
|
||||
static_cast<ServerPlayer*>(p)->doCloseContainer();
|
||||
}
|
||||
|
||||
void ServerSideNetworkHandler::handle(const RakNet::RakNetGUID& source, ContainerSetSlotPacket* packet) {
|
||||
if (!level) return;
|
||||
|
||||
Player* p = findPlayer(level, &source);
|
||||
if (!p) return;
|
||||
|
||||
if (p->containerMenu == NULL) {
|
||||
LOGW("User has no container!\n");
|
||||
return;
|
||||
}
|
||||
if (p->containerMenu->containerId != packet->containerId)
|
||||
{
|
||||
LOGW("Wrong container id: %d vs %d\n", p->containerMenu->containerId, packet->containerId);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ContainerType::FURNACE == p->containerMenu->containerType) {
|
||||
//LOGI("Server:Setting slot %d: %s\n", packet->slot, packet->item.toString().c_str());
|
||||
p->containerMenu->setSlot(packet->slot, &packet->item);
|
||||
//p->containerMenu->setSlot(packet->slot, packet->item.isNull()? NULL : &packet->item);
|
||||
}
|
||||
if (ContainerType::CONTAINER == p->containerMenu->containerType) {
|
||||
//LOGI("Server:Setting slot %d: %s\n", packet->slot, packet->item.toString().c_str());
|
||||
p->containerMenu->setSlot(packet->slot, &packet->item);
|
||||
//p->containerMenu->setSlot(packet->slot, packet->item.isNull()? NULL : &packet->item);
|
||||
}
|
||||
}
|
||||
|
||||
void ServerSideNetworkHandler::handle( const RakNet::RakNetGUID& source, SetHealthPacket* packet )
|
||||
{
|
||||
for (unsigned int i = 0; i < level->players.size(); ++i) {
|
||||
Player* p = level->players[i];
|
||||
if (p->owner == source) {
|
||||
if (packet->health <= -32) {
|
||||
int diff = packet->health - SetHealthPacket::HEALTH_MODIFY_OFFSET;
|
||||
if (diff > 0) p->hurt(NULL, diff);
|
||||
else if (diff < 0) p->heal(-diff);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ServerSideNetworkHandler::handle( const RakNet::RakNetGUID& source, SignUpdatePacket* packet ) {
|
||||
redistributePacket(packet, source);
|
||||
if (!level)
|
||||
return;
|
||||
|
||||
TileEntity* te = level->getTileEntity(packet->x, packet->y, packet->z);
|
||||
if (TileEntity::isType(te, TileEntityType::Sign)) {
|
||||
SignTileEntity* ste = (SignTileEntity*) te;
|
||||
if (ste->isEditable()) {
|
||||
for (int i = 0; i < SignTileEntity::NUM_LINES; i++) {
|
||||
ste->messages[i] = packet->lines[i];
|
||||
}
|
||||
//ste->setChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ServerSideNetworkHandler::allowIncomingConnections( bool doAllow )
|
||||
{
|
||||
if (doAllow) {
|
||||
raknetInstance->announceServer(minecraft->options.username);
|
||||
} else {
|
||||
raknetInstance->announceServer("");
|
||||
}
|
||||
_allowIncoming = doAllow;
|
||||
}
|
||||
|
||||
Player* ServerSideNetworkHandler::popPendingPlayer( const RakNet::RakNetGUID& source )
|
||||
{
|
||||
if (!level) {
|
||||
LOGE("Could not add player since Level is NULL!\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < _pendingPlayers.size(); ++i) {
|
||||
Player* p = _pendingPlayers[i];
|
||||
if (p->owner == source) {
|
||||
_pendingPlayers.erase(_pendingPlayers.begin() + i);
|
||||
return p;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void ServerSideNetworkHandler::levelEvent( Player* source, int type, int x, int y, int z, int data )
|
||||
{
|
||||
LevelEventPacket packet(type, x, y, z, data);
|
||||
redistributePacket(&packet, source? source->owner : rakPeer->GetMyGUID());
|
||||
}
|
||||
|
||||
void ServerSideNetworkHandler::tileEvent( int x, int y, int z, int b0, int b1 )
|
||||
{
|
||||
TileEventPacket packet(x, y, z, b0, b1);
|
||||
raknetInstance->send(packet);
|
||||
}
|
||||
|
||||
Player* ServerSideNetworkHandler::getPlayer( const RakNet::RakNetGUID& source ) {
|
||||
for (unsigned int i = 0; i < level->players.size(); ++i)
|
||||
if (source == level->players[i]->owner) return level->players[i];
|
||||
return NULL;
|
||||
}
|
||||
82
src/network/ServerSideNetworkHandler.h
Executable file
82
src/network/ServerSideNetworkHandler.h
Executable file
@@ -0,0 +1,82 @@
|
||||
#ifndef _MINECRAFT_NETWORK_SERVERSIDENETWORKHANDLER_H_
|
||||
#define _MINECRAFT_NETWORK_SERVERSIDENETWORKHANDLER_H_
|
||||
|
||||
|
||||
#include "NetEventCallback.h"
|
||||
#include "../raknet/RakNetTypes.h"
|
||||
#include "../world/level/LevelListener.h"
|
||||
#include <vector>
|
||||
|
||||
class Minecraft;
|
||||
class Level;
|
||||
class IRakNetInstance;
|
||||
class Packet;
|
||||
class Player;
|
||||
|
||||
class ServerSideNetworkHandler : public NetEventCallback, public LevelListener
|
||||
{
|
||||
public:
|
||||
ServerSideNetworkHandler(Minecraft* minecraft, IRakNetInstance* raknetInstance);
|
||||
virtual ~ServerSideNetworkHandler();
|
||||
|
||||
virtual void levelGenerated(Level* level);
|
||||
|
||||
virtual void tileChanged(int x, int y, int z);
|
||||
virtual void tileBrightnessChanged(int x, int y, int z) { /* do nothing */ }
|
||||
virtual Packet* getAddPacketFromEntity(Entity* entity);
|
||||
virtual void entityAdded(Entity* e);
|
||||
virtual void entityRemoved(Entity* e);
|
||||
virtual void levelEvent(Player* source, int type, int x, int y, int z, int data);
|
||||
virtual void tileEvent(int x, int y, int z, int b0, int b1);
|
||||
|
||||
virtual void onNewClient(const RakNet::RakNetGUID& clientGuid);
|
||||
virtual void onDisconnect(const RakNet::RakNetGUID& guid);
|
||||
|
||||
void onReady_ClientGeneration(const RakNet::RakNetGUID& source);
|
||||
void onReady_RequestedChunks(const RakNet::RakNetGUID& source);
|
||||
|
||||
virtual void handle(const RakNet::RakNetGUID& source, LoginPacket* packet);
|
||||
virtual void handle(const RakNet::RakNetGUID& source, ReadyPacket* packet);
|
||||
virtual void handle(const RakNet::RakNetGUID& source, MovePlayerPacket* packet);
|
||||
//virtual void handle(const RakNet::RakNetGUID& source, PlaceBlockPacket* packet);
|
||||
virtual void handle(const RakNet::RakNetGUID& source, RemoveBlockPacket* packet);
|
||||
//virtual void handle(const RakNet::RakNetGUID& source, ExplodePacket* packet);
|
||||
virtual void handle(const RakNet::RakNetGUID& source, RequestChunkPacket* packet);
|
||||
virtual void handle(const RakNet::RakNetGUID& source, PlayerEquipmentPacket* packet);
|
||||
virtual void handle(const RakNet::RakNetGUID& source, PlayerArmorEquipmentPacket* packet);
|
||||
virtual void handle(const RakNet::RakNetGUID& source, SetHealthPacket* packet);
|
||||
//virtual void handle(const RakNet::RakNetGUID& source, TeleportEntityPacket* packet);
|
||||
virtual void handle(const RakNet::RakNetGUID& source, InteractPacket* packet);
|
||||
virtual void handle(const RakNet::RakNetGUID& source, AnimatePacket* packet);
|
||||
virtual void handle(const RakNet::RakNetGUID& source, UseItemPacket* packet);
|
||||
virtual void handle(const RakNet::RakNetGUID& source, EntityEventPacket* packet);
|
||||
virtual void handle(const RakNet::RakNetGUID& source, PlayerActionPacket* packet);
|
||||
virtual void handle(const RakNet::RakNetGUID& source, RespawnPacket* packet);
|
||||
virtual void handle(const RakNet::RakNetGUID& source, SendInventoryPacket* packet);
|
||||
virtual void handle(const RakNet::RakNetGUID& source, DropItemPacket* packet);
|
||||
virtual void handle(const RakNet::RakNetGUID& source, ContainerSetSlotPacket* packet);
|
||||
virtual void handle(const RakNet::RakNetGUID& source, ContainerClosePacket* packet);
|
||||
virtual void handle(const RakNet::RakNetGUID& source, SignUpdatePacket* packet);
|
||||
|
||||
bool allowsIncomingConnections() { return _allowIncoming; }
|
||||
void allowIncomingConnections(bool doAllow);
|
||||
|
||||
Player* popPendingPlayer(const RakNet::RakNetGUID& source);
|
||||
private:
|
||||
|
||||
void redistributePacket(Packet* packet, const RakNet::RakNetGUID& fromPlayer);
|
||||
void displayGameMessage(const std::string& message);
|
||||
|
||||
Player* getPlayer(const RakNet::RakNetGUID& source);
|
||||
private:
|
||||
|
||||
Minecraft* minecraft;
|
||||
Level* level;
|
||||
IRakNetInstance* raknetInstance;
|
||||
RakNet::RakPeerInterface* rakPeer;
|
||||
|
||||
std::vector<Player*> _pendingPlayers;
|
||||
bool _allowIncoming;
|
||||
};
|
||||
|
||||
#endif
|
||||
721
src/network/command/CommandServer.cpp
Executable file
721
src/network/command/CommandServer.cpp
Executable file
@@ -0,0 +1,721 @@
|
||||
#include "CommandServer.h"
|
||||
#include "../../client/Minecraft.h"
|
||||
#include "../../world/level/Level.h"
|
||||
#include "../../world/entity/Entity.h"
|
||||
|
||||
#ifdef WIN32
|
||||
#define SERR(x) (WSA ## x)
|
||||
#else
|
||||
#define SERR(x) (x)
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "../RakNetInstance.h"
|
||||
#include "../packet/ChatPacket.h"
|
||||
#include "../packet/AdventureSettingsPacket.h"
|
||||
#include "../../world/level/LevelSettings.h"
|
||||
#include "../../world/entity/player/Player.h"
|
||||
#include "../../client/gamemode/CreatorMode.h"
|
||||
#include "../../client/player/LocalPlayer.h"
|
||||
#include "../RakNetInstance.h"
|
||||
|
||||
const std::string NullString;
|
||||
const std::string CommandServer::Ok("\n");
|
||||
const std::string CommandServer::Fail("Fail\n");
|
||||
|
||||
static bool setSocketBlocking(int socket, bool blocking);
|
||||
|
||||
// Return value < 0 means socket is shut down / broken
|
||||
static int Readline(ConnectedClient* client, std::string& out, int maxlen);
|
||||
static int Writeline(ConnectedClient* client, const std::string& in, int maxlen);
|
||||
|
||||
class CameraEntity: public Mob
|
||||
{
|
||||
typedef Mob super;
|
||||
public:
|
||||
CameraEntity(Level* level)
|
||||
: super(level),
|
||||
followEntityId(-1)
|
||||
{
|
||||
moveTo(128, 72, 128, 0, 90.0f);
|
||||
}
|
||||
|
||||
void follow(int entityId) {
|
||||
followEntityId = entityId;
|
||||
}
|
||||
|
||||
void tick() {
|
||||
if (followEntityId < 0) return;
|
||||
|
||||
xOld = xo = x;
|
||||
yOld = yo = y;
|
||||
zOld = zo = z;
|
||||
xRotO = xRot;
|
||||
yRotO = yRot;
|
||||
|
||||
Entity* e = level->getEntity(followEntityId);
|
||||
if (!e) return;
|
||||
setPos(e->x, e->y + 6, e->z);
|
||||
}
|
||||
|
||||
int getEntityTypeId() const { return 0; }
|
||||
|
||||
private:
|
||||
int followEntityId;
|
||||
};
|
||||
|
||||
static int getSocketError() {
|
||||
#ifdef WIN32
|
||||
return WSAGetLastError();
|
||||
#else
|
||||
return errno;
|
||||
#endif
|
||||
}
|
||||
|
||||
static int t = 0;
|
||||
|
||||
template <typename T>
|
||||
static std::string ToStringOk(const T& a) {
|
||||
std::stringstream ss;
|
||||
ss << a << "\n";
|
||||
return ss.str();
|
||||
}
|
||||
template <typename T>
|
||||
static std::string ToStringOk(const T& a, const T& b) {
|
||||
std::stringstream ss;
|
||||
ss << a << "," << b << "\n";
|
||||
return ss.str();
|
||||
}
|
||||
template <typename T>
|
||||
static std::string ToStringOk(const T& a, const T& b, const T& c) {
|
||||
std::stringstream ss;
|
||||
ss << a << "," << b << "," << c << "\n";
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
static bool inRange(int c, int lowInclusive, int highInclusive) {
|
||||
return c >= lowInclusive && c <= highInclusive;
|
||||
}
|
||||
|
||||
CommandServer::CommandServer( Minecraft* mc )
|
||||
: mc(mc),
|
||||
serverSocket(0),
|
||||
restoreBuffer(0),
|
||||
inited(false)
|
||||
{
|
||||
camera = new CameraEntity(mc->level);
|
||||
|
||||
Pos p = mc->level->getSharedSpawnPos();
|
||||
apiPosTranslate = OffsetPosTranslator((float)-p.x, (float)-p.y, (float)-p.z);
|
||||
}
|
||||
|
||||
CommandServer::~CommandServer() {
|
||||
_close();
|
||||
|
||||
delete camera;
|
||||
delete[] restoreBuffer;
|
||||
}
|
||||
|
||||
void CommandServer::_close()
|
||||
{
|
||||
if (inited) {
|
||||
if (serverSocket > 0) {
|
||||
#ifdef WIN32
|
||||
closesocket(serverSocket);
|
||||
#else
|
||||
close(serverSocket);
|
||||
#endif
|
||||
}
|
||||
inited = false;
|
||||
serverSocket = 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool CommandServer::init(short port) {
|
||||
_close();
|
||||
|
||||
if ((serverSocket = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
|
||||
printf("Failed creating socket - 1\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
setSocketBlocking(serverSocket, false);
|
||||
|
||||
memset(&serverAddress, 0, sizeof(serverAddress));
|
||||
serverAddress.sin_family = AF_INET;
|
||||
serverAddress.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
serverAddress.sin_port = htons(port);
|
||||
|
||||
int enabled = 1;
|
||||
setsockopt(serverSocket, SOL_SOCKET, SO_REUSEADDR, (const char*)&enabled, sizeof(enabled));
|
||||
|
||||
if (bind(serverSocket, (struct sockaddr *) &serverAddress, sizeof(serverAddress)) < 0) {
|
||||
printf("Failed binding socket - 2\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (listen(serverSocket, 128) < 0 ) {
|
||||
printf("Failed listening on socket - 3\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
LOGI("Listening on port %d\n", port);
|
||||
inited = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string CommandServer::parse(ConnectedClient& client, const std::string& s) {
|
||||
int b = s.find("(");
|
||||
if (b == std::string::npos) {
|
||||
return Fail;
|
||||
}
|
||||
|
||||
int e = s.rfind(")");
|
||||
if (b == std::string::npos) {
|
||||
return Fail;
|
||||
}
|
||||
|
||||
std::string cmd = s.substr(0, b);
|
||||
std::string rest = s.substr(b+1, e-b-1);
|
||||
|
||||
//
|
||||
// Block related get, set and query
|
||||
//
|
||||
if (cmd == "world.setBlock") {
|
||||
int x, y, z, id, data;
|
||||
bool hasData = true;
|
||||
|
||||
int c = sscanf(rest.c_str(), "%d,%d,%d,%d,%d", &x, &y, &z, &id, &data);
|
||||
if (!inRange(c, 4, 5)) return Fail;
|
||||
if (c == 4) hasData = false;
|
||||
|
||||
id &= 255;
|
||||
if (id > 0 && !Tile::tiles[id])
|
||||
return Fail;
|
||||
|
||||
apiPosTranslate.from(x, y, z);
|
||||
|
||||
if (hasData)
|
||||
mc->level->setTileAndData(x, y, z, id, data & 15);
|
||||
else
|
||||
mc->level->setTile(x, y, z, id);
|
||||
|
||||
return NullString;
|
||||
}
|
||||
|
||||
if (cmd == "world.getBlock") {
|
||||
int x, y, z;
|
||||
if (3 != sscanf(rest.c_str(), "%d,%d,%d", &x, &y, &z)) {
|
||||
return Fail;
|
||||
}
|
||||
apiPosTranslate.from(x, y, z);
|
||||
return ToStringOk(mc->level->getTile(x, y, z));
|
||||
}
|
||||
|
||||
if (cmd == "world.setBlocks") {
|
||||
int x0, y0, z0, x1, y1, z1, id, data;
|
||||
bool hasData = true;
|
||||
|
||||
int c = sscanf(rest.c_str(), "%d,%d,%d,%d,%d,%d,%d,%d", &x0, &y0, &z0, &x1, &y1, &z1, &id, &data);
|
||||
if (!inRange(c, 7, 8)) return Fail;
|
||||
if (c == 7) hasData = false;
|
||||
|
||||
id &= 255;
|
||||
|
||||
if (id > 0 && !Tile::tiles[id])
|
||||
return Fail;
|
||||
|
||||
if (x0 > x1) std::swap(x0, x1);
|
||||
if (y0 > y1) std::swap(y0, y1);
|
||||
if (z0 > z1) std::swap(z0, z1);
|
||||
|
||||
apiPosTranslate.from(x0, y0, z0);
|
||||
apiPosTranslate.from(x1, y1, z1);
|
||||
|
||||
if (x0 < 0) x0 = 0;
|
||||
if (y0 < 0) y0 = 0;
|
||||
if (z0 < 0) z0 = 0;
|
||||
if (x1 >= LEVEL_WIDTH ) x1 = LEVEL_WIDTH - 1;
|
||||
if (y1 >= LEVEL_HEIGHT) y1 = LEVEL_HEIGHT - 1;
|
||||
if (z1 >= LEVEL_DEPTH ) z1 = LEVEL_DEPTH - 1;
|
||||
|
||||
for (int y = y0; y <= y1; ++y)
|
||||
for (int z = z0; z <= z1; ++z)
|
||||
for (int x = x0; x <= x1; ++x) {
|
||||
if (hasData)
|
||||
mc->level->setTileAndData(x, y, z, id, data & 15);
|
||||
else
|
||||
mc->level->setTile(x, y, z, id);
|
||||
}
|
||||
return NullString;
|
||||
}
|
||||
|
||||
if (cmd == "world.getHeight") {
|
||||
int x, z;
|
||||
if (2 != sscanf(rest.c_str(), "%d,%d", &x, &z)) {
|
||||
return Fail;
|
||||
}
|
||||
x -= (int)apiPosTranslate.xo;
|
||||
z -= (int)apiPosTranslate.zo;
|
||||
const int y = mc->level->getHeightmap(x, z) + (int)apiPosTranslate.yo;
|
||||
return ToStringOk(y);
|
||||
}
|
||||
|
||||
//
|
||||
// Player related get, set and query
|
||||
//
|
||||
if (cmd == "player.setTile") {
|
||||
if (!mc->player)
|
||||
return Fail;
|
||||
|
||||
int x, y, z;
|
||||
if (3 != sscanf(rest.c_str(), "%d,%d,%d", &x, &y, &z)) {
|
||||
return Fail;
|
||||
}
|
||||
|
||||
apiPosTranslate.from(x, y, z);
|
||||
Entity* e = (Entity*) mc->player;
|
||||
e->moveTo((float)x + 0.5f, (float)y, (float)z + 0.5f, e->yRot, e->xRot);
|
||||
return NullString;
|
||||
}
|
||||
|
||||
if (cmd == "player.getTile") {
|
||||
if (!mc->player)
|
||||
return Fail;
|
||||
|
||||
Entity* e = (Entity*) mc->player;
|
||||
|
||||
int x = (int)e->x, y = (int)(e->y - e->heightOffset), z = (int)e->z;
|
||||
apiPosTranslate.to(x, y, z);
|
||||
return ToStringOk(x, y, z);
|
||||
}
|
||||
|
||||
if (cmd == "player.setPos") {
|
||||
if (!mc->player)
|
||||
return Fail;
|
||||
|
||||
float x, y, z;
|
||||
if (3 != sscanf(rest.c_str(), "%f,%f,%f", &x, &y, &z)) {
|
||||
return Fail;
|
||||
}
|
||||
|
||||
apiPosTranslate.from(x, y, z);
|
||||
Entity* e = (Entity*) mc->player;
|
||||
e->moveTo(x, y, z, e->yRot, e->xRot);
|
||||
return NullString;
|
||||
}
|
||||
|
||||
if (cmd == "player.getPos") {
|
||||
if (!mc->player)
|
||||
return Fail;
|
||||
|
||||
Entity* e = (Entity*) mc->player;
|
||||
|
||||
float x = e->x, y = e->y - e->heightOffset, z = e->z;
|
||||
apiPosTranslate.to(x, y, z);
|
||||
return ToStringOk(x, y, z);
|
||||
}
|
||||
|
||||
//
|
||||
// Entity
|
||||
//
|
||||
if (cmd == "entity.setTile") {
|
||||
int id, x, y, z;
|
||||
if (4 != sscanf(rest.c_str(), "%d,%d,%d,%d", &id, &x, &y, &z)) {
|
||||
return Fail;
|
||||
}
|
||||
Entity* e = mc->level->getEntity(id);
|
||||
if (!e) return Fail;
|
||||
|
||||
apiPosTranslate.from(x, y, z);
|
||||
e->moveTo((float)x + 0.5f, (float)y, (float)z + 0.5f, e->yRot, e->xRot);
|
||||
return NullString;
|
||||
}
|
||||
|
||||
if (cmd == "entity.getTile") {
|
||||
int id;
|
||||
if (1 != sscanf(rest.c_str(), "%d", &id))
|
||||
return Fail;
|
||||
|
||||
Entity* e = mc->level->getEntity(id);
|
||||
if (!e) return Fail;
|
||||
|
||||
int x = (int)e->x, y = (int)(e->y - e->heightOffset), z = (int)e->z;
|
||||
apiPosTranslate.to(x, y, z);
|
||||
return ToStringOk(x, y, z);
|
||||
}
|
||||
|
||||
if (cmd == "entity.setPos") {
|
||||
int id;
|
||||
float x, y, z;
|
||||
if (4 != sscanf(rest.c_str(), "%d,%f,%f,%f", &id, &x, &y, &z)) {
|
||||
return Fail;
|
||||
}
|
||||
Entity* e = mc->level->getEntity(id);
|
||||
if (!e) return Fail;
|
||||
|
||||
apiPosTranslate.from(x, y, z);
|
||||
e->moveTo(x, y, z, e->yRot, e->xRot);
|
||||
return NullString;
|
||||
}
|
||||
|
||||
if (cmd == "entity.getPos") {
|
||||
int id;
|
||||
if (1 != sscanf(rest.c_str(), "%d", &id))
|
||||
return Fail;
|
||||
|
||||
Entity* e = mc->level->getEntity(id);
|
||||
if (!e) return Fail;
|
||||
|
||||
float x = e->x, y = e->y - e->heightOffset, z = e->z;
|
||||
apiPosTranslate.to(x, y, z);
|
||||
return ToStringOk(x, y, z);
|
||||
}
|
||||
|
||||
//
|
||||
// Chat
|
||||
//
|
||||
if (cmd == "chat.post") {
|
||||
#ifndef STANDALONE_SERVER
|
||||
mc->gui.addMessage(rest);
|
||||
#endif
|
||||
ChatPacket p(rest, false);
|
||||
dispatchPacket(p);
|
||||
return NullString;
|
||||
}
|
||||
|
||||
//
|
||||
// Camera
|
||||
//
|
||||
if (cmd == "camera.mode.setFixed") {
|
||||
camera->follow(-1);
|
||||
mc->cameraTargetPlayer = camera;
|
||||
return NullString;
|
||||
}
|
||||
if (cmd == "camera.mode.setNormal") {
|
||||
int entityId = -1;
|
||||
if (!rest.empty()) {
|
||||
if (1 != sscanf(rest.c_str(), "%d", &entityId)) return Fail;
|
||||
}
|
||||
if (entityId > 0) {
|
||||
Entity* e = mc->level->getEntity(entityId);
|
||||
if (e && e->isMob()) mc->cameraTargetPlayer = (Mob*)e;
|
||||
} else {
|
||||
mc->cameraTargetPlayer = (Mob*)mc->player;
|
||||
}
|
||||
return NullString;
|
||||
}
|
||||
|
||||
if (cmd == "camera.mode.setFollow") {
|
||||
int entityId = -1;
|
||||
if (!rest.empty()) {
|
||||
if (1 != sscanf(rest.c_str(), "%d", &entityId)) return Fail;
|
||||
}
|
||||
if (entityId < 0) entityId = mc->player->entityId;
|
||||
|
||||
camera->follow(entityId);
|
||||
mc->cameraTargetPlayer = camera;
|
||||
return NullString;
|
||||
}
|
||||
|
||||
if (cmd == "camera.setPos") {
|
||||
float x, y, z;
|
||||
if (3 != sscanf(rest.c_str(), "%f,%f,%f", &x, &y, &z)) {
|
||||
return Fail;
|
||||
}
|
||||
|
||||
apiPosTranslate.from(x, y, z);
|
||||
Entity* e = (Entity*) mc->cameraTargetPlayer;
|
||||
e->moveTo((float)x + 0.5f, (float)y, (float)z + 0.5f, e->yRot, e->xRot);
|
||||
return NullString;
|
||||
}
|
||||
|
||||
//
|
||||
// Entities
|
||||
//
|
||||
if (cmd == "world.getPlayerIds") {
|
||||
std::stringstream s;
|
||||
int size = mc->level->players.size();
|
||||
for (int i = 0; i < size; ++i) {
|
||||
if (i != 0) s << "|";
|
||||
s << mc->level->players[i]->entityId;
|
||||
}
|
||||
s << "\n";
|
||||
return s.str();
|
||||
}
|
||||
|
||||
//
|
||||
// Set and restore Checkpoint
|
||||
//
|
||||
if (cmd == "world.checkpoint.save") {
|
||||
if (mc->player) {
|
||||
Entity* e = (Entity*) mc->player;
|
||||
|
||||
static Stopwatch sw;
|
||||
sw.start();
|
||||
|
||||
// Save a cuboid around the player
|
||||
const int CSize = CHUNK_CACHE_WIDTH;
|
||||
int cx = (int)e->x / CSize;
|
||||
int cz = (int)e->z / CSize;
|
||||
|
||||
restorePos = Pos(cx, (int)e->y - 8, cz);
|
||||
handleCheckpoint(false);
|
||||
|
||||
sw.stop();
|
||||
sw.printEvery(1, "set-checkpoint");
|
||||
}
|
||||
}
|
||||
|
||||
if (cmd == "world.checkpoint.restore") {
|
||||
bool success = handleCheckpoint(true);
|
||||
if (success) {
|
||||
int xx = 16 * (restorePos.x - 2);
|
||||
int zz = 16 * (restorePos.z - 2);
|
||||
mc->level->setTilesDirty(xx, restorePos.y, zz,
|
||||
xx + 5 * 16, restorePos.y + RestoreHeight, zz + 5 * 16);
|
||||
}
|
||||
return success? NullString : Fail;
|
||||
}
|
||||
|
||||
//
|
||||
// Event queries
|
||||
//
|
||||
if (cmd.find("events.") == 0) {
|
||||
return handleEventPollMessage(client, cmd);
|
||||
}
|
||||
|
||||
// Settings
|
||||
if (cmd.find("player.setting") == 0
|
||||
|| cmd.find("world.setting") == 0) {
|
||||
int value;
|
||||
static char name[1024];
|
||||
if (rest.find(",") >= 100) return Fail;
|
||||
if (2 != sscanf(rest.c_str(), "%[^,],%d", name, &value)) return Fail;
|
||||
return handleSetSetting(name, value);
|
||||
}
|
||||
|
||||
return NullString;
|
||||
}
|
||||
|
||||
bool CommandServer::handleCheckpoint(bool doRestore ) {
|
||||
const int cx = restorePos.x;
|
||||
const int cz = restorePos.z;
|
||||
const int y0 = restorePos.y;
|
||||
const int y1 = y0 + RestoreHeight;
|
||||
const int CSize = CHUNK_CACHE_WIDTH;
|
||||
const int numChunkBytes = RestoreHeight * CSize * CSize * 20 / 8;
|
||||
|
||||
if (!restoreBuffer) {
|
||||
if (doRestore) return false;
|
||||
|
||||
int numBytes = 5 * 5 * numChunkBytes;
|
||||
restoreBuffer = new unsigned char[numBytes];
|
||||
}
|
||||
|
||||
int offset = 0;
|
||||
for (int z = cz - 2; z <= cz + 2; ++z)
|
||||
for (int x = cx - 2; x <= cx + 2; ++x) {
|
||||
LevelChunk* c = mc->level->getChunk(x, z);
|
||||
if (!c) continue;
|
||||
|
||||
if (doRestore) {
|
||||
//LOGI("restoring: %d, %d\n", x, z);
|
||||
c->setBlocksAndData(restoreBuffer, 0, y0, 0, CSize, y1, CSize, offset);
|
||||
} else {
|
||||
//LOGI("saving: %d, %d\n", x, z);
|
||||
c->getBlocksAndData(restoreBuffer, 0, y0, 0, CSize, y1, CSize, offset);
|
||||
}
|
||||
offset += numChunkBytes;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void CommandServer::tick() {
|
||||
if (!inited)
|
||||
return;
|
||||
|
||||
_updateAccept();
|
||||
_updateClients();
|
||||
++t;
|
||||
|
||||
if (mc->cameraTargetPlayer == camera) {
|
||||
camera->tick();
|
||||
}
|
||||
}
|
||||
|
||||
void CommandServer::_updateAccept() {
|
||||
int fd = accept(serverSocket, NULL, NULL);
|
||||
if (fd == -1) {
|
||||
int err = getSocketError();
|
||||
if (err != SERR(EWOULDBLOCK)) {
|
||||
LOGE("Error when trying to accept connections. Error ID: %d\n", err);
|
||||
}
|
||||
return;
|
||||
}
|
||||
setSocketBlocking(fd, false);
|
||||
clients.push_back(ConnectedClient(fd));
|
||||
|
||||
ConnectedClient& c = clients[clients.size()-1];
|
||||
c.lastPoll_blockHit = mc->level->getTime();
|
||||
}
|
||||
|
||||
void CommandServer::_updateClients() {
|
||||
for (int i = clients.size() - 1; i >= 0; --i) {
|
||||
if (!_updateClient(clients[i]))
|
||||
clients.erase(clients.begin() + i);
|
||||
}
|
||||
}
|
||||
|
||||
bool CommandServer::_updateClient(ConnectedClient& client) {
|
||||
std::string line;
|
||||
int maxReadCount = 32;
|
||||
|
||||
while (--maxReadCount >= 0) {
|
||||
int ret = Readline(&client, line, 1024);
|
||||
//printf("Read: %s @ %d\n", client.data.c_str(), t);
|
||||
if (ret)
|
||||
return ret > 0;
|
||||
|
||||
std::string response = parse(client, line);
|
||||
if (NullString != response)
|
||||
if (Writeline(&client, response, 1024) < 0)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void CommandServer::dispatchPacket( Packet& p ) {
|
||||
if (!mc->netCallback || !mc->player) return;
|
||||
const RakNet::RakNetGUID& guid = ((Player*)mc->player)->owner;
|
||||
mc->raknetInstance->send(p);
|
||||
//p.handle(guid, mc->netCallback);
|
||||
}
|
||||
|
||||
std::string CommandServer::handleEventPollMessage( ConnectedClient& client, const std::string& cmd ) {
|
||||
ICreator* c = mc->getCreator();
|
||||
if (!c) {
|
||||
return Fail;
|
||||
}
|
||||
|
||||
if (cmd == "events.clear") {
|
||||
long t = mc->level->getTime();
|
||||
client.lastPoll_blockHit = t;
|
||||
return NullString;
|
||||
}
|
||||
|
||||
if (cmd == "events.block.hits") {
|
||||
ICreator::EventList<ICreator::TileEvent>& events = c->getTileEvents();
|
||||
std::stringstream ss;
|
||||
|
||||
events.write(ss, apiPosTranslate, client.lastPoll_blockHit);
|
||||
client.lastPoll_blockHit = mc->level->getTime();
|
||||
|
||||
ss << "\n";
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
return Fail;
|
||||
}
|
||||
|
||||
void updateAdventureSettingFlag(Minecraft* mc, AdventureSettingsPacket::Flags flag, bool status) {
|
||||
AdventureSettingsPacket p(mc->level->adventureSettings);
|
||||
p.set(flag, status);
|
||||
p.fillIn(mc->level->adventureSettings);
|
||||
mc->raknetInstance->send(p);
|
||||
}
|
||||
|
||||
std::string CommandServer::handleSetSetting( const std::string& setting, int value )
|
||||
{
|
||||
bool status = value != 0;
|
||||
|
||||
if (setting == "autojump") mc->player->autoJumpEnabled = status;
|
||||
|
||||
AdventureSettingsPacket::Flags flag = (AdventureSettingsPacket::Flags)0;
|
||||
if (setting == "nametags_visible") flag = AdventureSettingsPacket::ShowNameTags;
|
||||
if (setting == "world_immutable") flag = AdventureSettingsPacket::WorldImmutable;
|
||||
|
||||
if (flag != 0)
|
||||
updateAdventureSettingFlag(mc, flag, status);
|
||||
|
||||
return NullString;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool setSocketBlocking(int socket, bool blocking) {
|
||||
if (socket< 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef WIN32
|
||||
unsigned long mode = blocking ? 0 : 1;
|
||||
return (ioctlsocket(socket, FIONBIO, &mode) == 0) ? true : false;
|
||||
#else
|
||||
int flags = fcntl(socket, F_GETFL, 0);
|
||||
if (flags < 0) return false;
|
||||
flags = blocking ? (flags & ~O_NONBLOCK) : (flags|O_NONBLOCK);
|
||||
return (fcntl(socket, F_SETFL, flags) == 0) ? true : false;
|
||||
#endif
|
||||
}
|
||||
|
||||
int Readline(ConnectedClient* client, std::string& out, int maxlen) {
|
||||
static char data[2048];
|
||||
char* buffer = data;
|
||||
|
||||
if (!client->data.empty()) {
|
||||
memcpy(data, client->data.c_str(), client->data.length());
|
||||
client->data.clear();
|
||||
}
|
||||
|
||||
bool socketError = false;
|
||||
for (int n = 1; n < maxlen; n++ ) {
|
||||
int rc;
|
||||
char c;
|
||||
if ( (rc = recv(client->socket, &c, 1, 0)) == 1 ) {
|
||||
*buffer++ = c;
|
||||
|
||||
if ( c == '\n' ) {
|
||||
*buffer = 0;
|
||||
out.assign(data, buffer + 1);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else if ( rc == 0 ) {
|
||||
socketError = true;
|
||||
break;
|
||||
}
|
||||
else if ( rc == -1) {
|
||||
int err = getSocketError();
|
||||
if (err == SERR(EINTR))
|
||||
continue;
|
||||
socketError = (err != SERR(EWOULDBLOCK));
|
||||
break;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
client->data.assign(data, buffer + 1);
|
||||
return socketError? -1 : 1;
|
||||
}
|
||||
|
||||
int Writeline(ConnectedClient* client, const std::string& in, int maxlen) {
|
||||
size_t left = in.length();
|
||||
const char *buffer = in.c_str();
|
||||
|
||||
while ( left > 0 ) {
|
||||
int n;
|
||||
if ( (n = send(client->socket, buffer, left, 0)) <= 0 ) {
|
||||
int err = getSocketError();
|
||||
if (err == SERR(EINTR))
|
||||
n = 0;
|
||||
else
|
||||
return (err == SERR(EWOULDBLOCK))? 1 : -1;
|
||||
}
|
||||
left -= n;
|
||||
buffer += n;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
77
src/network/command/CommandServer.h
Executable file
77
src/network/command/CommandServer.h
Executable file
@@ -0,0 +1,77 @@
|
||||
#ifndef COMMANDSERVER_H__
|
||||
#define COMMANDSERVER_H__
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#ifdef WIN32
|
||||
#include <WinSock2.h>
|
||||
#else
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
|
||||
#include "../../world/PosTranslator.h"
|
||||
#include "../../world/Pos.h"
|
||||
|
||||
class Minecraft;
|
||||
class Packet;
|
||||
class CameraEntity;
|
||||
|
||||
class ConnectedClient {
|
||||
public:
|
||||
ConnectedClient(int socketFd)
|
||||
: socket(socketFd),
|
||||
lastPoll_blockHit(0)
|
||||
{
|
||||
}
|
||||
|
||||
int socket;
|
||||
std::string data;
|
||||
|
||||
int lastPoll_blockHit;
|
||||
};
|
||||
|
||||
class CommandServer {
|
||||
public:
|
||||
CommandServer(Minecraft* mc);
|
||||
~CommandServer();
|
||||
|
||||
bool init(short port);
|
||||
void tick();
|
||||
//void update();
|
||||
private:
|
||||
std::string parse(ConnectedClient& client, const std::string& s);
|
||||
void _close();
|
||||
|
||||
void _updateAccept();
|
||||
void _updateClients();
|
||||
// return true if client is in error/should be removed, false if not
|
||||
bool _updateClient(ConnectedClient& client);
|
||||
|
||||
bool handleCheckpoint(bool doRestore);
|
||||
|
||||
void dispatchPacket(Packet& p);
|
||||
std::string handleEventPollMessage( ConnectedClient& client, const std::string& cmd );
|
||||
std::string handleSetSetting(const std::string& setting, int value);
|
||||
|
||||
bool inited;
|
||||
int serverSocket;
|
||||
struct sockaddr_in serverAddress;
|
||||
|
||||
Minecraft* mc;
|
||||
OffsetPosTranslator apiPosTranslate;
|
||||
|
||||
static const int RestoreHeight = 48;
|
||||
unsigned char* restoreBuffer;
|
||||
Pos restorePos;
|
||||
|
||||
CameraEntity* camera;
|
||||
|
||||
std::vector<ConnectedClient> clients;
|
||||
|
||||
static const std::string Ok;
|
||||
static const std::string Fail;
|
||||
};
|
||||
|
||||
#endif /*COMMANDSERVER_H__*/
|
||||
93
src/network/packet/AddEntityPacket.h
Executable file
93
src/network/packet/AddEntityPacket.h
Executable file
@@ -0,0 +1,93 @@
|
||||
#ifndef NET_MINECRAFT_NETWORK_PACKET__AddEntityPacket_H__
|
||||
#define NET_MINECRAFT_NETWORK_PACKET__AddEntityPacket_H__
|
||||
|
||||
#include "../Packet.h"
|
||||
#include "../../world/entity/Entity.h"
|
||||
|
||||
class AddEntityPacket : public Packet
|
||||
{
|
||||
public:
|
||||
AddEntityPacket() {}
|
||||
|
||||
AddEntityPacket(const Entity* e, int data = 0)
|
||||
: entityId(e->entityId),
|
||||
type(e->getEntityTypeId()),
|
||||
x(e->x),
|
||||
y(e->y),
|
||||
z(e->z),
|
||||
_data(data)
|
||||
{
|
||||
if (hasMovementData()) {
|
||||
xd = e->xd;
|
||||
yd = e->yd;
|
||||
zd = e->zd;
|
||||
}
|
||||
}
|
||||
|
||||
void write(RakNet::BitStream* bitStream)
|
||||
{
|
||||
bitStream->Write((RakNet::MessageID)(ID_USER_PACKET_ENUM + PACKET_ADDENTITY));
|
||||
bitStream->Write(entityId);
|
||||
unsigned char bType = (unsigned char)type;
|
||||
bitStream->Write(bType);
|
||||
bitStream->Write(x);
|
||||
bitStream->Write(y);
|
||||
bitStream->Write(z);
|
||||
bitStream->Write(_data);
|
||||
|
||||
if (hasMovementData()) {
|
||||
const float M = 3.9f;
|
||||
short xa = (short)(8000.0f * Mth::clamp(xd, -M, M));
|
||||
short ya = (short)(8000.0f * Mth::clamp(yd, -M, M));
|
||||
short za = (short)(8000.0f * Mth::clamp(zd, -M, M));
|
||||
|
||||
bitStream->Write(xa);
|
||||
bitStream->Write(ya);
|
||||
bitStream->Write(za);
|
||||
}
|
||||
}
|
||||
|
||||
void read(RakNet::BitStream* bitStream)
|
||||
{
|
||||
bitStream->Read(entityId);
|
||||
unsigned char bType;
|
||||
bitStream->Read(bType);
|
||||
type = bType;
|
||||
bitStream->Read(x);
|
||||
bitStream->Read(y);
|
||||
bitStream->Read(z);
|
||||
bitStream->Read(_data);
|
||||
|
||||
if (hasMovementData()) {
|
||||
short xa, ya, za;
|
||||
bitStream->Read(xa);
|
||||
bitStream->Read(ya);
|
||||
bitStream->Read(za);
|
||||
xd = xa / 8000.0f;
|
||||
yd = ya / 8000.0f;
|
||||
zd = za / 8000.0f;
|
||||
}
|
||||
}
|
||||
|
||||
void handle(const RakNet::RakNetGUID& source, NetEventCallback* callback)
|
||||
{
|
||||
callback->handle(source, (AddEntityPacket*)this);
|
||||
}
|
||||
|
||||
bool hasMovementData() {
|
||||
return _data > 0;
|
||||
}
|
||||
int data() {
|
||||
return _data;
|
||||
}
|
||||
|
||||
public:
|
||||
int entityId;
|
||||
float x, y, z;
|
||||
float xd, yd, zd;
|
||||
int type;
|
||||
private:
|
||||
int _data;
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_NETWORK_PACKET__AddEntityPacket_H__*/
|
||||
78
src/network/packet/AddItemEntityPacket.h
Executable file
78
src/network/packet/AddItemEntityPacket.h
Executable file
@@ -0,0 +1,78 @@
|
||||
#ifndef NET_MINECRAFT_NETWORK_PACKET__AddItemEntityPacket_H__
|
||||
#define NET_MINECRAFT_NETWORK_PACKET__AddItemEntityPacket_H__
|
||||
|
||||
//package net.minecraft.network.packet;
|
||||
|
||||
#include "../Packet.h"
|
||||
#include "../../world/entity/item/ItemEntity.h"
|
||||
#include "../../world/item/ItemInstance.h"
|
||||
#include "../../util/Mth.h"
|
||||
|
||||
class AddItemEntityPacket: public Packet {
|
||||
public:
|
||||
AddItemEntityPacket() {
|
||||
}
|
||||
|
||||
AddItemEntityPacket(const ItemEntity* itemEntity)
|
||||
: id(itemEntity->entityId),
|
||||
itemId(itemEntity->item.id),
|
||||
itemCount(itemEntity->item.count),
|
||||
auxValue(itemEntity->item.getAuxValue()),
|
||||
x(itemEntity->x),
|
||||
y(itemEntity->y),
|
||||
z(itemEntity->z),
|
||||
_xa((signed char) (itemEntity->xd * 128.0)),
|
||||
_ya((signed char) (itemEntity->yd * 128.0)),
|
||||
_za((signed char) (itemEntity->zd * 128.0))
|
||||
{
|
||||
}
|
||||
|
||||
void read(RakNet::BitStream* bitStream)
|
||||
{
|
||||
bitStream->Read(id);
|
||||
bitStream->Read(itemId);
|
||||
bitStream->Read(itemCount);
|
||||
bitStream->Read(auxValue);
|
||||
bitStream->Read(x);
|
||||
bitStream->Read(y);
|
||||
bitStream->Read(z);
|
||||
bitStream->Read(_xa);
|
||||
bitStream->Read(_ya);
|
||||
bitStream->Read(_za);
|
||||
}
|
||||
|
||||
void write(RakNet::BitStream* bitStream)
|
||||
{
|
||||
bitStream->Write((RakNet::MessageID)(ID_USER_PACKET_ENUM + PACKET_ADDITEMENTITY));
|
||||
bitStream->Write(id);
|
||||
bitStream->Write(itemId);
|
||||
bitStream->Write(itemCount);
|
||||
bitStream->Write(auxValue);
|
||||
bitStream->Write(x);
|
||||
bitStream->Write(y);
|
||||
bitStream->Write(z);
|
||||
bitStream->Write(_xa);
|
||||
bitStream->Write(_ya);
|
||||
bitStream->Write(_za);
|
||||
}
|
||||
|
||||
void handle(const RakNet::RakNetGUID& source, NetEventCallback* callback)
|
||||
{
|
||||
callback->handle(source, (AddItemEntityPacket*)this);
|
||||
}
|
||||
|
||||
float xa() { return (float)(_xa) / 128.0f; }
|
||||
float ya() { return (float)(_ya) / 128.0f; }
|
||||
float za() { return (float)(_za) / 128.0f; }
|
||||
|
||||
int id;
|
||||
float x, y, z;
|
||||
|
||||
short itemId;
|
||||
short auxValue;
|
||||
unsigned char itemCount;
|
||||
private:
|
||||
signed char _xa, _ya, _za;
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_NETWORK_PACKET__AddItemEntityPacket_H__*/
|
||||
78
src/network/packet/AddMobPacket.h
Executable file
78
src/network/packet/AddMobPacket.h
Executable file
@@ -0,0 +1,78 @@
|
||||
#ifndef NET_MINECRAFT_NETWORK_PACKET__AddMobPacket_H__
|
||||
#define NET_MINECRAFT_NETWORK_PACKET__AddMobPacket_H__
|
||||
|
||||
#include "../Packet.h"
|
||||
#include "../../world/entity/Mob.h"
|
||||
#include "../../util/RakDataIO.h"
|
||||
|
||||
class AddMobPacket : public Packet
|
||||
{
|
||||
public:
|
||||
AddMobPacket()
|
||||
: _entityData(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
~AddMobPacket() {
|
||||
for (unsigned int i = 0; i < unpack.size(); ++i)
|
||||
delete unpack[i];
|
||||
}
|
||||
|
||||
AddMobPacket(const Mob* mob)
|
||||
: entityId(mob->entityId),
|
||||
type(mob->getEntityTypeId()),
|
||||
x(mob->x),
|
||||
y(mob->y),
|
||||
z(mob->z),
|
||||
xRot(mob->xRot),
|
||||
yRot(mob->yRot),
|
||||
_entityData(mob->getEntityData())
|
||||
{
|
||||
}
|
||||
|
||||
void write(RakNet::BitStream* bitStream)
|
||||
{
|
||||
bitStream->Write((RakNet::MessageID)(ID_USER_PACKET_ENUM + PACKET_ADDMOB));
|
||||
bitStream->Write(entityId);
|
||||
bitStream->Write(type);
|
||||
bitStream->Write(x);
|
||||
bitStream->Write(y);
|
||||
bitStream->Write(z);
|
||||
bitStream->Write(PacketUtil::Rot_degreesToChar(yRot));
|
||||
bitStream->Write(PacketUtil::Rot_degreesToChar(xRot));
|
||||
RakDataOutput dos(*bitStream);
|
||||
_entityData->packAll(&dos);
|
||||
}
|
||||
|
||||
void read(RakNet::BitStream* bitStream)
|
||||
{
|
||||
bitStream->Read(entityId);
|
||||
bitStream->Read(type);
|
||||
bitStream->Read(x);
|
||||
bitStream->Read(y);
|
||||
bitStream->Read(z);
|
||||
char rx, ry;
|
||||
bitStream->Read(ry);
|
||||
bitStream->Read(rx);
|
||||
RakDataInput dis(*bitStream);
|
||||
unpack = SynchedEntityData::unpack(&dis);
|
||||
yRot = PacketUtil::Rot_degreesToChar(ry);
|
||||
xRot = PacketUtil::Rot_charToDegrees(rx);
|
||||
}
|
||||
|
||||
void handle(const RakNet::RakNetGUID& source, NetEventCallback* callback)
|
||||
{
|
||||
callback->handle(source, (AddMobPacket*)this);
|
||||
}
|
||||
|
||||
public:
|
||||
int entityId;
|
||||
int type;
|
||||
float x, y, z;
|
||||
float xRot, yRot;
|
||||
SynchedEntityData::DataList unpack;
|
||||
private:
|
||||
const SynchedEntityData* _entityData;
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_NETWORK_PACKET__AddMobPacket_H__*/
|
||||
48
src/network/packet/AddPaintingPacket.h
Executable file
48
src/network/packet/AddPaintingPacket.h
Executable file
@@ -0,0 +1,48 @@
|
||||
#ifndef NET_MINECRAFT_NETWORK_PACKET__AddPaintingPacket_H__
|
||||
#define NET_MINECRAFT_NETWORK_PACKET__AddPaintingPacket_H__
|
||||
#include "../Packet.h"
|
||||
#include "../../world/entity/Painting.h"
|
||||
class AddPaintingPacket : public Packet {
|
||||
public:
|
||||
AddPaintingPacket() : entityId(0), xTile(0), yTile(0), zTile(0), dir(-1) {
|
||||
|
||||
}
|
||||
AddPaintingPacket(Painting* painting) {
|
||||
entityId = painting->entityId;
|
||||
xTile = painting->xTile;
|
||||
yTile = painting->yTile;
|
||||
zTile = painting->zTile;
|
||||
dir = painting->dir;
|
||||
motive = painting->motive->name;
|
||||
}
|
||||
void write(RakNet::BitStream* bitStream) {
|
||||
bitStream->Write((RakNet::MessageID)(ID_USER_PACKET_ENUM + PACKET_ADDPAINTING));
|
||||
bitStream->Write(entityId);
|
||||
bitStream->Write(xTile);
|
||||
bitStream->Write(yTile);
|
||||
bitStream->Write(zTile);
|
||||
bitStream->Write(dir);
|
||||
RakNet::RakString rakMotive(motive.c_str());
|
||||
bitStream->Write(rakMotive);
|
||||
}
|
||||
void read(RakNet::BitStream* bitStream) {
|
||||
bitStream->Read(entityId);
|
||||
bitStream->Read(xTile);
|
||||
bitStream->Read(yTile);
|
||||
bitStream->Read(zTile);
|
||||
bitStream->Read(dir);
|
||||
RakNet::RakString rakMotive;
|
||||
bitStream->Read(rakMotive);
|
||||
motive = std::string(rakMotive.C_String());
|
||||
}
|
||||
void handle(const RakNet::RakNetGUID& source, NetEventCallback* callback) {
|
||||
callback->handle(source, (AddPaintingPacket*)this);
|
||||
}
|
||||
public:
|
||||
int entityId;
|
||||
int xTile, yTile, zTile;
|
||||
int dir;
|
||||
std::string motive;
|
||||
};
|
||||
|
||||
#endif /* NET_MINECRAFT_NETWORK_PACKET__AddPaintingPacket_H__ */
|
||||
93
src/network/packet/AddPlayerPacket.h
Executable file
93
src/network/packet/AddPlayerPacket.h
Executable file
@@ -0,0 +1,93 @@
|
||||
#ifndef NET_MINECRAFT_NETWORK_PACKET__AddPlayerPacket_H__
|
||||
#define NET_MINECRAFT_NETWORK_PACKET__AddPlayerPacket_H__
|
||||
|
||||
#include "../Packet.h"
|
||||
#include "../../world/entity/player/Player.h"
|
||||
#include "../../world/entity/player/Inventory.h"
|
||||
|
||||
class AddPlayerPacket : public Packet
|
||||
{
|
||||
public:
|
||||
AddPlayerPacket()
|
||||
: _entityData(NULL)
|
||||
{}
|
||||
|
||||
AddPlayerPacket(const Player* p)
|
||||
: owner(p->owner),
|
||||
name(p->name.c_str()),
|
||||
entityId(p->entityId),
|
||||
x(p->x),
|
||||
y(p->y - p->heightOffset),
|
||||
z(p->z),
|
||||
xRot(p->xRot),
|
||||
yRot(p->yRot),
|
||||
carriedItemId(0),
|
||||
carriedItemAuxValue(0),
|
||||
_entityData(p->getEntityData())
|
||||
{
|
||||
if (ItemInstance* item = p->inventory->getSelected()) {
|
||||
carriedItemId = item->id;
|
||||
carriedItemAuxValue = item->getAuxValue();
|
||||
}
|
||||
}
|
||||
|
||||
~AddPlayerPacket() {
|
||||
for (unsigned int i = 0; i < unpack.size(); ++i)
|
||||
delete unpack[i];
|
||||
}
|
||||
|
||||
void write(RakNet::BitStream* bitStream)
|
||||
{
|
||||
bitStream->Write((RakNet::MessageID)(ID_USER_PACKET_ENUM + PACKET_ADDPLAYER));
|
||||
|
||||
bitStream->Write(owner);
|
||||
bitStream->Write(name);
|
||||
bitStream->Write(entityId);
|
||||
bitStream->Write(x);
|
||||
bitStream->Write(y);
|
||||
bitStream->Write(z);
|
||||
bitStream->Write(PacketUtil::Rot_degreesToChar(yRot));
|
||||
bitStream->Write(PacketUtil::Rot_degreesToChar(xRot));
|
||||
bitStream->Write(carriedItemId);
|
||||
bitStream->Write(carriedItemAuxValue);
|
||||
RakDataOutput dos(*bitStream);
|
||||
_entityData->packAll(&dos);
|
||||
}
|
||||
|
||||
void read(RakNet::BitStream* bitStream)
|
||||
{
|
||||
bitStream->Read(owner);
|
||||
bitStream->Read(name);
|
||||
bitStream->Read(entityId);
|
||||
bitStream->Read(x);
|
||||
bitStream->Read(y);
|
||||
bitStream->Read(z);
|
||||
char rx, ry;
|
||||
bitStream->Read(ry);
|
||||
bitStream->Read(rx);
|
||||
bitStream->Read(carriedItemId);
|
||||
bitStream->Read(carriedItemAuxValue);
|
||||
RakDataInput dis(*bitStream);
|
||||
unpack = SynchedEntityData::unpack(&dis);
|
||||
yRot = PacketUtil::Rot_degreesToChar(ry);
|
||||
xRot = PacketUtil::Rot_charToDegrees(rx);
|
||||
}
|
||||
|
||||
void handle(const RakNet::RakNetGUID& source, NetEventCallback* callback)
|
||||
{
|
||||
callback->handle(source, (AddPlayerPacket*)this);
|
||||
}
|
||||
|
||||
RakNet::RakNetGUID owner;
|
||||
RakNet::RakString name;
|
||||
int entityId;
|
||||
float x, y, z;
|
||||
float xRot, yRot;
|
||||
short carriedItemId;
|
||||
short carriedItemAuxValue;
|
||||
SynchedEntityData::DataList unpack;
|
||||
private:
|
||||
const SynchedEntityData* _entityData;
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_NETWORK_PACKET__AddPlayerPacket_H__*/
|
||||
67
src/network/packet/AdventureSettingsPacket.h
Executable file
67
src/network/packet/AdventureSettingsPacket.h
Executable file
@@ -0,0 +1,67 @@
|
||||
#ifndef NET_MINECRAFT_NETWORK_PACKET__AdventureSettingsPacket_H__
|
||||
#define NET_MINECRAFT_NETWORK_PACKET__AdventureSettingsPacket_H__
|
||||
|
||||
#include "../Packet.h"
|
||||
#include "../../world/level/Level.h"
|
||||
|
||||
class AdventureSettingsPacket: public Packet
|
||||
{
|
||||
public:
|
||||
enum Flags {
|
||||
WorldImmutable = 1,
|
||||
NoPvP = 2,
|
||||
NoPvM = 4,
|
||||
NoMvP = 8,
|
||||
StaticTime = 16,
|
||||
ShowNameTags = 32,
|
||||
};
|
||||
|
||||
AdventureSettingsPacket() {}
|
||||
|
||||
AdventureSettingsPacket(const AdventureSettings& settings)
|
||||
: flags(0)
|
||||
{
|
||||
set(WorldImmutable, settings.immutableWorld);
|
||||
set(NoPvP, settings.noPvP);
|
||||
set(NoPvM, settings.noPvM);
|
||||
set(NoMvP, settings.noMvP);
|
||||
set(StaticTime, !settings.doTickTime);
|
||||
set(ShowNameTags, settings.showNameTags);
|
||||
}
|
||||
|
||||
void write(RakNet::BitStream* bitStream)
|
||||
{
|
||||
bitStream->Write((RakNet::MessageID)(ID_USER_PACKET_ENUM + PACKET_ADVENTURESETTINGS));
|
||||
bitStream->Write(flags);
|
||||
}
|
||||
|
||||
void read(RakNet::BitStream* bitStream)
|
||||
{
|
||||
bitStream->Read(flags);
|
||||
}
|
||||
|
||||
void handle(const RakNet::RakNetGUID& source, NetEventCallback* callback)
|
||||
{
|
||||
callback->handle(source, (AdventureSettingsPacket*)this);
|
||||
}
|
||||
|
||||
void fillIn( AdventureSettings& adventureSettings ) const
|
||||
{
|
||||
adventureSettings.immutableWorld= isSet(WorldImmutable);
|
||||
adventureSettings.noPvP = isSet(NoPvP);
|
||||
adventureSettings.noPvM = isSet(NoPvM);
|
||||
adventureSettings.noMvP = isSet(NoMvP);
|
||||
adventureSettings.doTickTime = !isSet(StaticTime);
|
||||
adventureSettings.showNameTags = isSet(ShowNameTags);
|
||||
}
|
||||
|
||||
unsigned int flags;
|
||||
|
||||
void set(Flags flag, bool status) { status? set(flag) : clear(flag); }
|
||||
void set(Flags flag) { flags |= flag; }
|
||||
void toggle(Flags flag){ flags ^= flag; }
|
||||
void clear(Flags flag) { flags &= ~flag; }
|
||||
bool isSet(Flags flag) const { return (flags & flag) != 0; }
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_NETWORK_PACKET__AdventureSettingsPacket_H__*/
|
||||
46
src/network/packet/AnimatePacket.h
Executable file
46
src/network/packet/AnimatePacket.h
Executable file
@@ -0,0 +1,46 @@
|
||||
#ifndef NET_MINECRAFT_NETWORK_PACKET__AnimatePacket_H__
|
||||
#define NET_MINECRAFT_NETWORK_PACKET__AnimatePacket_H__
|
||||
|
||||
#include "../Packet.h"
|
||||
|
||||
class AnimatePacket: public Packet
|
||||
{
|
||||
public:
|
||||
static const int Swing = 1;
|
||||
static const int WAKE_UP = 3;
|
||||
|
||||
int entityId;
|
||||
char action;
|
||||
|
||||
AnimatePacket() {}
|
||||
|
||||
AnimatePacket(int action, int entityId)
|
||||
: action(action),
|
||||
entityId(entityId)
|
||||
{}
|
||||
AnimatePacket(int action, Entity* e)
|
||||
: action(action),
|
||||
entityId(e->entityId)
|
||||
{}
|
||||
|
||||
void write(RakNet::BitStream* bitStream)
|
||||
{
|
||||
bitStream->Write((RakNet::MessageID)(ID_USER_PACKET_ENUM + PACKET_ANIMATE));
|
||||
|
||||
bitStream->Write(action);
|
||||
bitStream->Write(entityId);
|
||||
}
|
||||
|
||||
void read(RakNet::BitStream* bitStream)
|
||||
{
|
||||
bitStream->Read(action);
|
||||
bitStream->Read(entityId);
|
||||
}
|
||||
|
||||
void handle(const RakNet::RakNetGUID& source, NetEventCallback* callback)
|
||||
{
|
||||
callback->handle(source, (AnimatePacket*)this);
|
||||
}
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_NETWORK_PACKET__AnimatePacket_H__*/
|
||||
41
src/network/packet/ChatPacket.h
Executable file
41
src/network/packet/ChatPacket.h
Executable file
@@ -0,0 +1,41 @@
|
||||
#ifndef NET_MINECRAFT_NETWORK_PACKET__ChatPacket_H__
|
||||
#define NET_MINECRAFT_NETWORK_PACKET__ChatPacket_H__
|
||||
#include "../Packet.h"
|
||||
#include "../..//world/entity/player/Player.h"
|
||||
|
||||
class ChatPacket: public Packet
|
||||
{
|
||||
public:
|
||||
static const int MAX_CHAT_LENGTH = 100;
|
||||
static const int MAX_LENGTH = MAX_CHAT_LENGTH + Player::MAX_NAME_LENGTH;
|
||||
ChatPacket() {
|
||||
}
|
||||
|
||||
ChatPacket(std::string message, bool isSystem = true) {
|
||||
if(message.length() > MAX_LENGTH) {
|
||||
message = message.substr(0, MAX_LENGTH);
|
||||
}
|
||||
this->message = message;
|
||||
this->isSystem = isSystem;
|
||||
}
|
||||
|
||||
void write(RakNet::BitStream* bitStream) {
|
||||
bitStream->Write((RakNet::MessageID)(ID_USER_PACKET_ENUM + PACKET_CHAT));
|
||||
bitStream->Write(message.c_str());
|
||||
}
|
||||
|
||||
void read(RakNet::BitStream* bitStream) {
|
||||
char buff[MAX_LENGTH + 30];
|
||||
bitStream->Read(buff);
|
||||
message = buff;
|
||||
}
|
||||
|
||||
void handle(const RakNet::RakNetGUID& source, NetEventCallback* callback) {
|
||||
callback->handle(source, (ChatPacket*)this);
|
||||
}
|
||||
|
||||
std::string message;
|
||||
bool isSystem;
|
||||
};
|
||||
|
||||
#endif /* NET_MINECRAFT_NETWORK_PACKET__ChatPacket_H__ */
|
||||
77
src/network/packet/ChunkDataPacket.h
Executable file
77
src/network/packet/ChunkDataPacket.h
Executable file
@@ -0,0 +1,77 @@
|
||||
#ifndef NET_MINECRAFT_NETWORK_PACKET__ChunkDataPacket_H__
|
||||
#define NET_MINECRAFT_NETWORK_PACKET__ChunkDataPacket_H__
|
||||
|
||||
#include "../Packet.h"
|
||||
#include "../../world/level/chunk/LevelChunk.h"
|
||||
|
||||
class ChunkDataPacket : public Packet
|
||||
{
|
||||
public:
|
||||
|
||||
int x, z;
|
||||
RakNet::BitStream chunkData;
|
||||
LevelChunk* chunk;
|
||||
|
||||
ChunkDataPacket()
|
||||
{
|
||||
}
|
||||
|
||||
ChunkDataPacket(int x, int z, LevelChunk* chunk)
|
||||
: x(x),
|
||||
z(z),
|
||||
chunk(chunk)
|
||||
{
|
||||
}
|
||||
|
||||
void write(RakNet::BitStream* bitStream)
|
||||
{
|
||||
bitStream->Write((RakNet::MessageID)(ID_USER_PACKET_ENUM + PACKET_CHUNKDATA));
|
||||
|
||||
bitStream->Write(x);
|
||||
bitStream->Write(z);
|
||||
|
||||
unsigned char* blockIds = chunk->getBlockData();
|
||||
DataLayer& blockData = chunk->data;
|
||||
|
||||
const int setSize = LEVEL_HEIGHT / 8;
|
||||
const int setShift = 4; // power of LEVEL_HEIGHT / 8
|
||||
|
||||
chunkData.Reset();
|
||||
for (int i = 0; i < CHUNK_COLUMNS; i++)
|
||||
{
|
||||
unsigned char updateBits = chunk->updateMap[i];
|
||||
chunkData.Write(updateBits);
|
||||
|
||||
if (updateBits > 0)
|
||||
{
|
||||
int colDataPosition = (i % CHUNK_WIDTH) << 11 | (i / CHUNK_WIDTH) << 7;
|
||||
|
||||
for (int set = 0; set < 8; set++)
|
||||
{
|
||||
if ((updateBits & (1 << set)) != 0)
|
||||
{
|
||||
chunkData.Write((const char*)(&blockIds[colDataPosition + (set << setShift)]), setSize);
|
||||
// block data is only 4 bits per block
|
||||
chunkData.Write((const char*)(&blockData.data[(colDataPosition + (set << setShift)) >> 1]), setSize >> 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bitStream->Write(chunkData);
|
||||
}
|
||||
|
||||
void read(RakNet::BitStream* bitStream)
|
||||
{
|
||||
bitStream->Read(x);
|
||||
bitStream->Read(z);
|
||||
bitStream->Read(chunkData);
|
||||
}
|
||||
|
||||
void handle(const RakNet::RakNetGUID& source, NetEventCallback* callback)
|
||||
{
|
||||
callback->handle(source, (ChunkDataPacket*)this);
|
||||
}
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_NETWORK_PACKET__ChunkDataPacket_H__*/
|
||||
43
src/network/packet/ContainerAckPacket.h
Executable file
43
src/network/packet/ContainerAckPacket.h
Executable file
@@ -0,0 +1,43 @@
|
||||
#ifndef NET_MINECRAFT_NETWORK_PACKET__ContainerAckPacket_H__
|
||||
#define NET_MINECRAFT_NETWORK_PACKET__ContainerAckPacket_H__
|
||||
|
||||
//package net.minecraft.network.packet;
|
||||
|
||||
#include "../Packet.h"
|
||||
|
||||
class ContainerAckPacket: public Packet
|
||||
{
|
||||
public:
|
||||
ContainerAckPacket() {
|
||||
}
|
||||
|
||||
ContainerAckPacket(int containerId, short uid, bool accepted)
|
||||
: containerId(containerId),
|
||||
uid(uid),
|
||||
accepted(accepted)
|
||||
{
|
||||
}
|
||||
|
||||
void write(RakNet::BitStream* bitStream) {
|
||||
bitStream->Write((RakNet::MessageID)(ID_USER_PACKET_ENUM + PACKET_CONTAINERACK));
|
||||
bitStream->Write(containerId);
|
||||
bitStream->Write(uid);
|
||||
bitStream->Write(accepted);
|
||||
}
|
||||
|
||||
void read(RakNet::BitStream* bitStream) {
|
||||
bitStream->Read(containerId);
|
||||
bitStream->Read(uid);
|
||||
bitStream->Read(accepted);
|
||||
}
|
||||
|
||||
void handle(const RakNet::RakNetGUID& source, NetEventCallback* callback) {
|
||||
callback->handle(source, (ContainerAckPacket*)this);
|
||||
}
|
||||
|
||||
short uid;
|
||||
unsigned char containerId;
|
||||
bool accepted;
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_NETWORK_PACKET__ContainerAckPacket_H__*/
|
||||
35
src/network/packet/ContainerClosePacket.h
Executable file
35
src/network/packet/ContainerClosePacket.h
Executable file
@@ -0,0 +1,35 @@
|
||||
#ifndef NET_MINECRAFT_NETWORK_PACKET__ContainerClosePacket_H__
|
||||
#define NET_MINECRAFT_NETWORK_PACKET__ContainerClosePacket_H__
|
||||
|
||||
//package net.minecraft.network.packet;
|
||||
|
||||
#include "../Packet.h"
|
||||
|
||||
class ContainerClosePacket: public Packet
|
||||
{
|
||||
public:
|
||||
ContainerClosePacket() {
|
||||
}
|
||||
|
||||
ContainerClosePacket(int containerId)
|
||||
: containerId(containerId)
|
||||
{
|
||||
}
|
||||
|
||||
void read(RakNet::BitStream* bitStream) {
|
||||
bitStream->Read(containerId);
|
||||
}
|
||||
|
||||
void write(RakNet::BitStream* bitStream) {
|
||||
bitStream->Write((RakNet::MessageID)(ID_USER_PACKET_ENUM + PACKET_CONTAINERCLOSE));
|
||||
bitStream->Write(containerId);
|
||||
}
|
||||
|
||||
void handle(const RakNet::RakNetGUID& source, NetEventCallback* callback) {
|
||||
callback->handle(source, (ContainerClosePacket*)this);
|
||||
}
|
||||
|
||||
unsigned char containerId;
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_NETWORK_PACKET__ContainerClosePacket_H__*/
|
||||
47
src/network/packet/ContainerOpenPacket.h
Executable file
47
src/network/packet/ContainerOpenPacket.h
Executable file
@@ -0,0 +1,47 @@
|
||||
#ifndef NET_MINECRAFT_NETWORK_PACKET__ContainerOpenPacket_H__
|
||||
#define NET_MINECRAFT_NETWORK_PACKET__ContainerOpenPacket_H__
|
||||
|
||||
//package net.minecraft.network.packet;
|
||||
|
||||
#include "../Packet.h"
|
||||
|
||||
class ContainerOpenPacket: public Packet
|
||||
{
|
||||
public:
|
||||
ContainerOpenPacket() {
|
||||
}
|
||||
|
||||
ContainerOpenPacket(int containerId, int type, const std::string& title, int size)
|
||||
: containerId(containerId),
|
||||
type(type),
|
||||
title(title.c_str()),
|
||||
size(size)
|
||||
{
|
||||
}
|
||||
|
||||
void write(RakNet::BitStream* bitStream) {
|
||||
bitStream->Write((RakNet::MessageID)(ID_USER_PACKET_ENUM + PACKET_CONTAINEROPEN));
|
||||
bitStream->Write(containerId);
|
||||
bitStream->Write(type);
|
||||
bitStream->Write(size);
|
||||
bitStream->Write(title);
|
||||
}
|
||||
|
||||
void read(RakNet::BitStream* bitStream) {
|
||||
bitStream->Read(containerId);
|
||||
bitStream->Read(type);
|
||||
bitStream->Read(size);
|
||||
bitStream->Read(title);
|
||||
}
|
||||
|
||||
void handle(const RakNet::RakNetGUID& source, NetEventCallback* callback) {
|
||||
callback->handle(source, (ContainerOpenPacket*)this);
|
||||
}
|
||||
|
||||
RakNet::RakString title;
|
||||
unsigned char containerId;
|
||||
unsigned char type;
|
||||
unsigned char size;
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_NETWORK_PACKET__ContainerOpenPacket_H__*/
|
||||
44
src/network/packet/ContainerSetContentPacket.h
Executable file
44
src/network/packet/ContainerSetContentPacket.h
Executable file
@@ -0,0 +1,44 @@
|
||||
#ifndef NET_MINECRAFT_NETWORK_PACKET__ContainerSetContentPacket_H__
|
||||
#define NET_MINECRAFT_NETWORK_PACKET__ContainerSetContentPacket_H__
|
||||
|
||||
//package net.minecraft.network.packet;
|
||||
|
||||
#include "../Packet.h"
|
||||
|
||||
class ContainerSetContentPacket: public Packet
|
||||
{
|
||||
public:
|
||||
ContainerSetContentPacket() {
|
||||
}
|
||||
|
||||
ContainerSetContentPacket(int containerId, const std::vector<ItemInstance>& newItems)
|
||||
: containerId(containerId),
|
||||
items(newItems.begin(), newItems.end())
|
||||
{
|
||||
}
|
||||
|
||||
void write(RakNet::BitStream* bitStream) {
|
||||
bitStream->Write((RakNet::MessageID)(ID_USER_PACKET_ENUM + PACKET_CONTAINERSETCONTENT));
|
||||
bitStream->Write(containerId);
|
||||
bitStream->Write((short)items.size());
|
||||
for (unsigned int i = 0; i < items.size(); ++i)
|
||||
PacketUtil::writeItemInstance(items[i], bitStream);
|
||||
}
|
||||
|
||||
void read(RakNet::BitStream* bitStream) {
|
||||
bitStream->Read(containerId);
|
||||
short numItems;
|
||||
bitStream->Read(numItems);
|
||||
for (int i = 0; i < numItems; ++i)
|
||||
items.push_back( PacketUtil::readItemInstance(bitStream) );
|
||||
}
|
||||
|
||||
void handle(const RakNet::RakNetGUID& source, NetEventCallback* callback) {
|
||||
callback->handle(source, (ContainerSetContentPacket*)this);
|
||||
}
|
||||
|
||||
unsigned char containerId;
|
||||
std::vector<ItemInstance> items;
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_NETWORK_PACKET__ContainerSetContentPacket_H__*/
|
||||
43
src/network/packet/ContainerSetDataPacket.h
Executable file
43
src/network/packet/ContainerSetDataPacket.h
Executable file
@@ -0,0 +1,43 @@
|
||||
#ifndef NET_MINECRAFT_NETWORK_PACKET__ContainerSetDataPacket_H__
|
||||
#define NET_MINECRAFT_NETWORK_PACKET__ContainerSetDataPacket_H__
|
||||
|
||||
//package net.minecraft.network.packet;
|
||||
|
||||
#include "../Packet.h"
|
||||
|
||||
class ContainerSetDataPacket: public Packet
|
||||
{
|
||||
public:
|
||||
ContainerSetDataPacket() {
|
||||
}
|
||||
|
||||
ContainerSetDataPacket(int containerId, int id, int value)
|
||||
: containerId(containerId),
|
||||
id(id),
|
||||
value(value)
|
||||
{
|
||||
}
|
||||
|
||||
void write(RakNet::BitStream* bitStream) {
|
||||
bitStream->Write((RakNet::MessageID)(ID_USER_PACKET_ENUM + PACKET_CONTAINERSETDATA));
|
||||
bitStream->Write(containerId);
|
||||
bitStream->Write(id);
|
||||
bitStream->Write(value);
|
||||
}
|
||||
|
||||
void read(RakNet::BitStream* bitStream) {
|
||||
bitStream->Read(containerId);
|
||||
bitStream->Read(id);
|
||||
bitStream->Read(value);
|
||||
}
|
||||
|
||||
void handle(const RakNet::RakNetGUID& source, NetEventCallback* callback) {
|
||||
callback->handle(source, (ContainerSetDataPacket*)this);
|
||||
}
|
||||
|
||||
short id;
|
||||
short value;
|
||||
unsigned char containerId;
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_NETWORK_PACKET__ContainerSetDataPacket_H__*/
|
||||
64
src/network/packet/ContainerSetSlotPacket.h
Executable file
64
src/network/packet/ContainerSetSlotPacket.h
Executable file
@@ -0,0 +1,64 @@
|
||||
#ifndef NET_MINECRAFT_NETWORK_PACKET__ContainerSetSlotPacket_H__
|
||||
#define NET_MINECRAFT_NETWORK_PACKET__ContainerSetSlotPacket_H__
|
||||
|
||||
//package net.minecraft.network.packet;
|
||||
|
||||
#include "../Packet.h"
|
||||
#include "../../world/item/ItemInstance.h"
|
||||
|
||||
// Note: This can be seen as "ContainerWantSetSlotPacket" when sent from
|
||||
// client to server. Currently, the client handles side-effects relating
|
||||
// to it's own inventory, regardless of the success of the operation.
|
||||
class ContainerSetSlotPacket: public Packet
|
||||
{
|
||||
public:
|
||||
static const char SETTYPE_SET = 0;
|
||||
static const char SETTYPE_ADD = 1;
|
||||
//static const int SETTYPE_SUB = 2;
|
||||
static const char SETTYPE_TAKE = 5;
|
||||
|
||||
ContainerSetSlotPacket() {
|
||||
}
|
||||
|
||||
//@todo: pointer parameter?
|
||||
ContainerSetSlotPacket(int containerId, int slot, const ItemInstance& item)
|
||||
: containerId(containerId),
|
||||
slot(slot),
|
||||
item(item),
|
||||
setType(SETTYPE_SET)
|
||||
//item(item? *item : ItemInstance())
|
||||
{
|
||||
}
|
||||
ContainerSetSlotPacket(char setType, int containerId, int slot, const ItemInstance& item)
|
||||
: setType(setType),
|
||||
containerId(containerId),
|
||||
slot(slot),
|
||||
item(item)
|
||||
//item(item? *item : ItemInstance())
|
||||
{
|
||||
}
|
||||
|
||||
void write(RakNet::BitStream* bitStream) {
|
||||
bitStream->Write((RakNet::MessageID)(ID_USER_PACKET_ENUM + PACKET_CONTAINERSETSLOT));
|
||||
bitStream->Write(containerId);
|
||||
bitStream->Write(slot);
|
||||
PacketUtil::writeItemInstance(item, bitStream);
|
||||
}
|
||||
|
||||
void read(RakNet::BitStream* bitStream) {
|
||||
bitStream->Read(containerId);
|
||||
bitStream->Read(slot);
|
||||
item = PacketUtil::readItemInstance(bitStream);
|
||||
}
|
||||
|
||||
void handle(const RakNet::RakNetGUID& source, NetEventCallback* callback) {
|
||||
callback->handle(source, (ContainerSetSlotPacket*)this);
|
||||
}
|
||||
|
||||
unsigned char setType;
|
||||
unsigned char containerId;
|
||||
short slot;
|
||||
ItemInstance item;
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_NETWORK_PACKET__ContainerSetSlotPacket_H__*/
|
||||
45
src/network/packet/DropItemPacket.h
Executable file
45
src/network/packet/DropItemPacket.h
Executable file
@@ -0,0 +1,45 @@
|
||||
#ifndef NET_MINECRAFT_NETWORK_PACKET__DropItemPacket_H__
|
||||
#define NET_MINECRAFT_NETWORK_PACKET__DropItemPacket_H__
|
||||
|
||||
#include "../Packet.h"
|
||||
|
||||
class DropItemPacket: public Packet
|
||||
{
|
||||
public:
|
||||
DropItemPacket()
|
||||
{
|
||||
}
|
||||
|
||||
DropItemPacket(int entityId, const ItemInstance& item)
|
||||
: entityId(entityId),
|
||||
item(item),
|
||||
dropType(0)
|
||||
{
|
||||
}
|
||||
|
||||
void write(RakNet::BitStream* bitStream)
|
||||
{
|
||||
bitStream->Write((RakNet::MessageID)(ID_USER_PACKET_ENUM + PACKET_DROPITEM));
|
||||
bitStream->Write(entityId);
|
||||
bitStream->Write(dropType);
|
||||
PacketUtil::writeItemInstance(item, bitStream);
|
||||
}
|
||||
|
||||
void read(RakNet::BitStream* bitStream)
|
||||
{
|
||||
bitStream->Read(entityId);
|
||||
bitStream->Read(dropType);
|
||||
item = PacketUtil::readItemInstance(bitStream);
|
||||
}
|
||||
|
||||
void handle(const RakNet::RakNetGUID& source, NetEventCallback* callback)
|
||||
{
|
||||
callback->handle(source, (DropItemPacket*)this);
|
||||
}
|
||||
|
||||
int entityId;
|
||||
unsigned char dropType;
|
||||
ItemInstance item;
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_NETWORK_PACKET__DropItemPacket_H__*/
|
||||
40
src/network/packet/EntityEventPacket.h
Executable file
40
src/network/packet/EntityEventPacket.h
Executable file
@@ -0,0 +1,40 @@
|
||||
#ifndef NET_MINECRAFT_NETWORK_PACKET__EntityEventPacket_H__
|
||||
#define NET_MINECRAFT_NETWORK_PACKET__EntityEventPacket_H__
|
||||
|
||||
//package net.minecraft.network.packet;
|
||||
|
||||
#include "../Packet.h"
|
||||
|
||||
class EntityEventPacket: public Packet {
|
||||
public:
|
||||
EntityEventPacket() {}
|
||||
|
||||
EntityEventPacket(int entityId, char eventId)
|
||||
: entityId(entityId),
|
||||
eventId(eventId)
|
||||
{}
|
||||
|
||||
void write(RakNet::BitStream* bitStream)
|
||||
{
|
||||
bitStream->Write((RakNet::MessageID)(ID_USER_PACKET_ENUM + PACKET_ENTITYEVENT));
|
||||
bitStream->Write(entityId);
|
||||
bitStream->Write(eventId);
|
||||
}
|
||||
|
||||
void read(RakNet::BitStream* bitStream)
|
||||
{
|
||||
bitStream->Read(entityId);
|
||||
bitStream->Read(eventId);
|
||||
}
|
||||
|
||||
void handle(const RakNet::RakNetGUID& source, NetEventCallback* callback)
|
||||
{
|
||||
callback->handle(source, (EntityEventPacket*)this);
|
||||
}
|
||||
|
||||
int entityId;
|
||||
unsigned char eventId;
|
||||
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_NETWORK_PACKET__EntityEventPacket_H__*/
|
||||
76
src/network/packet/ExplodePacket.h
Executable file
76
src/network/packet/ExplodePacket.h
Executable file
@@ -0,0 +1,76 @@
|
||||
#ifndef NET_MINECRAFT_NETWORK_PACKET__ExplodePacket_H__
|
||||
#define NET_MINECRAFT_NETWORK_PACKET__ExplodePacket_H__
|
||||
|
||||
//package net.minecraft.network.packet;
|
||||
|
||||
#include "../Packet.h"
|
||||
#include "../../world/level/Explosion.h"
|
||||
|
||||
class ExplodePacket: public Packet
|
||||
{
|
||||
public:
|
||||
float x, y, z;
|
||||
float r;
|
||||
std::vector<TilePos> toBlow;
|
||||
|
||||
ExplodePacket() {}
|
||||
|
||||
ExplodePacket(float x, float y, float z, float r, const TilePosSet& tiles)
|
||||
: x(x),
|
||||
y(y),
|
||||
z(z),
|
||||
r(r),
|
||||
toBlow(tiles.begin(), tiles.end())
|
||||
{}
|
||||
|
||||
void write(RakNet::BitStream* bitStream)
|
||||
{
|
||||
bitStream->Write((RakNet::MessageID)(ID_USER_PACKET_ENUM + PACKET_EXPLODE));
|
||||
bitStream->Write(x);
|
||||
bitStream->Write(y);
|
||||
bitStream->Write(z);
|
||||
bitStream->Write(r);
|
||||
int xp = (int)x;
|
||||
int yp = (int)y;
|
||||
int zp = (int)z;
|
||||
|
||||
int count = (int)toBlow.size();
|
||||
bitStream->Write(count);
|
||||
for (int i = 0; i < count; ++i) {
|
||||
const TilePos& tp = toBlow[i];
|
||||
bitStream->Write((signed char)(tp.x - xp));
|
||||
bitStream->Write((signed char)(tp.y - yp));
|
||||
bitStream->Write((signed char)(tp.z - zp));
|
||||
}
|
||||
}
|
||||
|
||||
void read(RakNet::BitStream* bitStream)
|
||||
{
|
||||
bitStream->Read(x);
|
||||
bitStream->Read(y);
|
||||
bitStream->Read(z);
|
||||
bitStream->Read(r);
|
||||
int xp = (int)x;
|
||||
int yp = (int)y;
|
||||
int zp = (int)z;
|
||||
|
||||
// Write the tileset for the exploded tiles
|
||||
int count;
|
||||
bitStream->Read(count);
|
||||
toBlow.reserve(count);
|
||||
for (int i = 0; i < count; ++i) {
|
||||
signed char xx,yy,zz;
|
||||
bitStream->Read(xx);
|
||||
bitStream->Read(yy);
|
||||
bitStream->Read(zz);
|
||||
toBlow.push_back( TilePos(xp + xx, yp + yy, zp + zz) );
|
||||
}
|
||||
}
|
||||
|
||||
void handle(const RakNet::RakNetGUID& source, NetEventCallback* callback)
|
||||
{
|
||||
callback->handle(source, (ExplodePacket*)this);
|
||||
}
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_NETWORK_PACKET__ExplodePacket_H__*/
|
||||
32
src/network/packet/HurtArmorPacket.h
Executable file
32
src/network/packet/HurtArmorPacket.h
Executable file
@@ -0,0 +1,32 @@
|
||||
#ifndef NET_MINECRAFT_NETWORK_PACKET__HurtArmorPacket_H__
|
||||
#define NET_MINECRAFT_NETWORK_PACKET__HurtArmorPacket_H__
|
||||
|
||||
#include "../Packet.h"
|
||||
|
||||
class HurtArmorPacket: public Packet
|
||||
{
|
||||
public:
|
||||
HurtArmorPacket() {}
|
||||
|
||||
HurtArmorPacket(int dmg)
|
||||
: dmg(dmg)
|
||||
{}
|
||||
|
||||
void write(RakNet::BitStream* bitStream) {
|
||||
bitStream->Write((RakNet::MessageID)(ID_USER_PACKET_ENUM + PACKET_HURTARMOR));
|
||||
|
||||
bitStream->Write(dmg);
|
||||
}
|
||||
|
||||
void read(RakNet::BitStream* bitStream) {
|
||||
bitStream->Read(dmg);
|
||||
}
|
||||
|
||||
void handle(const RakNet::RakNetGUID& source, NetEventCallback* callback) {
|
||||
callback->handle(source, (HurtArmorPacket*)this);
|
||||
}
|
||||
|
||||
signed char dmg;
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_NETWORK_PACKET__HurtArmorPacket_H__*/
|
||||
47
src/network/packet/InteractPacket.h
Executable file
47
src/network/packet/InteractPacket.h
Executable file
@@ -0,0 +1,47 @@
|
||||
#ifndef NET_MINECRAFT_NETWORK_PACKET__InteractPacket_H__
|
||||
#define NET_MINECRAFT_NETWORK_PACKET__InteractPacket_H__
|
||||
|
||||
#include "../Packet.h"
|
||||
|
||||
class InteractPacket : public Packet
|
||||
{
|
||||
public:
|
||||
static const int Interact = 1;
|
||||
static const int Attack = 2;
|
||||
|
||||
char action;
|
||||
int sourceId;
|
||||
int targetId;
|
||||
|
||||
InteractPacket() {
|
||||
}
|
||||
|
||||
InteractPacket(char action, int sourceId, int targetId)
|
||||
: action(action),
|
||||
sourceId(sourceId),
|
||||
targetId(targetId)
|
||||
{}
|
||||
|
||||
void write(RakNet::BitStream* bitStream)
|
||||
{
|
||||
bitStream->Write((RakNet::MessageID)(ID_USER_PACKET_ENUM + PACKET_INTERACT));
|
||||
|
||||
bitStream->Write(action);
|
||||
bitStream->Write(sourceId);
|
||||
bitStream->Write(targetId);
|
||||
}
|
||||
|
||||
void read(RakNet::BitStream* bitStream)
|
||||
{
|
||||
bitStream->Read(action);
|
||||
bitStream->Read(sourceId);
|
||||
bitStream->Read(targetId);
|
||||
}
|
||||
|
||||
void handle(const RakNet::RakNetGUID& source, NetEventCallback* callback)
|
||||
{
|
||||
callback->handle(source, (InteractPacket*)this);
|
||||
}
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_NETWORK_PACKET__InteractPacket_H__*/
|
||||
49
src/network/packet/LevelEventPacket.h
Executable file
49
src/network/packet/LevelEventPacket.h
Executable file
@@ -0,0 +1,49 @@
|
||||
#ifndef NET_MINECRAFT_NETWORK_PACKET__LevelEventPacket_H__
|
||||
#define NET_MINECRAFT_NETWORK_PACKET__LevelEventPacket_H__
|
||||
|
||||
//package net.minecraft.network.packet;
|
||||
|
||||
#include "../Packet.h"
|
||||
|
||||
class LevelEventPacket: public Packet {
|
||||
public:
|
||||
LevelEventPacket() {}
|
||||
|
||||
LevelEventPacket(int eventId, int x, int y, int z, int data)
|
||||
: eventId(eventId),
|
||||
x(x),
|
||||
y(y),
|
||||
z(z),
|
||||
data(data)
|
||||
{}
|
||||
|
||||
void write(RakNet::BitStream* bitStream)
|
||||
{
|
||||
bitStream->Write((RakNet::MessageID)(ID_USER_PACKET_ENUM + PACKET_LEVELEVENT));
|
||||
bitStream->Write(eventId);
|
||||
bitStream->Write(x);
|
||||
bitStream->Write(y);
|
||||
bitStream->Write(z);
|
||||
bitStream->Write(data);
|
||||
}
|
||||
|
||||
void read(RakNet::BitStream* bitStream)
|
||||
{
|
||||
bitStream->Read(eventId);
|
||||
bitStream->Read(x);
|
||||
bitStream->Read(y);
|
||||
bitStream->Read(z);
|
||||
bitStream->Read(data);
|
||||
}
|
||||
|
||||
void handle(const RakNet::RakNetGUID& source, NetEventCallback* callback)
|
||||
{
|
||||
callback->handle(source, (LevelEventPacket*)this);
|
||||
}
|
||||
|
||||
short eventId;
|
||||
short x, y, z;
|
||||
int data;
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_NETWORK_PACKET__LevelEventPacket_H__*/
|
||||
51
src/network/packet/LoginPacket.h
Executable file
51
src/network/packet/LoginPacket.h
Executable file
@@ -0,0 +1,51 @@
|
||||
#ifndef NET_MINECRAFT_NETWORK_PACKET__LoginPacket_H__
|
||||
#define NET_MINECRAFT_NETWORK_PACKET__LoginPacket_H__
|
||||
|
||||
#include "../Packet.h"
|
||||
|
||||
class LoginPacket : public Packet
|
||||
{
|
||||
public:
|
||||
RakNet::RakString clientName;
|
||||
int clientNetworkVersion;
|
||||
int clientNetworkLowestSupportedVersion;
|
||||
|
||||
LoginPacket()
|
||||
: clientNetworkVersion(-1),
|
||||
clientNetworkLowestSupportedVersion(-1)
|
||||
{
|
||||
}
|
||||
|
||||
LoginPacket(const RakNet::RakString& clientName, int clientVersion)
|
||||
: clientName(clientName),
|
||||
clientNetworkVersion(clientVersion),
|
||||
clientNetworkLowestSupportedVersion(clientVersion)
|
||||
{
|
||||
}
|
||||
|
||||
void write(RakNet::BitStream* bitStream)
|
||||
{
|
||||
bitStream->Write((RakNet::MessageID)(ID_USER_PACKET_ENUM + PACKET_LOGIN));
|
||||
bitStream->Write(clientName);
|
||||
bitStream->Write(clientNetworkVersion);
|
||||
bitStream->Write(clientNetworkLowestSupportedVersion);
|
||||
}
|
||||
|
||||
void read(RakNet::BitStream* bitStream)
|
||||
{
|
||||
bitStream->Read(clientName);
|
||||
// First versions didn't send the client version
|
||||
//LOGI("unread: %d\n", bitStream->GetNumberOfUnreadBits());
|
||||
if (bitStream->GetNumberOfUnreadBits() > 0) {
|
||||
bitStream->Read(clientNetworkVersion);
|
||||
bitStream->Read(clientNetworkLowestSupportedVersion);
|
||||
}
|
||||
}
|
||||
|
||||
void handle(const RakNet::RakNetGUID& source, NetEventCallback* callback)
|
||||
{
|
||||
callback->handle(source, (LoginPacket*)this);
|
||||
}
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_NETWORK_PACKET__LoginPacket_H__*/
|
||||
40
src/network/packet/LoginStatusPacket.h
Executable file
40
src/network/packet/LoginStatusPacket.h
Executable file
@@ -0,0 +1,40 @@
|
||||
#ifndef NET_MINECRAFT_NETWORK_PACKET__LoginStatusPacket_H__
|
||||
#define NET_MINECRAFT_NETWORK_PACKET__LoginStatusPacket_H__
|
||||
|
||||
#include "../Packet.h"
|
||||
|
||||
namespace LoginStatus {
|
||||
const int Success = 0;
|
||||
const int Failed_ClientOld = 1;
|
||||
const int Failed_ServerOld = 2;
|
||||
}
|
||||
|
||||
class LoginStatusPacket : public Packet {
|
||||
public:
|
||||
LoginStatusPacket()
|
||||
{
|
||||
}
|
||||
LoginStatusPacket(int status)
|
||||
: status(status)
|
||||
{}
|
||||
|
||||
void write(RakNet::BitStream* bitStream)
|
||||
{
|
||||
bitStream->Write((RakNet::MessageID)(ID_USER_PACKET_ENUM + PACKET_LOGINSTATUS));
|
||||
bitStream->Write(status);
|
||||
}
|
||||
|
||||
void read(RakNet::BitStream* bitStream)
|
||||
{
|
||||
bitStream->Read(status);
|
||||
}
|
||||
|
||||
void handle(const RakNet::RakNetGUID& source, NetEventCallback* callback)
|
||||
{
|
||||
callback->handle(source, (LoginStatusPacket*)this);
|
||||
}
|
||||
|
||||
int status;
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_NETWORK_PACKET__LoginStatusPacket_H__*/
|
||||
39
src/network/packet/MessagePacket.h
Executable file
39
src/network/packet/MessagePacket.h
Executable file
@@ -0,0 +1,39 @@
|
||||
#ifndef NET_MINECRAFT_NETWORK_PACKET__MessagePacket_H__
|
||||
#define NET_MINECRAFT_NETWORK_PACKET__MessagePacket_H__
|
||||
|
||||
#include "../Packet.h"
|
||||
|
||||
class MessagePacket : public Packet
|
||||
{
|
||||
public:
|
||||
|
||||
RakNet::RakString message;
|
||||
|
||||
MessagePacket()
|
||||
{
|
||||
}
|
||||
|
||||
MessagePacket(const RakNet::RakString& message)
|
||||
: message(message)
|
||||
{
|
||||
}
|
||||
|
||||
void write(RakNet::BitStream* bitStream)
|
||||
{
|
||||
bitStream->Write((RakNet::MessageID)(ID_USER_PACKET_ENUM + PACKET_MESSAGE));
|
||||
|
||||
bitStream->Write(message);
|
||||
}
|
||||
|
||||
void read(RakNet::BitStream* bitStream)
|
||||
{
|
||||
bitStream->Read(message);
|
||||
}
|
||||
|
||||
void handle(const RakNet::RakNetGUID& source, NetEventCallback* callback)
|
||||
{
|
||||
callback->handle(source, (MessagePacket*)this);
|
||||
}
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_NETWORK_PACKET__MessagePacket_H__*/
|
||||
78
src/network/packet/MoveEntityPacket.h
Executable file
78
src/network/packet/MoveEntityPacket.h
Executable file
@@ -0,0 +1,78 @@
|
||||
#ifndef NET_MINECRAFT_NETWORK_PACKET__MoveEntityPacket_H__
|
||||
#define NET_MINECRAFT_NETWORK_PACKET__MoveEntityPacket_H__
|
||||
|
||||
#include "../Packet.h"
|
||||
|
||||
class MoveEntityPacket: public Packet
|
||||
{
|
||||
public:
|
||||
MoveEntityPacket()
|
||||
: hasRot(false)
|
||||
{}
|
||||
|
||||
// PACKET_MOVEENTITY is unknown and undefined (and not used)
|
||||
void write(RakNet::BitStream* bitStream) {
|
||||
bitStream->Write((RakNet::MessageID)(ID_USER_PACKET_ENUM + PACKET_MOVEENTITY));
|
||||
}
|
||||
|
||||
void read(RakNet::BitStream* bitStream) {};
|
||||
|
||||
void handle(const RakNet::RakNetGUID& source, NetEventCallback* callback)
|
||||
{
|
||||
callback->handle(source, (MoveEntityPacket*)this);
|
||||
}
|
||||
|
||||
int entityId;
|
||||
float x, y, z;
|
||||
float xRot;
|
||||
float yRot;
|
||||
bool hasRot;
|
||||
};
|
||||
|
||||
class MoveEntityPacket_PosRot: public MoveEntityPacket
|
||||
{
|
||||
typedef MoveEntityPacket super;
|
||||
public:
|
||||
MoveEntityPacket_PosRot() {
|
||||
hasRot = true;
|
||||
}
|
||||
|
||||
//MoveEntityPacket_PosRot(int entityId, float x, float y, float z, float yRot, float xRot) {
|
||||
// set(entityId, x, y, z, yRot, xRot);
|
||||
//}
|
||||
|
||||
MoveEntityPacket_PosRot(const Entity* e) {
|
||||
set(e->entityId, e->x, e->y - e->heightOffset, e->z, e->yRot, e->xRot);
|
||||
}
|
||||
|
||||
void set(int entityId, float x, float y, float z, float yRot, float xRot) {
|
||||
this->entityId = entityId;
|
||||
this->x = x;
|
||||
this->y = y;
|
||||
this->z = z;
|
||||
this->xRot = xRot;
|
||||
this->yRot = yRot;
|
||||
}
|
||||
|
||||
void write(RakNet::BitStream* bitStream) {
|
||||
bitStream->Write((RakNet::MessageID)(ID_USER_PACKET_ENUM + PACKET_MOVEENTITY_POSROT));
|
||||
|
||||
bitStream->Write(entityId);
|
||||
bitStream->Write(x);
|
||||
bitStream->Write(y);
|
||||
bitStream->Write(z);
|
||||
bitStream->Write(yRot);
|
||||
bitStream->Write(xRot);
|
||||
}
|
||||
|
||||
void read(RakNet::BitStream* bitStream) {
|
||||
bitStream->Read(entityId);
|
||||
bitStream->Read(x);
|
||||
bitStream->Read(y);
|
||||
bitStream->Read(z);
|
||||
bitStream->Read(yRot);
|
||||
bitStream->Read(xRot);
|
||||
}
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_NETWORK_PACKET__MoveEntityPacket_H__*/
|
||||
54
src/network/packet/MovePlayerPacket.h
Executable file
54
src/network/packet/MovePlayerPacket.h
Executable file
@@ -0,0 +1,54 @@
|
||||
#ifndef NET_MINECRAFT_NETWORK_PACKET__MovePlayerPacket_H__
|
||||
#define NET_MINECRAFT_NETWORK_PACKET__MovePlayerPacket_H__
|
||||
|
||||
#include "../Packet.h"
|
||||
|
||||
class MovePlayerPacket : public Packet
|
||||
{
|
||||
public:
|
||||
|
||||
int entityId;
|
||||
float x, y, z, xRot, yRot;
|
||||
|
||||
MovePlayerPacket()
|
||||
{
|
||||
}
|
||||
|
||||
MovePlayerPacket(int entityId, float x, float y, float z, float xRot, float yRot)
|
||||
: entityId(entityId),
|
||||
x(x),
|
||||
y(y),
|
||||
z(z),
|
||||
xRot(xRot),
|
||||
yRot(yRot)
|
||||
{}
|
||||
|
||||
void write(RakNet::BitStream* bitStream)
|
||||
{
|
||||
bitStream->Write((RakNet::MessageID)(ID_USER_PACKET_ENUM + PACKET_MOVEPLAYER));
|
||||
|
||||
bitStream->Write(entityId);
|
||||
bitStream->Write(x);
|
||||
bitStream->Write(y);
|
||||
bitStream->Write(z);
|
||||
bitStream->Write(yRot);
|
||||
bitStream->Write(xRot);
|
||||
}
|
||||
|
||||
void read(RakNet::BitStream* bitStream)
|
||||
{
|
||||
bitStream->Read(entityId);
|
||||
bitStream->Read(x);
|
||||
bitStream->Read(y);
|
||||
bitStream->Read(z);
|
||||
bitStream->Read(yRot);
|
||||
bitStream->Read(xRot);
|
||||
}
|
||||
|
||||
void handle(const RakNet::RakNetGUID& source, NetEventCallback* callback)
|
||||
{
|
||||
callback->handle(source, (MovePlayerPacket*)this);
|
||||
}
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_NETWORK_PACKET__MovePlayerPacket_H__*/
|
||||
54
src/network/packet/PacketInclude.h
Executable file
54
src/network/packet/PacketInclude.h
Executable file
@@ -0,0 +1,54 @@
|
||||
#ifndef NET_MINECRAFT_NETWORK_PACKET__PacketInclude_H__
|
||||
#define NET_MINECRAFT_NETWORK_PACKET__PacketInclude_H__
|
||||
|
||||
#include "AddEntityPacket.h"
|
||||
#include "AddItemEntityPacket.h"
|
||||
#include "AddMobPacket.h"
|
||||
#include "AddPaintingPacket.h"
|
||||
#include "AddPlayerPacket.h"
|
||||
#include "AnimatePacket.h"
|
||||
#include "AdventureSettingsPacket.h"
|
||||
#include "ChatPacket.h"
|
||||
#include "ContainerAckPacket.h"
|
||||
#include "ContainerOpenPacket.h"
|
||||
#include "ContainerClosePacket.h"
|
||||
#include "ContainerSetDataPacket.h"
|
||||
#include "ContainerSetSlotPacket.h"
|
||||
#include "ContainerSetContentPacket.h"
|
||||
#include "ChunkDataPacket.h"
|
||||
#include "DropItemPacket.h"
|
||||
#include "EntityEventPacket.h"
|
||||
#include "ExplodePacket.h"
|
||||
#include "HurtArmorPacket.h"
|
||||
#include "InteractPacket.h"
|
||||
#include "LevelEventPacket.h"
|
||||
#include "LoginPacket.h"
|
||||
#include "LoginStatusPacket.h"
|
||||
#include "MessagePacket.h"
|
||||
#include "MoveEntityPacket.h"
|
||||
#include "MovePlayerPacket.h"
|
||||
#include "PlaceBlockPacket.h"
|
||||
#include "PlayerActionPacket.h"
|
||||
#include "PlayerEquipmentPacket.h"
|
||||
#include "PlayerArmorEquipmentPacket.h"
|
||||
#include "ReadyPacket.h"
|
||||
#include "RemoveBlockPacket.h"
|
||||
#include "RemoveEntityPacket.h"
|
||||
#include "RemovePlayerPacket.h"
|
||||
#include "RespawnPacket.h"
|
||||
#include "RequestChunkPacket.h"
|
||||
#include "SendInventoryPacket.h"
|
||||
#include "SetEntityDataPacket.h"
|
||||
#include "SetEntityMotionPacket.h"
|
||||
#include "SetHealthPacket.h"
|
||||
#include "SetSpawnPositionPacket.h"
|
||||
#include "SetTimePacket.h"
|
||||
#include "SignUpdatePacket.h"
|
||||
#include "StartGamePacket.h"
|
||||
#include "TakeItemEntityPacket.h"
|
||||
//#include "TeleportEntityPacket.h"
|
||||
#include "TileEventPacket.h"
|
||||
#include "UpdateBlockPacket.h"
|
||||
#include "UseItemPacket.h"
|
||||
|
||||
#endif /*NET_MINECRAFT_NETWORK_PACKET__PacketInclude_H__*/
|
||||
60
src/network/packet/PlaceBlockPacket.h
Executable file
60
src/network/packet/PlaceBlockPacket.h
Executable file
@@ -0,0 +1,60 @@
|
||||
#ifndef NET_MINECRAFT_NETWORK_PACKET__PlaceBlockPacket_H__
|
||||
#define NET_MINECRAFT_NETWORK_PACKET__PlaceBlockPacket_H__
|
||||
|
||||
#include "../Packet.h"
|
||||
|
||||
class PlaceBlockPacket : public Packet
|
||||
{
|
||||
public:
|
||||
|
||||
// the id of the player who is placing the block, used to animate the player
|
||||
int entityId;
|
||||
int x, z;
|
||||
unsigned char y, facing, blockId, blockData;
|
||||
|
||||
PlaceBlockPacket()
|
||||
{
|
||||
}
|
||||
|
||||
PlaceBlockPacket(int entityId, int x, int y, int z, int facing, int blockId, int blockData)
|
||||
: entityId(entityId),
|
||||
x(x),
|
||||
y((unsigned char)(y & 0xff)),
|
||||
z(z),
|
||||
facing ((unsigned char)(facing & 0xff)),
|
||||
blockId((unsigned char)(blockId & 0xff)),
|
||||
blockData((unsigned char)(blockData & 0xff))
|
||||
{
|
||||
}
|
||||
|
||||
void write(RakNet::BitStream* bitStream)
|
||||
{
|
||||
bitStream->Write((RakNet::MessageID)(ID_USER_PACKET_ENUM + PACKET_PLACEBLOCK));
|
||||
|
||||
bitStream->Write(entityId);
|
||||
bitStream->Write(x);
|
||||
bitStream->Write(z);
|
||||
bitStream->Write(y);
|
||||
bitStream->Write(facing);
|
||||
bitStream->Write(blockId);
|
||||
bitStream->Write(blockData);
|
||||
}
|
||||
|
||||
void read(RakNet::BitStream* bitStream)
|
||||
{
|
||||
bitStream->Read(entityId);
|
||||
bitStream->Read(x);
|
||||
bitStream->Read(z);
|
||||
bitStream->Read(y);
|
||||
bitStream->Read(facing);
|
||||
bitStream->Read(blockId);
|
||||
bitStream->Read(blockData);
|
||||
}
|
||||
|
||||
void handle(const RakNet::RakNetGUID& source, NetEventCallback* callback)
|
||||
{
|
||||
callback->handle(source, (PlaceBlockPacket*)this);
|
||||
}
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_NETWORK_PACKET__PlaceBlockPacket_H__*/
|
||||
62
src/network/packet/PlayerActionPacket.h
Executable file
62
src/network/packet/PlayerActionPacket.h
Executable file
@@ -0,0 +1,62 @@
|
||||
#ifndef NET_MINECRAFT_NETWORK_PACKET__PlayerActionPacket_H__
|
||||
#define NET_MINECRAFT_NETWORK_PACKET__PlayerActionPacket_H__
|
||||
|
||||
#include "../Packet.h"
|
||||
|
||||
class PlayerActionPacket : public Packet
|
||||
{
|
||||
public:
|
||||
static const int START_DESTROY_BLOCK = 0;
|
||||
static const int ABORT_DESTROY_BLOCK = 1;
|
||||
static const int STOP_DESTROY_BLOCK = 2;
|
||||
static const int GET_UPDATED_BLOCK = 3;
|
||||
static const int DROP_ITEM = 4;
|
||||
static const int RELEASE_USE_ITEM = 5;
|
||||
static const int STOP_SLEEPING = 6;
|
||||
|
||||
PlayerActionPacket()
|
||||
: x(0),
|
||||
y(0),
|
||||
z(0),
|
||||
action(0),
|
||||
face(0),
|
||||
entityId(0)
|
||||
{}
|
||||
|
||||
PlayerActionPacket(int action, int x, int y, int z, int face, int entityId)
|
||||
: x(x),
|
||||
y(y),
|
||||
z(z),
|
||||
face(face),
|
||||
action(action),
|
||||
entityId(entityId)
|
||||
{}
|
||||
|
||||
void read(RakNet::BitStream* bitStream) {
|
||||
bitStream->Read(action);
|
||||
bitStream->Read(x);
|
||||
bitStream->Read(y);
|
||||
bitStream->Read(z);
|
||||
bitStream->Read(face);
|
||||
bitStream->Read(entityId);
|
||||
}
|
||||
|
||||
void write(RakNet::BitStream* bitStream) {
|
||||
bitStream->Write((RakNet::MessageID)(ID_USER_PACKET_ENUM + PACKET_PLAYERACTION));
|
||||
|
||||
bitStream->Write(action);
|
||||
bitStream->Write(x);
|
||||
bitStream->Write(y);
|
||||
bitStream->Write(z);
|
||||
bitStream->Write(face);
|
||||
bitStream->Write(entityId);
|
||||
}
|
||||
|
||||
void handle(const RakNet::RakNetGUID& source, NetEventCallback* callback) {
|
||||
callback->handle(source, (PlayerActionPacket*)this);
|
||||
}
|
||||
|
||||
int x, y, z, face, action, entityId;
|
||||
};
|
||||
|
||||
#endif /* NET_MINECRAFT_NETWORK_PACKET__PlayerActionPacket_H__ */
|
||||
78
src/network/packet/PlayerArmorEquipmentPacket.h
Executable file
78
src/network/packet/PlayerArmorEquipmentPacket.h
Executable file
@@ -0,0 +1,78 @@
|
||||
#ifndef NET_MINECRAFT_NETWORK_PACKET__PlayerArmorEquipmentPacket_H__
|
||||
#define NET_MINECRAFT_NETWORK_PACKET__PlayerArmorEquipmentPacket_H__
|
||||
|
||||
#include "../Packet.h"
|
||||
#include "../../world/entity/player/Player.h"
|
||||
#include "../../world/item/ArmorItem.h"
|
||||
#include "../../world/item/ItemInstance.h"
|
||||
|
||||
// @note: A visual update only
|
||||
class PlayerArmorEquipmentPacket : public Packet
|
||||
{
|
||||
public:
|
||||
int entityId;
|
||||
signed char head;
|
||||
signed char torso;
|
||||
signed char legs;
|
||||
signed char feet;
|
||||
|
||||
PlayerArmorEquipmentPacket() {
|
||||
}
|
||||
|
||||
PlayerArmorEquipmentPacket(Player* player)
|
||||
: entityId(player->entityId)
|
||||
{
|
||||
get(head, player->getArmor(ArmorItem::SLOT_HEAD));
|
||||
get(torso, player->getArmor(ArmorItem::SLOT_TORSO));
|
||||
get(legs, player->getArmor(ArmorItem::SLOT_LEGS));
|
||||
get(feet, player->getArmor(ArmorItem::SLOT_FEET));
|
||||
}
|
||||
|
||||
void write(RakNet::BitStream* bitStream) {
|
||||
bitStream->Write((RakNet::MessageID)(ID_USER_PACKET_ENUM + PACKET_PLAYERARMOREQUIPMENT));
|
||||
|
||||
bitStream->Write(entityId);
|
||||
bitStream->Write(head);
|
||||
bitStream->Write(torso);
|
||||
bitStream->Write(legs);
|
||||
bitStream->Write(feet);
|
||||
}
|
||||
|
||||
void read(RakNet::BitStream* bitStream) {
|
||||
bitStream->Read(entityId);
|
||||
bitStream->Read(head);
|
||||
bitStream->Read(torso);
|
||||
bitStream->Read(legs);
|
||||
bitStream->Read(feet);
|
||||
}
|
||||
|
||||
void handle(const RakNet::RakNetGUID& source, NetEventCallback* callback) {
|
||||
callback->handle(source, (PlayerArmorEquipmentPacket*)this);
|
||||
}
|
||||
|
||||
void fillIn(Player* player) {
|
||||
set(player, head, ArmorItem::SLOT_HEAD);
|
||||
set(player, torso, ArmorItem::SLOT_TORSO);
|
||||
set(player, legs, ArmorItem::SLOT_LEGS);
|
||||
set(player, feet, ArmorItem::SLOT_FEET);
|
||||
}
|
||||
|
||||
private:
|
||||
void get(signed char& s, const ItemInstance* item) {
|
||||
if (item) {
|
||||
s = item->id - 256;
|
||||
} else {
|
||||
s = -1;
|
||||
}
|
||||
}
|
||||
|
||||
void set(Player* p, signed char s, int slot) {
|
||||
if (s < 0) p->setArmor(slot, NULL);
|
||||
else {
|
||||
ItemInstance item((int)s + 256, 1, 0);
|
||||
p->setArmor(slot, &item);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_NETWORK_PACKET__PlayerArmorEquipmentPacket_H__*/
|
||||
46
src/network/packet/PlayerEquipmentPacket.h
Executable file
46
src/network/packet/PlayerEquipmentPacket.h
Executable file
@@ -0,0 +1,46 @@
|
||||
#ifndef NET_MINECRAFT_NETWORK_PACKET__PlayerEquipmentPacket_H__
|
||||
#define NET_MINECRAFT_NETWORK_PACKET__PlayerEquipmentPacket_H__
|
||||
|
||||
#include "../Packet.h"
|
||||
|
||||
class PlayerEquipmentPacket : public Packet
|
||||
{
|
||||
public:
|
||||
int entityId;
|
||||
unsigned short itemId;
|
||||
unsigned short itemAuxValue;
|
||||
|
||||
PlayerEquipmentPacket()
|
||||
{
|
||||
}
|
||||
|
||||
PlayerEquipmentPacket(int entityId, int itemId, int data)
|
||||
: entityId(entityId),
|
||||
itemId(itemId),
|
||||
itemAuxValue(data)
|
||||
{
|
||||
}
|
||||
|
||||
void write(RakNet::BitStream* bitStream)
|
||||
{
|
||||
bitStream->Write((RakNet::MessageID)(ID_USER_PACKET_ENUM + PACKET_PLAYEREQUIPMENT));
|
||||
|
||||
bitStream->Write(entityId);
|
||||
bitStream->Write(itemId);
|
||||
bitStream->Write(itemAuxValue);
|
||||
}
|
||||
|
||||
void read(RakNet::BitStream* bitStream)
|
||||
{
|
||||
bitStream->Read(entityId);
|
||||
bitStream->Read(itemId);
|
||||
bitStream->Read(itemAuxValue);
|
||||
}
|
||||
|
||||
void handle(const RakNet::RakNetGUID& source, NetEventCallback* callback)
|
||||
{
|
||||
callback->handle(source, (PlayerEquipmentPacket*)this);
|
||||
}
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_NETWORK_PACKET__PlayerEquipmentPacket_H__*/
|
||||
42
src/network/packet/ReadyPacket.h
Executable file
42
src/network/packet/ReadyPacket.h
Executable file
@@ -0,0 +1,42 @@
|
||||
#ifndef NET_MINECRAFT_NETWORK_PACKET__ReadyPacket_H__
|
||||
#define NET_MINECRAFT_NETWORK_PACKET__ReadyPacket_H__
|
||||
|
||||
#include "../Packet.h"
|
||||
|
||||
class ReadyPacket: public Packet
|
||||
{
|
||||
public:
|
||||
static const char READY_UNDEFINED = 0;
|
||||
static const char READY_CLIENTGENERATION = 1;
|
||||
static const char READY_REQUESTEDCHUNKS = 2;
|
||||
|
||||
ReadyPacket()
|
||||
: type(READY_UNDEFINED)
|
||||
{
|
||||
}
|
||||
|
||||
ReadyPacket(char type)
|
||||
: type(type)
|
||||
{
|
||||
}
|
||||
|
||||
void write(RakNet::BitStream* bitStream)
|
||||
{
|
||||
bitStream->Write((RakNet::MessageID)(ID_USER_PACKET_ENUM + PACKET_READY));
|
||||
bitStream->Write(type);
|
||||
}
|
||||
|
||||
void read(RakNet::BitStream* bitStream)
|
||||
{
|
||||
bitStream->Read(type);
|
||||
}
|
||||
|
||||
void handle(const RakNet::RakNetGUID& source, NetEventCallback* callback)
|
||||
{
|
||||
callback->handle(source, (ReadyPacket*)this);
|
||||
}
|
||||
|
||||
char type;
|
||||
};
|
||||
|
||||
#endif /*#NET_MINECRAFT_NETWORK_PACKET__ReadyPacket_H__*/
|
||||
52
src/network/packet/RemoveBlockPacket.h
Executable file
52
src/network/packet/RemoveBlockPacket.h
Executable file
@@ -0,0 +1,52 @@
|
||||
#ifndef NET_MINECRAFT_NETWORK_PACKET__RemoveBlockPacket_H__
|
||||
#define NET_MINECRAFT_NETWORK_PACKET__RemoveBlockPacket_H__
|
||||
|
||||
#include "../Packet.h"
|
||||
#include "../../world/entity/player/Player.h"
|
||||
|
||||
class RemoveBlockPacket : public Packet
|
||||
{
|
||||
public:
|
||||
|
||||
// the id of the player who is placing the block, used to animate the player
|
||||
int entityId;
|
||||
int x, z;
|
||||
unsigned char y;
|
||||
|
||||
RemoveBlockPacket()
|
||||
{
|
||||
}
|
||||
|
||||
RemoveBlockPacket(Player* p, int x, int y, int z)
|
||||
: entityId(p->entityId),
|
||||
x(x),
|
||||
y((unsigned char)(y & 0xff)),
|
||||
z(z)
|
||||
{
|
||||
}
|
||||
|
||||
void write(RakNet::BitStream* bitStream)
|
||||
{
|
||||
bitStream->Write((RakNet::MessageID)(ID_USER_PACKET_ENUM + PACKET_REMOVEBLOCK));
|
||||
|
||||
bitStream->Write(entityId);
|
||||
bitStream->Write(x);
|
||||
bitStream->Write(z);
|
||||
bitStream->Write(y);
|
||||
}
|
||||
|
||||
void read(RakNet::BitStream* bitStream)
|
||||
{
|
||||
bitStream->Read(entityId);
|
||||
bitStream->Read(x);
|
||||
bitStream->Read(z);
|
||||
bitStream->Read(y);
|
||||
}
|
||||
|
||||
void handle(const RakNet::RakNetGUID& source, NetEventCallback* callback)
|
||||
{
|
||||
callback->handle(source, (RemoveBlockPacket*)this);
|
||||
}
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_NETWORK_PACKET__RemoveBlockPacket_H__*/
|
||||
39
src/network/packet/RemoveEntityPacket.h
Executable file
39
src/network/packet/RemoveEntityPacket.h
Executable file
@@ -0,0 +1,39 @@
|
||||
#ifndef NET_MINECRAFT_NETWORK_PACKET__RemoveEntityPacket_H__
|
||||
#define NET_MINECRAFT_NETWORK_PACKET__RemoveEntityPacket_H__
|
||||
|
||||
#include "../Packet.h"
|
||||
|
||||
class RemoveEntityPacket : public Packet
|
||||
{
|
||||
public:
|
||||
|
||||
int entityId;
|
||||
|
||||
RemoveEntityPacket()
|
||||
{
|
||||
}
|
||||
|
||||
RemoveEntityPacket(int entityId)
|
||||
: entityId(entityId)
|
||||
{
|
||||
}
|
||||
|
||||
void write(RakNet::BitStream* bitStream)
|
||||
{
|
||||
bitStream->Write((RakNet::MessageID)(ID_USER_PACKET_ENUM + PACKET_REMOVEENTITY));
|
||||
|
||||
bitStream->Write(entityId);
|
||||
}
|
||||
|
||||
void read(RakNet::BitStream* bitStream)
|
||||
{
|
||||
bitStream->Read(entityId);
|
||||
}
|
||||
|
||||
void handle(const RakNet::RakNetGUID& source, NetEventCallback* callback)
|
||||
{
|
||||
callback->handle(source, (RemoveEntityPacket*)this);
|
||||
}
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_NETWORK_PACKET__RemoveEntityPacket_H__*/
|
||||
41
src/network/packet/RemovePlayerPacket.h
Executable file
41
src/network/packet/RemovePlayerPacket.h
Executable file
@@ -0,0 +1,41 @@
|
||||
#ifndef NET_MINECRAFT_NETWORK_PACKET__RemovePlayerPacket_H__
|
||||
#define NET_MINECRAFT_NETWORK_PACKET__RemovePlayerPacket_H__
|
||||
|
||||
#include "../Packet.h"
|
||||
#include "../../world/entity/player/Player.h"
|
||||
|
||||
class RemovePlayerPacket : public Packet
|
||||
{
|
||||
public:
|
||||
RemovePlayerPacket() {}
|
||||
|
||||
RemovePlayerPacket(const Player* p)
|
||||
: entityId(p->entityId),
|
||||
owner(p->owner)
|
||||
{
|
||||
}
|
||||
|
||||
void write(RakNet::BitStream* bitStream)
|
||||
{
|
||||
bitStream->Write((RakNet::MessageID)(ID_USER_PACKET_ENUM + PACKET_REMOVEPLAYER));
|
||||
|
||||
bitStream->Write(entityId);
|
||||
bitStream->Write(owner);
|
||||
}
|
||||
|
||||
void read(RakNet::BitStream* bitStream)
|
||||
{
|
||||
bitStream->Read(entityId);
|
||||
bitStream->Read(owner);
|
||||
}
|
||||
|
||||
void handle(const RakNet::RakNetGUID& source, NetEventCallback* callback)
|
||||
{
|
||||
callback->handle(source, (RemovePlayerPacket*)this);
|
||||
}
|
||||
|
||||
int entityId;
|
||||
RakNet::RakNetGUID owner;
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_NETWORK_PACKET__RemovePlayerPacket_H__*/
|
||||
42
src/network/packet/RequestChunkPacket.h
Executable file
42
src/network/packet/RequestChunkPacket.h
Executable file
@@ -0,0 +1,42 @@
|
||||
#ifndef NET_MINECRAFT_NETWORK_PACKET__RequestChunkPacket_H__
|
||||
#define NET_MINECRAFT_NETWORK_PACKET__RequestChunkPacket_H__
|
||||
|
||||
#include "../Packet.h"
|
||||
|
||||
class RequestChunkPacket : public Packet
|
||||
{
|
||||
public:
|
||||
|
||||
int x, z;
|
||||
|
||||
RequestChunkPacket()
|
||||
{
|
||||
}
|
||||
|
||||
RequestChunkPacket(int _x, int _z)
|
||||
{
|
||||
x = _x;
|
||||
z = _z;
|
||||
}
|
||||
|
||||
void write(RakNet::BitStream* bitStream)
|
||||
{
|
||||
bitStream->Write((RakNet::MessageID)(ID_USER_PACKET_ENUM + PACKET_REQUESTCHUNK));
|
||||
|
||||
bitStream->Write(x);
|
||||
bitStream->Write(z);
|
||||
}
|
||||
|
||||
void read(RakNet::BitStream* bitStream)
|
||||
{
|
||||
bitStream->Read(x);
|
||||
bitStream->Read(z);
|
||||
}
|
||||
|
||||
void handle(const RakNet::RakNetGUID& source, NetEventCallback* callback)
|
||||
{
|
||||
callback->handle(source, (RequestChunkPacket*)this);
|
||||
}
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_NETWORK_PACKET__RequestChunkPacket_H__*/
|
||||
47
src/network/packet/RespawnPacket.h
Executable file
47
src/network/packet/RespawnPacket.h
Executable file
@@ -0,0 +1,47 @@
|
||||
#ifndef NET_MINECRAFT_NETWORK_PACKET__RespawnPacket_H__
|
||||
#define NET_MINECRAFT_NETWORK_PACKET__RespawnPacket_H__
|
||||
|
||||
#include "../Packet.h"
|
||||
|
||||
class RespawnPacket: public Packet
|
||||
{
|
||||
public:
|
||||
RespawnPacket()
|
||||
{
|
||||
}
|
||||
|
||||
RespawnPacket(const Player* p)
|
||||
: x(p->x),y(p->y),z(p->z),
|
||||
entityId(p->entityId)
|
||||
{
|
||||
}
|
||||
|
||||
void write(RakNet::BitStream* bitStream)
|
||||
{
|
||||
bitStream->Write((RakNet::MessageID)(ID_USER_PACKET_ENUM + PACKET_RESPAWN));
|
||||
bitStream->Write(entityId);
|
||||
bitStream->Write(x);
|
||||
bitStream->Write(y);
|
||||
bitStream->Write(z);
|
||||
}
|
||||
|
||||
void read(RakNet::BitStream* bitStream)
|
||||
{
|
||||
bitStream->Read(entityId);
|
||||
bitStream->Read(x);
|
||||
bitStream->Read(y);
|
||||
bitStream->Read(z);
|
||||
}
|
||||
|
||||
void handle(const RakNet::RakNetGUID& source, NetEventCallback* callback)
|
||||
{
|
||||
callback->handle(source, (RespawnPacket*)this);
|
||||
}
|
||||
|
||||
float x;
|
||||
float y;
|
||||
float z;
|
||||
int entityId;
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_NETWORK_PACKET__RespawnPacket_H__*/
|
||||
69
src/network/packet/SendInventoryPacket.h
Executable file
69
src/network/packet/SendInventoryPacket.h
Executable file
@@ -0,0 +1,69 @@
|
||||
#ifndef NET_MINECRAFT_NETWORK_PACKET__SendInventoryPacket_H__
|
||||
#define NET_MINECRAFT_NETWORK_PACKET__SendInventoryPacket_H__
|
||||
|
||||
#include "../Packet.h"
|
||||
|
||||
class SendInventoryPacket: public Packet
|
||||
{
|
||||
public:
|
||||
SendInventoryPacket()
|
||||
{
|
||||
}
|
||||
|
||||
SendInventoryPacket(Player* player, bool dropItems)
|
||||
: entityId(player->entityId),
|
||||
extra(dropItems? ExtraDrop : 0)
|
||||
{
|
||||
Inventory* inv = player->inventory;
|
||||
numItems = 0;
|
||||
for (int i = Inventory::MAX_SELECTION_SIZE; i < inv->getContainerSize(); ++i) {
|
||||
++numItems;
|
||||
ItemInstance* item = inv->getItem(i);
|
||||
items.push_back(item? *item : ItemInstance());
|
||||
}
|
||||
for (int i = 0; i < NumArmorItems; ++i) {
|
||||
ItemInstance* item = player->getArmor(i);
|
||||
items.push_back(item? *item : ItemInstance());
|
||||
}
|
||||
}
|
||||
|
||||
void write(RakNet::BitStream* bitStream)
|
||||
{
|
||||
bitStream->Write((RakNet::MessageID)(ID_USER_PACKET_ENUM + PACKET_SENDINVENTORY));
|
||||
bitStream->Write(entityId);
|
||||
bitStream->Write(extra);
|
||||
bitStream->Write(numItems);
|
||||
// Inventory
|
||||
for (int i = 0; i < numItems; ++i)
|
||||
PacketUtil::writeItemInstance(items[i], bitStream);
|
||||
// Armor
|
||||
for (int i = 0; i < NumArmorItems; ++i)
|
||||
PacketUtil::writeItemInstance(items[i + numItems], bitStream);
|
||||
}
|
||||
|
||||
void read(RakNet::BitStream* bitStream)
|
||||
{
|
||||
bitStream->Read(entityId);
|
||||
bitStream->Read(extra);
|
||||
bitStream->Read(numItems);
|
||||
items.clear();
|
||||
// Inventory, Armor
|
||||
for (int i = 0; i < numItems + NumArmorItems; ++i)
|
||||
items.push_back(PacketUtil::readItemInstance(bitStream));
|
||||
}
|
||||
|
||||
void handle(const RakNet::RakNetGUID& source, NetEventCallback* callback)
|
||||
{
|
||||
callback->handle(source, (SendInventoryPacket*)this);
|
||||
}
|
||||
|
||||
int entityId;
|
||||
std::vector<ItemInstance> items;
|
||||
short numItems;
|
||||
unsigned char extra;
|
||||
|
||||
static const int ExtraDrop = 1;
|
||||
static const int NumArmorItems = 4;
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_NETWORK_PACKET__SendInventoryPacket_H__*/
|
||||
64
src/network/packet/SetEntityDataPacket.h
Executable file
64
src/network/packet/SetEntityDataPacket.h
Executable file
@@ -0,0 +1,64 @@
|
||||
#ifndef NET_MINECRAFT_NETWORK_PACKET__SetEntityDataPacket_H__
|
||||
#define NET_MINECRAFT_NETWORK_PACKET__SetEntityDataPacket_H__
|
||||
|
||||
//package net.minecraft.network.packet;
|
||||
|
||||
#include "../Packet.h"
|
||||
|
||||
#include "../../world/entity/SynchedEntityData.h"
|
||||
#include "../../util/RakDataIO.h"
|
||||
|
||||
class SetEntityDataPacket: public Packet
|
||||
{
|
||||
public:
|
||||
SetEntityDataPacket()
|
||||
: deletePackedItems(false)
|
||||
{}
|
||||
|
||||
SetEntityDataPacket(int id, SynchedEntityData& entityData)
|
||||
: id(id),
|
||||
deletePackedItems(false),
|
||||
packedItems(entityData.packDirty())
|
||||
{
|
||||
}
|
||||
|
||||
~SetEntityDataPacket() {
|
||||
if (deletePackedItems)
|
||||
for (unsigned int i = 0; i < packedItems.size(); ++i)
|
||||
delete packedItems[i];
|
||||
}
|
||||
|
||||
void write(RakNet::BitStream* bitStream)
|
||||
{
|
||||
bitStream->Write((RakNet::MessageID)(ID_USER_PACKET_ENUM + PACKET_SETENTITYDATA));
|
||||
bitStream->Write(id);
|
||||
|
||||
RakDataOutput dos(*bitStream);
|
||||
SynchedEntityData::pack(&packedItems, &dos);
|
||||
}
|
||||
|
||||
void read(RakNet::BitStream* bitStream)
|
||||
{
|
||||
bitStream->Read(id);
|
||||
|
||||
RakDataInput dis(*bitStream);
|
||||
packedItems = SynchedEntityData::unpack(&dis);
|
||||
deletePackedItems = true;
|
||||
}
|
||||
|
||||
void handle(const RakNet::RakNetGUID& source, NetEventCallback* callback)
|
||||
{
|
||||
callback->handle(source, (SetEntityDataPacket*)this);
|
||||
}
|
||||
|
||||
SynchedEntityData::DataList& getUnpackedData() {
|
||||
return packedItems;
|
||||
}
|
||||
public:
|
||||
int id;
|
||||
private:
|
||||
bool deletePackedItems;
|
||||
SynchedEntityData::DataList packedItems;
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_NETWORK_PACKET__SetEntityDataPacket_H__*/
|
||||
68
src/network/packet/SetEntityMotionPacket.h
Executable file
68
src/network/packet/SetEntityMotionPacket.h
Executable file
@@ -0,0 +1,68 @@
|
||||
#ifndef NET_MINECRAFT_NETWORK_PACKET__SetEntityMotionPacket_H__
|
||||
#define NET_MINECRAFT_NETWORK_PACKET__SetEntityMotionPacket_H__
|
||||
|
||||
//package net.minecraft.network.packet;
|
||||
|
||||
#include "../Packet.h"
|
||||
#include "../../world/entity/Entity.h"
|
||||
|
||||
class SetEntityMotionPacket: public Packet
|
||||
{
|
||||
public:
|
||||
SetEntityMotionPacket() {}
|
||||
|
||||
SetEntityMotionPacket(Entity* e) {
|
||||
init(e->entityId, e->xd, e->yd, e->zd);
|
||||
}
|
||||
|
||||
SetEntityMotionPacket(int id, float xd, float yd, float zd) {
|
||||
init(id, xd, yd, zd);
|
||||
}
|
||||
|
||||
void write(RakNet::BitStream* bitStream)
|
||||
{
|
||||
const float M = 3.9f;
|
||||
short xa = (short)(8000.0f * Mth::clamp(xd, -M, M));
|
||||
short ya = (short)(8000.0f * Mth::clamp(yd, -M, M));
|
||||
short za = (short)(8000.0f * Mth::clamp(zd, -M, M));
|
||||
|
||||
bitStream->Write((RakNet::MessageID)(ID_USER_PACKET_ENUM + PACKET_SETENTITYMOTION));
|
||||
bitStream->Write(id);
|
||||
bitStream->Write(xa);
|
||||
bitStream->Write(ya);
|
||||
bitStream->Write(za);
|
||||
}
|
||||
|
||||
void read(RakNet::BitStream* bitStream)
|
||||
{
|
||||
short xa, ya, za;
|
||||
bitStream->Read(id);
|
||||
bitStream->Read(xa);
|
||||
bitStream->Read(ya);
|
||||
bitStream->Read(za);
|
||||
|
||||
xd = xa / 8000.0f;
|
||||
yd = ya / 8000.0f;
|
||||
zd = za / 8000.0f;
|
||||
}
|
||||
|
||||
void handle(const RakNet::RakNetGUID& source, NetEventCallback* callback)
|
||||
{
|
||||
callback->handle(source, (SetEntityMotionPacket*)this);
|
||||
}
|
||||
|
||||
private:
|
||||
void init(int entityId, float xd, float yd, float zd) {
|
||||
this->id = entityId;
|
||||
this->xd = xd;
|
||||
this->yd = yd;
|
||||
this->zd = zd;
|
||||
}
|
||||
|
||||
public:
|
||||
int id;
|
||||
float xd, yd, zd;
|
||||
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_NETWORK_PACKET__SetEntityMotionPacket_H__*/
|
||||
41
src/network/packet/SetHealthPacket.h
Executable file
41
src/network/packet/SetHealthPacket.h
Executable file
@@ -0,0 +1,41 @@
|
||||
#ifndef NET_MINECRAFT_NETWORK_PACKET__SetHealthPacket_H__
|
||||
#define NET_MINECRAFT_NETWORK_PACKET__SetHealthPacket_H__
|
||||
|
||||
#include "../Packet.h"
|
||||
|
||||
//package net.minecraft.network.packet;
|
||||
|
||||
class SetHealthPacket: public Packet {
|
||||
public:
|
||||
static const int HEALTH_MODIFY_OFFSET = -64;
|
||||
|
||||
SetHealthPacket() {
|
||||
}
|
||||
|
||||
SetHealthPacket(int health)
|
||||
: health(health)
|
||||
{
|
||||
}
|
||||
|
||||
void write(RakNet::BitStream* bitStream)
|
||||
{
|
||||
bitStream->Write((RakNet::MessageID)(ID_USER_PACKET_ENUM + PACKET_SETHEALTH));
|
||||
bitStream->Write((signed char)health);
|
||||
}
|
||||
|
||||
void read(RakNet::BitStream* bitStream)
|
||||
{
|
||||
signed char tmpHealth;
|
||||
bitStream->Read(tmpHealth);
|
||||
health = tmpHealth;
|
||||
}
|
||||
|
||||
void handle(const RakNet::RakNetGUID& source, NetEventCallback* callback)
|
||||
{
|
||||
callback->handle(source, (SetHealthPacket*)this);
|
||||
}
|
||||
|
||||
int health;
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_NETWORK_PACKET__SetHealthPacket_H__*/
|
||||
52
src/network/packet/SetSpawnPositionPacket.h
Executable file
52
src/network/packet/SetSpawnPositionPacket.h
Executable file
@@ -0,0 +1,52 @@
|
||||
#ifndef NET_MINECRAFT_NETWORK_PACKET__SetSpawnPositionPacket_H__
|
||||
#define NET_MINECRAFT_NETWORK_PACKET__SetSpawnPositionPacket_H__
|
||||
|
||||
#include "../Packet.h"
|
||||
|
||||
class SetSpawnPositionPacket : public Packet
|
||||
{
|
||||
public:
|
||||
int entityId;
|
||||
int x, z;
|
||||
unsigned char y;
|
||||
|
||||
SetSpawnPositionPacket()
|
||||
{
|
||||
}
|
||||
|
||||
SetSpawnPositionPacket(int x, int y, int z)
|
||||
: x(x),
|
||||
y((unsigned char)(y & 0xff)),
|
||||
z(z)
|
||||
{
|
||||
}
|
||||
SetSpawnPositionPacket(const Pos& pos)
|
||||
: x(pos.x),
|
||||
y((unsigned char)(pos.y & 0xff)),
|
||||
z(pos.z)
|
||||
{
|
||||
}
|
||||
|
||||
void write(RakNet::BitStream* bitStream)
|
||||
{
|
||||
bitStream->Write((RakNet::MessageID)(ID_USER_PACKET_ENUM + PACKET_SETSPAWNPOSITION));
|
||||
|
||||
bitStream->Write(x);
|
||||
bitStream->Write(z);
|
||||
bitStream->Write(y);
|
||||
}
|
||||
|
||||
void read(RakNet::BitStream* bitStream)
|
||||
{
|
||||
bitStream->Read(x);
|
||||
bitStream->Read(z);
|
||||
bitStream->Read(y);
|
||||
}
|
||||
|
||||
void handle(const RakNet::RakNetGUID& source, NetEventCallback* callback)
|
||||
{
|
||||
callback->handle(source, (SetSpawnPositionPacket*)this);
|
||||
}
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_NETWORK_PACKET__SetSpawnPositionPacket_H__*/
|
||||
36
src/network/packet/SetTimePacket.h
Executable file
36
src/network/packet/SetTimePacket.h
Executable file
@@ -0,0 +1,36 @@
|
||||
#ifndef NET_MINECRAFT_NETWORK_PACKET__SetTimePacket_H__
|
||||
#define NET_MINECRAFT_NETWORK_PACKET__SetTimePacket_H__
|
||||
|
||||
//package net.minecraft.network.packet;
|
||||
|
||||
#include "../Packet.h"
|
||||
|
||||
class SetTimePacket: public Packet {
|
||||
public:
|
||||
SetTimePacket() {
|
||||
}
|
||||
|
||||
SetTimePacket(long time)
|
||||
: time(time)
|
||||
{}
|
||||
|
||||
void write(RakNet::BitStream* bitStream)
|
||||
{
|
||||
bitStream->Write((RakNet::MessageID)(ID_USER_PACKET_ENUM + PACKET_SETTIME));
|
||||
bitStream->Write(time);
|
||||
}
|
||||
|
||||
void read(RakNet::BitStream* bitStream)
|
||||
{
|
||||
bitStream->Read(time);
|
||||
}
|
||||
|
||||
void handle(const RakNet::RakNetGUID& source, NetEventCallback* callback)
|
||||
{
|
||||
callback->handle(source, (SetTimePacket*)this);
|
||||
}
|
||||
|
||||
long time;
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_NETWORK_PACKET__SetTimePacket_H__*/
|
||||
68
src/network/packet/SignUpdatePacket.h
Executable file
68
src/network/packet/SignUpdatePacket.h
Executable file
@@ -0,0 +1,68 @@
|
||||
#ifndef NET_MINECRAFT_NETWORK_PACKET__SignUpdatePacket_H__
|
||||
#define NET_MINECRAFT_NETWORK_PACKET__SignUpdatePacket_H__
|
||||
|
||||
//package net.minecraft.network.packet;
|
||||
|
||||
#include "../Packet.h"
|
||||
#include "../../util/RakDataIO.h"
|
||||
#include "../../world/level/tile/entity/SignTileEntity.h"
|
||||
|
||||
class SignUpdatePacket: public Packet
|
||||
{
|
||||
public:
|
||||
SignUpdatePacket() {}
|
||||
|
||||
SignUpdatePacket(int x, int y, int z, const std::string lines[])
|
||||
: x(x),
|
||||
y(y),
|
||||
z(z)
|
||||
{
|
||||
for (int i = 0; i < 4; ++i)
|
||||
this->lines[i] = lines[i];
|
||||
}
|
||||
|
||||
/*@Override*/
|
||||
void read(RakNet::BitStream* bitStream) {
|
||||
short xx, zz;
|
||||
unsigned char yy;
|
||||
bitStream->Read(xx);
|
||||
bitStream->Read(yy);
|
||||
bitStream->Read(zz);
|
||||
x = xx;
|
||||
z = zz;
|
||||
y = yy;
|
||||
|
||||
RakDataInput dis(*bitStream);
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
lines[i] = dis.readString();
|
||||
if (lines[i].length() > SignTileEntity::MAX_LINE_LENGTH)
|
||||
lines[i].resize(SignTileEntity::MAX_LINE_LENGTH);
|
||||
}
|
||||
}
|
||||
|
||||
/*@Override*/
|
||||
void write(RakNet::BitStream* bitStream) {
|
||||
bitStream->Write((RakNet::MessageID)(ID_USER_PACKET_ENUM + PACKET_SIGNUPDATE));
|
||||
short xx = x;
|
||||
short zz = z;
|
||||
unsigned char yy = y;
|
||||
bitStream->Write(xx);
|
||||
bitStream->Write(yy);
|
||||
bitStream->Write(zz);
|
||||
|
||||
RakDataOutput dos(*bitStream);
|
||||
for (int i = 0; i < 4; ++i)
|
||||
dos.writeString(lines[i]);
|
||||
}
|
||||
|
||||
/*@Override*/
|
||||
void handle(const RakNet::RakNetGUID& source, NetEventCallback* callback) {
|
||||
callback->handle(source, (SignUpdatePacket*)this);
|
||||
}
|
||||
|
||||
public:
|
||||
int x, y, z;
|
||||
std::string lines[4];
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_NETWORK_PACKET__SignUpdatePacket_H__*/
|
||||
61
src/network/packet/StartGamePacket.h
Executable file
61
src/network/packet/StartGamePacket.h
Executable file
@@ -0,0 +1,61 @@
|
||||
#ifndef NET_MINECRAFT_NETWORK_PACKET__StartGamePacket_H__
|
||||
#define NET_MINECRAFT_NETWORK_PACKET__StartGamePacket_H__
|
||||
|
||||
#include "../Packet.h"
|
||||
|
||||
class StartGamePacket : public Packet
|
||||
{
|
||||
public:
|
||||
long levelSeed;
|
||||
int levelGeneratorVersion;
|
||||
int gameType;
|
||||
|
||||
int entityId;
|
||||
float x, y, z;
|
||||
|
||||
StartGamePacket()
|
||||
{
|
||||
}
|
||||
|
||||
StartGamePacket(long seed, int levelGeneratorVersion, int gameType, int entityId, float x, float y, float z)
|
||||
: levelSeed(seed),
|
||||
levelGeneratorVersion(levelGeneratorVersion),
|
||||
gameType(gameType),
|
||||
entityId(entityId),
|
||||
x(x),
|
||||
y(y),
|
||||
z(z)
|
||||
{
|
||||
}
|
||||
|
||||
void write(RakNet::BitStream* bitStream)
|
||||
{
|
||||
bitStream->Write((RakNet::MessageID)(ID_USER_PACKET_ENUM + PACKET_STARTGAME));
|
||||
|
||||
bitStream->Write(levelSeed);
|
||||
bitStream->Write(levelGeneratorVersion);
|
||||
bitStream->Write(gameType);
|
||||
bitStream->Write(entityId);
|
||||
bitStream->Write(x);
|
||||
bitStream->Write(y);
|
||||
bitStream->Write(z);
|
||||
}
|
||||
|
||||
void read(RakNet::BitStream* bitStream)
|
||||
{
|
||||
bitStream->Read(levelSeed);
|
||||
bitStream->Read(levelGeneratorVersion);
|
||||
bitStream->Read(gameType);
|
||||
bitStream->Read(entityId);
|
||||
bitStream->Read(x);
|
||||
bitStream->Read(y);
|
||||
bitStream->Read(z);
|
||||
}
|
||||
|
||||
void handle(const RakNet::RakNetGUID& source, NetEventCallback* callback)
|
||||
{
|
||||
callback->handle(source, (StartGamePacket*)this);
|
||||
}
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_NETWORK_PACKET__StartGamePacket_H__*/
|
||||
42
src/network/packet/TakeItemEntityPacket.h
Executable file
42
src/network/packet/TakeItemEntityPacket.h
Executable file
@@ -0,0 +1,42 @@
|
||||
#ifndef NET_MINECRAFT_NETWORK_PACKET__TakeItemEntityPacket_H__
|
||||
#define NET_MINECRAFT_NETWORK_PACKET__TakeItemEntityPacket_H__
|
||||
|
||||
//package net.minecraft.network.packet;
|
||||
|
||||
#include "../Packet.h"
|
||||
|
||||
class TakeItemEntityPacket: public Packet
|
||||
{
|
||||
public:
|
||||
TakeItemEntityPacket() {
|
||||
}
|
||||
|
||||
TakeItemEntityPacket(int itemId, int playerId)
|
||||
: itemId(itemId),
|
||||
playerId(playerId)
|
||||
{
|
||||
}
|
||||
|
||||
void write(RakNet::BitStream* bitStream)
|
||||
{
|
||||
bitStream->Write((RakNet::MessageID)(ID_USER_PACKET_ENUM + PACKET_TAKEITEMENTITY));
|
||||
bitStream->Write(itemId);
|
||||
bitStream->Write(playerId);
|
||||
}
|
||||
|
||||
void read(RakNet::BitStream* bitStream)
|
||||
{
|
||||
bitStream->Read(itemId);
|
||||
bitStream->Read(playerId);
|
||||
}
|
||||
|
||||
void handle(const RakNet::RakNetGUID& source, NetEventCallback* callback)
|
||||
{
|
||||
callback->handle(source, (TakeItemEntityPacket*)this);
|
||||
}
|
||||
|
||||
int itemId;
|
||||
int playerId;
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_NETWORK_PACKET__TakeItemEntityPacket_H__*/
|
||||
77
src/network/packet/TeleportEntityPacket.h
Executable file
77
src/network/packet/TeleportEntityPacket.h
Executable file
@@ -0,0 +1,77 @@
|
||||
#ifndef NET_MINECRAFT_NETWORK_PACKET__TeleportEntityPacket_H__
|
||||
#define NET_MINECRAFT_NETWORK_PACKET__TeleportEntityPacket_H__
|
||||
|
||||
//package net.minecraft.network.packet;
|
||||
|
||||
#include "../Packet.h"
|
||||
|
||||
#include "../../world/entity/Entity.h"
|
||||
#include "../../util/Mth.h"
|
||||
|
||||
class TeleportEntityPacket: public Packet
|
||||
{
|
||||
public:
|
||||
TeleportEntityPacket() {
|
||||
}
|
||||
|
||||
TeleportEntityPacket(Entity* e, char cause)
|
||||
: id(e->entityId),
|
||||
x(e->x),
|
||||
y(e->y),
|
||||
z(e->z),
|
||||
yRot(e->yRot),
|
||||
xRot(e->xRot),
|
||||
cause(cause)
|
||||
{
|
||||
}
|
||||
|
||||
TeleportEntityPacket(int id, float x, float y, float z, float yRot, float xRot, char cause)
|
||||
: id(id),
|
||||
x(x),
|
||||
y(y),
|
||||
z(z),
|
||||
yRot(yRot),
|
||||
xRot(xRot),
|
||||
cause(cause)
|
||||
{
|
||||
}
|
||||
|
||||
void write(RakNet::BitStream* bitStream) {
|
||||
bitStream->Write((RakNet::MessageID)(ID_USER_PACKET_ENUM + PACKET_TELEPORTENTITY));
|
||||
bitStream->Write(id);
|
||||
bitStream->Write(x);
|
||||
bitStream->Write(y);
|
||||
bitStream->Write(z);
|
||||
bitStream->Write(PacketUtil::Rot_degreesToChar(yRot));
|
||||
bitStream->Write(PacketUtil::Rot_degreesToChar(xRot));
|
||||
bitStream->Write(cause);
|
||||
}
|
||||
|
||||
void read(RakNet::BitStream* bitStream) {
|
||||
bitStream->Read(id);
|
||||
bitStream->Read(x);
|
||||
bitStream->Read(y);
|
||||
bitStream->Read(z);
|
||||
char rx, ry;
|
||||
bitStream->Read(ry);
|
||||
bitStream->Read(rx);
|
||||
bitStream->Read(cause);
|
||||
yRot = PacketUtil::Rot_degreesToChar(ry);
|
||||
xRot = PacketUtil::Rot_charToDegrees(rx);
|
||||
|
||||
}
|
||||
|
||||
void handle(const RakNet::RakNetGUID& source, NetEventCallback* callback)
|
||||
{
|
||||
callback->handle(source, (TeleportEntityPacket*)this);
|
||||
}
|
||||
|
||||
int id;
|
||||
float x, y, z;
|
||||
float xRot, yRot; // sent as byte
|
||||
char cause;
|
||||
|
||||
static const int WANT_RESPAWN = 1;
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_NETWORK_PACKET__TeleportEntityPacket_H__*/
|
||||
48
src/network/packet/TileEventPacket.h
Executable file
48
src/network/packet/TileEventPacket.h
Executable file
@@ -0,0 +1,48 @@
|
||||
#ifndef NET_MINECRAFT_NETWORK_PACKET__TileEventPacket_H__
|
||||
#define NET_MINECRAFT_NETWORK_PACKET__TileEventPacket_H__
|
||||
|
||||
//package net.minecraft.network.packet;
|
||||
|
||||
#include "../Packet.h"
|
||||
|
||||
class TileEventPacket: public Packet {
|
||||
public:
|
||||
TileEventPacket() {}
|
||||
|
||||
TileEventPacket(int x, int y, int z, int b0, int b1)
|
||||
: x(x),
|
||||
y(y),
|
||||
z(z),
|
||||
b0(b0),
|
||||
b1(b1)
|
||||
{}
|
||||
|
||||
void write(RakNet::BitStream* bitStream)
|
||||
{
|
||||
bitStream->Write((RakNet::MessageID)(ID_USER_PACKET_ENUM + PACKET_TILEEVENT));
|
||||
bitStream->Write(x);
|
||||
bitStream->Write(y);
|
||||
bitStream->Write(z);
|
||||
bitStream->Write(b0);
|
||||
bitStream->Write(b1);
|
||||
}
|
||||
|
||||
void read(RakNet::BitStream* bitStream)
|
||||
{
|
||||
bitStream->Read(x);
|
||||
bitStream->Read(y);
|
||||
bitStream->Read(z);
|
||||
bitStream->Read(b0);
|
||||
bitStream->Read(b1);
|
||||
}
|
||||
|
||||
void handle(const RakNet::RakNetGUID& source, NetEventCallback* callback)
|
||||
{
|
||||
callback->handle(source, (TileEventPacket*)this);
|
||||
}
|
||||
|
||||
int x, y, z;
|
||||
int b0, b1;
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_NETWORK_PACKET__TileEventPacket_H__*/
|
||||
28
src/network/packet/UpdateArmorPacket.h
Executable file
28
src/network/packet/UpdateArmorPacket.h
Executable file
@@ -0,0 +1,28 @@
|
||||
#ifndef NET_MINECRAFT_NETWORK_PACKET__UpdateArmorPacket_H__
|
||||
#define NET_MINECRAFT_NETWORK_PACKET__UpdateArmorPacket_H__
|
||||
|
||||
#include "../Packet.h"
|
||||
|
||||
class UpdateArmorPacket: public Packet
|
||||
{
|
||||
public:
|
||||
UpdateArmorPacket(Player* player)
|
||||
{
|
||||
}
|
||||
|
||||
void write(RakNet::BitStream* bitStream){
|
||||
bitStream->Write((RakNet::MessageID)(ID_USER_PACKET_ENUM + PACKET_UPDATEARMOR));
|
||||
|
||||
//bitStream->Write();
|
||||
}
|
||||
|
||||
void read(RakNet::BitStream* bitStream) {
|
||||
//bitStream->Read();
|
||||
}
|
||||
|
||||
void handle(const RakNet::RakNetGUID& source, NetEventCallback* callback) {
|
||||
callback->handle(source, (UpdateArmorPacket*)this);
|
||||
}
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_NETWORK_PACKET__UpdateArmorPacket_H__*/
|
||||
55
src/network/packet/UpdateBlockPacket.h
Executable file
55
src/network/packet/UpdateBlockPacket.h
Executable file
@@ -0,0 +1,55 @@
|
||||
#ifndef NET_MINECRAFT_NETWORK_PACKET__UpdateBlockPacket_H__
|
||||
#define NET_MINECRAFT_NETWORK_PACKET__UpdateBlockPacket_H__
|
||||
|
||||
#include "../Packet.h"
|
||||
|
||||
class UpdateBlockPacket : public Packet
|
||||
{
|
||||
public:
|
||||
|
||||
int x, z;
|
||||
unsigned char y;
|
||||
unsigned char blockId;
|
||||
unsigned char blockData;
|
||||
|
||||
UpdateBlockPacket()
|
||||
{
|
||||
}
|
||||
|
||||
UpdateBlockPacket(int _x, int _y, int _z, int _blockId, int _blockData)
|
||||
{
|
||||
x = _x;
|
||||
y = (unsigned char)(_y & 0xff);
|
||||
z = _z;
|
||||
blockId = (unsigned char)(_blockId & 0xff);
|
||||
blockData = (unsigned char)(_blockData & 0xff);
|
||||
}
|
||||
|
||||
void write(RakNet::BitStream* bitStream)
|
||||
{
|
||||
bitStream->Write((RakNet::MessageID)(ID_USER_PACKET_ENUM + PACKET_UPDATEBLOCK));
|
||||
|
||||
bitStream->Write(x);
|
||||
bitStream->Write(z);
|
||||
bitStream->Write(y);
|
||||
bitStream->Write(blockId);
|
||||
bitStream->Write(blockData);
|
||||
}
|
||||
|
||||
void read(RakNet::BitStream* bitStream)
|
||||
{
|
||||
bitStream->Read(x);
|
||||
bitStream->Read(z);
|
||||
bitStream->Read(y);
|
||||
bitStream->Read(blockId);
|
||||
bitStream->Read(blockData);
|
||||
|
||||
}
|
||||
|
||||
void handle(const RakNet::RakNetGUID& source, NetEventCallback* callback)
|
||||
{
|
||||
callback->handle(source, (UpdateBlockPacket*)this);
|
||||
}
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_NETWORK_PACKET__UpdateBlockPacket_H__*/
|
||||
86
src/network/packet/UseItemPacket.h
Executable file
86
src/network/packet/UseItemPacket.h
Executable file
@@ -0,0 +1,86 @@
|
||||
#ifndef NET_MINECRAFT_NETWORK_PACKET__UseItemPacket_H__
|
||||
#define NET_MINECRAFT_NETWORK_PACKET__UseItemPacket_H__
|
||||
|
||||
//package net.minecraft.network.packet;
|
||||
|
||||
#include "../Packet.h"
|
||||
|
||||
#include "../../world/item/ItemInstance.h"
|
||||
|
||||
class UseItemPacket: public Packet
|
||||
{
|
||||
public:
|
||||
int x, y, z, face;
|
||||
float clickX, clickY, clickZ;
|
||||
int entityId;
|
||||
short itemId;
|
||||
unsigned char itemData;
|
||||
ItemInstance item;
|
||||
|
||||
UseItemPacket() {}
|
||||
|
||||
UseItemPacket(int x, int y, int z, int face, const ItemInstance* item, int entityId, float clickX, float clickY, float clickZ)
|
||||
: x(x),
|
||||
y(y),
|
||||
z(z),
|
||||
face(face),
|
||||
itemId(item? item->id : 0),
|
||||
itemData(item? item->getAuxValue() : 0),
|
||||
entityId(entityId),
|
||||
clickX(clickX),
|
||||
clickY(clickY),
|
||||
clickZ(clickZ)
|
||||
{}
|
||||
|
||||
UseItemPacket(const ItemInstance* item, int entityId, const Vec3& aim)
|
||||
: face(255),
|
||||
itemId(item? item->id : 0),
|
||||
itemData(item? item->getAuxValue() : 0),
|
||||
entityId(entityId),
|
||||
x((int)(aim.x * 32768.0f)),
|
||||
y((int)(aim.y * 32768.0f)),
|
||||
z((int)(aim.z * 32768.0f))
|
||||
{
|
||||
}
|
||||
|
||||
void write(RakNet::BitStream* bitStream)
|
||||
{
|
||||
bitStream->Write((RakNet::MessageID)(ID_USER_PACKET_ENUM + PACKET_USEITEM));
|
||||
|
||||
bitStream->Write(x);
|
||||
bitStream->Write(y);
|
||||
bitStream->Write(z);
|
||||
bitStream->Write(face);
|
||||
bitStream->Write(itemId);
|
||||
bitStream->Write(itemData);
|
||||
bitStream->Write(entityId);
|
||||
bitStream->Write(clickX);
|
||||
bitStream->Write(clickY);
|
||||
bitStream->Write(clickZ);
|
||||
}
|
||||
|
||||
void read(RakNet::BitStream* bitStream)
|
||||
{
|
||||
bitStream->Read(x);
|
||||
bitStream->Read(y);
|
||||
bitStream->Read(z);
|
||||
bitStream->Read(face);
|
||||
bitStream->Read(itemId);
|
||||
bitStream->Read(itemData);
|
||||
bitStream->Read(entityId);
|
||||
bitStream->Read(clickX);
|
||||
bitStream->Read(clickY);
|
||||
bitStream->Read(clickZ);
|
||||
item.id = itemId;
|
||||
item.setAuxValue(itemData);
|
||||
item.count = (itemId == 0 && itemData == 0)? 0 : 1;
|
||||
|
||||
}
|
||||
|
||||
void handle(const RakNet::RakNetGUID& source, NetEventCallback* callback)
|
||||
{
|
||||
callback->handle(source, (UseItemPacket*)this);
|
||||
}
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_NETWORK_PACKET__UseItemPacket_H__*/
|
||||
Reference in New Issue
Block a user