mirror of
https://github.com/celisej567/mcpe.git
synced 2026-09-17 20:10:23 +03:00
* Initial commit.
:)
This commit is contained in:
357
source/Network/ClientSideNetworkHandler.cpp
Normal file
357
source/Network/ClientSideNetworkHandler.cpp
Normal file
@@ -0,0 +1,357 @@
|
||||
#include <RakPeer.h>
|
||||
#include "ClientSideNetworkHandler.hpp"
|
||||
|
||||
// This lets you make the client shut up and not log events in the debug console.
|
||||
#define VERBOSE_CLIENT
|
||||
|
||||
#if defined(ORIGINAL_CODE) || defined(VERBOSE_CLIENT)
|
||||
#define puts_ignorable(str) puts(str)
|
||||
#define printf_ignorable(str, ...) printf(str, __VA_ARGS__)
|
||||
#else
|
||||
#define puts_ignorable(str)
|
||||
#define printf_ignorable(str, ...)
|
||||
#endif
|
||||
|
||||
ClientSideNetworkHandler::ClientSideNetworkHandler(Minecraft* pMinecraft, RakNetInstance* pRakNetInstance)
|
||||
{
|
||||
m_pMinecraft = pMinecraft;
|
||||
m_pRakNetInstance = pRakNetInstance;
|
||||
m_pServerPeer = m_pRakNetInstance->getPeer();
|
||||
}
|
||||
|
||||
void ClientSideNetworkHandler::levelGenerated(Level* level)
|
||||
{
|
||||
m_pLevel = level;
|
||||
requestNextChunk();
|
||||
}
|
||||
|
||||
void ClientSideNetworkHandler::onConnect(const RakNet::RakNetGUID& rakGuid) // server guid
|
||||
{
|
||||
RakNet::RakNetGUID localGuid = ((RakNet::RakPeer*)m_pServerPeer)->GetMyGUID();
|
||||
printf_ignorable("onConnect, server guid: %s, local guid: %s\n", rakGuid.ToString(), localGuid.ToString());
|
||||
|
||||
m_serverGUID = rakGuid;
|
||||
|
||||
LoginPacket* pLoginPkt = new LoginPacket;
|
||||
pLoginPkt->m_str = RakNet::RakString(m_pMinecraft->m_pUser->field_0.c_str());
|
||||
|
||||
m_pRakNetInstance->send(pLoginPkt);
|
||||
}
|
||||
|
||||
void ClientSideNetworkHandler::onUnableToConnect()
|
||||
{
|
||||
puts_ignorable("onUnableToConnect");
|
||||
}
|
||||
|
||||
void ClientSideNetworkHandler::onDisconnect(const RakNet::RakNetGUID& rakGuid)
|
||||
{
|
||||
puts_ignorable("onDisconnect");
|
||||
|
||||
if (m_pLevel)
|
||||
m_pLevel->field_11 = false;
|
||||
|
||||
m_pMinecraft->m_gui.addMessage("Disconnected from server");
|
||||
}
|
||||
|
||||
void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& rakGuid, MessagePacket* pMsgPkt)
|
||||
{
|
||||
puts_ignorable("MessagePacket");
|
||||
|
||||
m_pMinecraft->m_gui.addMessage(pMsgPkt->m_str.C_String());
|
||||
}
|
||||
|
||||
void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& rakGuid, StartGamePacket* pStartGamePkt)
|
||||
{
|
||||
puts_ignorable("StartGamePacket");
|
||||
|
||||
m_pMinecraft->getLevelSource()->deleteLevel("_LastJoinedServer");
|
||||
|
||||
m_pLevel = new Level(
|
||||
m_pMinecraft->getLevelSource()->selectLevel("_LastJoinedServer", true),
|
||||
"temp",
|
||||
pStartGamePkt->field_4,
|
||||
pStartGamePkt->field_8);
|
||||
|
||||
m_pLevel->field_11 = true;
|
||||
|
||||
auto pLocalPlayer = new LocalPlayer(m_pMinecraft, m_pLevel, m_pMinecraft->m_pUser, m_pLevel->m_pDimension->field_50);
|
||||
pLocalPlayer->m_guid = ((RakNet::RakPeer*)m_pServerPeer)->GetMyGUID();
|
||||
pLocalPlayer->m_EntityID = pStartGamePkt->field_C;
|
||||
|
||||
pLocalPlayer->moveTo(
|
||||
pStartGamePkt->field_10,
|
||||
pStartGamePkt->field_14,
|
||||
pStartGamePkt->field_18,
|
||||
pLocalPlayer->m_yaw,
|
||||
pLocalPlayer->m_pitch);
|
||||
|
||||
m_pMinecraft->setLevel(m_pLevel, "ClientSideNetworkHandler -> setLevel", pLocalPlayer);
|
||||
}
|
||||
|
||||
void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& rakGuid, AddPlayerPacket* pAddPlayerPkt)
|
||||
{
|
||||
puts_ignorable("AddPlayerPacket");
|
||||
|
||||
if (!m_pLevel) return;
|
||||
|
||||
Player* pPlayer = new Player(m_pLevel);
|
||||
pPlayer->m_EntityID = pAddPlayerPkt->m_id;
|
||||
m_pLevel->addEntity(pPlayer);
|
||||
|
||||
pPlayer->moveTo(
|
||||
pAddPlayerPkt->m_x,
|
||||
pAddPlayerPkt->m_y,
|
||||
pAddPlayerPkt->m_z,
|
||||
pPlayer->m_yaw,
|
||||
pPlayer->m_pitch);
|
||||
|
||||
pPlayer->m_name = pAddPlayerPkt->m_name;
|
||||
pPlayer->m_guid = pAddPlayerPkt->m_guid;
|
||||
|
||||
m_pMinecraft->m_gui.addMessage(pPlayer->m_name + " joined the game");
|
||||
}
|
||||
|
||||
void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& rakGuid, RemoveEntityPacket* pRemoveEntityPkt)
|
||||
{
|
||||
if (!m_pLevel) return;
|
||||
|
||||
Entity* pEnt = m_pLevel->getEntity(pRemoveEntityPkt->m_id);
|
||||
|
||||
#if defined(ORIGINAL_CODE) || UINTPTR_MAX == UINT32_MAX
|
||||
// @NOTE: On x64 systems, this won't print the right things.
|
||||
printf_ignorable("RemoveEntityPacket %d %d", pEnt, m_pMinecraft->m_pLocalPlayer);
|
||||
#else
|
||||
printf_ignorable("RemoveEntityPacket %p %p", pEnt, m_pMinecraft->m_pLocalPlayer);
|
||||
#endif
|
||||
|
||||
if (pEnt)
|
||||
m_pLevel->removeEntity(pEnt);
|
||||
}
|
||||
|
||||
void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& rakGuid, MovePlayerPacket* packet)
|
||||
{
|
||||
if (!m_pLevel) return;
|
||||
|
||||
Entity* pEntity = m_pLevel->getEntity(packet->m_id);
|
||||
if (!pEntity)
|
||||
{
|
||||
LogMsg("No player with id %d", packet->m_id);
|
||||
return;
|
||||
}
|
||||
|
||||
pEntity->lerpTo(packet->m_x, packet->m_y, packet->m_z, packet->m_yaw, packet->m_pitch, 3);
|
||||
}
|
||||
|
||||
void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& rakGuid, PlaceBlockPacket* pPlaceBlockPkt)
|
||||
{
|
||||
puts_ignorable("PlaceBlockPacket");
|
||||
|
||||
Player* pPlayer = (Player*)m_pLevel->getEntity(pPlaceBlockPkt->m_playerID);
|
||||
if (!pPlayer)
|
||||
{
|
||||
LogMsg("No player with id %d", pPlaceBlockPkt->m_playerID);
|
||||
return;
|
||||
}
|
||||
|
||||
pPlayer->swing();
|
||||
|
||||
// @BUG: Not buffering the update.
|
||||
if (!areAllChunksLoaded())
|
||||
return;
|
||||
|
||||
int x = pPlaceBlockPkt->m_x;
|
||||
int y = pPlaceBlockPkt->m_y;
|
||||
int z = pPlaceBlockPkt->m_z;
|
||||
int tile = pPlaceBlockPkt->m_tile;
|
||||
int face = pPlaceBlockPkt->m_face;
|
||||
|
||||
if (!m_pLevel->mayPlace(tile, x, y, z, true))
|
||||
return;
|
||||
|
||||
Tile* pTile = Tile::tiles[tile];
|
||||
if (!m_pLevel->setTile(x, y, z, tile))
|
||||
return;
|
||||
|
||||
Tile::tiles[tile]->setPlacedOnFace(m_pLevel, x, y, z, face);
|
||||
Tile::tiles[tile]->setPlacedBy(m_pLevel, x, y, z, pPlayer);
|
||||
|
||||
const Tile::SoundType* pSound = pTile->m_pSound;
|
||||
m_pLevel->playSound(float(x) + 0.5f, float(y) + 0.5f, float(z) + 0.5f, "step." + pSound->m_name, 0.5f * (1.0f + pSound->field_18), 0.8f * pSound->field_1C);
|
||||
}
|
||||
|
||||
void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& rakGuid, RemoveBlockPacket* pRemoveBlockPkt)
|
||||
{
|
||||
puts_ignorable("RemoveBlockPacket");
|
||||
|
||||
Player* pPlayer = (Player*)m_pLevel->getEntity(pRemoveBlockPkt->m_playerID);
|
||||
if (!pPlayer)
|
||||
{
|
||||
LogMsg("No player with id %d", pRemoveBlockPkt->m_playerID);
|
||||
return;
|
||||
}
|
||||
|
||||
pPlayer->swing();
|
||||
|
||||
// @BUG: Not buffering the update.
|
||||
if (!areAllChunksLoaded())
|
||||
return;
|
||||
|
||||
int x = pRemoveBlockPkt->m_x;
|
||||
int y = pRemoveBlockPkt->m_y;
|
||||
int z = pRemoveBlockPkt->m_z;
|
||||
|
||||
Tile* pTile = Tile::tiles[m_pLevel->getTile(x, y, z)];
|
||||
int data = m_pLevel->getData(x, y, z);
|
||||
bool setTileResult = m_pLevel->setTile(x, y, z, TILE_AIR);
|
||||
|
||||
if (pTile && setTileResult)
|
||||
{
|
||||
const Tile::SoundType* pSound = pTile->m_pSound;
|
||||
m_pLevel->playSound(float(x) + 0.5f, float(y) + 0.5f, float(z) + 0.5f, "step." + pSound->m_name, 0.5f * (1.0f + pSound->field_18), 0.8f * pSound->field_1C);
|
||||
|
||||
pTile->destroy(m_pLevel, x, y, z, data);
|
||||
}
|
||||
}
|
||||
|
||||
void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& rakGuid, UpdateBlockPacket* pkt)
|
||||
{
|
||||
if (!areAllChunksLoaded())
|
||||
{
|
||||
m_bufferedBlockUpdates.push_back(SBufferedBlockUpdate(pkt->m_x, pkt->m_y, pkt->m_z, pkt->m_tile, pkt->m_data));
|
||||
return;
|
||||
}
|
||||
|
||||
m_pLevel->setTileAndData(pkt->m_x, pkt->m_y, pkt->m_z, pkt->m_tile, pkt->m_data);
|
||||
}
|
||||
|
||||
void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& rakGuid, ChunkDataPacket* pChunkDataPkt)
|
||||
{
|
||||
if (!m_pLevel)
|
||||
{
|
||||
puts("Level @ handle ChunkDataPacket is 0");
|
||||
return;
|
||||
}
|
||||
|
||||
LevelChunk* pChunk = m_pLevel->getChunkSource()->create(pChunkDataPkt->m_x, pChunkDataPkt->m_z);
|
||||
if (!pChunk || pChunk->isEmpty())
|
||||
{
|
||||
puts("Failed to find write-able chunk");
|
||||
// @BUG: Not trying again.
|
||||
return;
|
||||
}
|
||||
|
||||
int x16 = 16 * pChunkDataPkt->m_x;
|
||||
int z16 = 16 * pChunkDataPkt->m_z;
|
||||
|
||||
bool updated = false;
|
||||
|
||||
int minY = 128, maxY = 0;
|
||||
int minX = 16, minZ = 16;
|
||||
int maxX = 0, maxZ = 0;
|
||||
|
||||
for (int k = 0; k < 256; k++)
|
||||
{
|
||||
uint8_t updMap;
|
||||
pChunkDataPkt->m_data.Read(updMap);
|
||||
|
||||
if (!updMap)
|
||||
continue;
|
||||
|
||||
for (int j = 0; j < 8; j++)
|
||||
{
|
||||
if ((updMap >> j) & 1)
|
||||
{
|
||||
int yPos = j * 16;
|
||||
TileID tiles[16];
|
||||
uint8_t datas[16 / 2];
|
||||
|
||||
pChunkDataPkt->m_data.Read((char*)tiles, 16 * sizeof(TileID));
|
||||
pChunkDataPkt->m_data.Read((char*)datas, 16 / 2);
|
||||
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
m_pLevel->setTileNoUpdate(x16 + (k & 0xF), yPos + i, z16 + (k >> 4), tiles[i]);
|
||||
}
|
||||
|
||||
int idx = ((k & 0xF) << 11) | ((k >> 4) << 7) + yPos;
|
||||
memcpy(&pChunk->m_tileData[idx >> 1], datas, sizeof datas);
|
||||
}
|
||||
|
||||
int ymin = 16 * (1 << j);
|
||||
if (minY >= ymin)
|
||||
minY = ymin;
|
||||
if (maxY < ymin + 15)
|
||||
maxY = ymin + 15;
|
||||
}
|
||||
|
||||
if (minX >= (k & 0xF))
|
||||
minX = k & 0xF;
|
||||
if (minZ >= (k >> 4))
|
||||
minZ = k >> 4;
|
||||
if (maxX <= (k & 0xF))
|
||||
maxX = k & 0xF;
|
||||
if (maxZ <= (k >> 4))
|
||||
maxZ = k >> 4;
|
||||
|
||||
updated = true;
|
||||
}
|
||||
|
||||
if (updated)
|
||||
m_pLevel->setTilesDirty(minX + x16, minY, minZ, maxX + x16, maxY, maxZ + z16);
|
||||
|
||||
pChunk->m_bUnsaved = true;
|
||||
|
||||
if (areAllChunksLoaded())
|
||||
flushAllBufferedUpdates();
|
||||
else
|
||||
requestNextChunk();
|
||||
}
|
||||
|
||||
void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& rakGuid, PlayerEquipmentPacket* pPlayerEquipmentPkt)
|
||||
{
|
||||
Player* pPlayer = (Player*)m_pLevel->getEntity(pPlayerEquipmentPkt->m_playerID);
|
||||
if (!pPlayer)
|
||||
return;
|
||||
|
||||
#ifndef ORIGINAL_CODE
|
||||
if (!Item::items[pPlayerEquipmentPkt->m_itemID])
|
||||
{
|
||||
LogMsg("That item %d doesn't actually exist!", pPlayerEquipmentPkt->m_itemID);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (pPlayer->m_guid == m_pServerPeer->GetMyGUID())
|
||||
{
|
||||
puts("Attempted to modify local player's inventory");
|
||||
return;
|
||||
}
|
||||
|
||||
pPlayer->m_pInventory->setSelectionSlotItemId(0, pPlayerEquipmentPkt->m_itemID);
|
||||
pPlayer->m_pInventory->selectSlot(0);
|
||||
}
|
||||
|
||||
bool ClientSideNetworkHandler::areAllChunksLoaded()
|
||||
{
|
||||
return m_chunksRequested > 255;
|
||||
}
|
||||
|
||||
void ClientSideNetworkHandler::requestNextChunk()
|
||||
{
|
||||
if (areAllChunksLoaded())
|
||||
return;
|
||||
|
||||
// @BUG: The return value of areAllChunksLoaded() is actually true even before the
|
||||
// 256th chunk is loaded.
|
||||
|
||||
m_pRakNetInstance->send(new RequestChunkPacket(m_chunksRequested % 16, m_chunksRequested / 16));
|
||||
m_chunksRequested++;
|
||||
}
|
||||
|
||||
void ClientSideNetworkHandler::flushAllBufferedUpdates()
|
||||
{
|
||||
for (const SBufferedBlockUpdate& u : m_bufferedBlockUpdates)
|
||||
{
|
||||
m_pLevel->setTileAndData(u.x, u.y, u.z, u.tile, u.data);
|
||||
}
|
||||
}
|
||||
53
source/Network/ClientSideNetworkHandler.hpp
Normal file
53
source/Network/ClientSideNetworkHandler.hpp
Normal file
@@ -0,0 +1,53 @@
|
||||
#pragma once
|
||||
|
||||
#include "NetEventCallback.hpp"
|
||||
#include "Minecraft.hpp"
|
||||
#include "RakNetInstance.hpp"
|
||||
|
||||
struct SBufferedBlockUpdate
|
||||
{
|
||||
int x, z;
|
||||
uint8_t y;
|
||||
uint8_t tile, data;
|
||||
|
||||
SBufferedBlockUpdate(int x, int y, int z, TileID tile, int data) :
|
||||
x(x), y(uint8_t(y)), z(z), tile(uint8_t(tile)), data(uint8_t(data))
|
||||
{}
|
||||
};
|
||||
|
||||
class ClientSideNetworkHandler : public NetEventCallback
|
||||
{
|
||||
public:
|
||||
ClientSideNetworkHandler(Minecraft*, RakNetInstance*);
|
||||
|
||||
void levelGenerated(Level*) override;
|
||||
void onConnect(const RakNet::RakNetGUID&) override;
|
||||
void onDisconnect(const RakNet::RakNetGUID&) override;
|
||||
void onUnableToConnect() override;
|
||||
void handle(const RakNet::RakNetGUID&, MessagePacket*) override;
|
||||
void handle(const RakNet::RakNetGUID&, StartGamePacket*) override;
|
||||
void handle(const RakNet::RakNetGUID&, AddPlayerPacket*) override;
|
||||
void handle(const RakNet::RakNetGUID&, RemoveEntityPacket*) override;
|
||||
void handle(const RakNet::RakNetGUID&, MovePlayerPacket*) override;
|
||||
void handle(const RakNet::RakNetGUID&, PlaceBlockPacket*) override;
|
||||
void handle(const RakNet::RakNetGUID&, RemoveBlockPacket*) override;
|
||||
void handle(const RakNet::RakNetGUID&, UpdateBlockPacket*) override;
|
||||
void handle(const RakNet::RakNetGUID&, ChunkDataPacket*) override;
|
||||
void handle(const RakNet::RakNetGUID&, PlayerEquipmentPacket*) override;
|
||||
|
||||
bool areAllChunksLoaded();
|
||||
void requestNextChunk();
|
||||
void flushAllBufferedUpdates(); // inlined
|
||||
|
||||
private:
|
||||
Minecraft* m_pMinecraft = NULL;
|
||||
Level* m_pLevel = NULL;
|
||||
RakNetInstance* m_pRakNetInstance = NULL;
|
||||
RakNet::RakPeerInterface* m_pServerPeer = NULL;
|
||||
int m_field_14;
|
||||
RakNet::RakNetGUID m_serverGUID;
|
||||
int m_field_24;
|
||||
std::vector<SBufferedBlockUpdate> m_bufferedBlockUpdates;
|
||||
int m_chunksRequested = 0;
|
||||
};
|
||||
|
||||
34
source/Network/MinecraftPackets.cpp
Normal file
34
source/Network/MinecraftPackets.cpp
Normal file
@@ -0,0 +1,34 @@
|
||||
#include "MinecraftPackets.hpp"
|
||||
|
||||
Packet* MinecraftPackets::createPacket(int type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case PACKET_LOGIN:
|
||||
return new LoginPacket;
|
||||
case PACKET_MESSAGE:
|
||||
return new MessagePacket;
|
||||
case PACKET_START_GAME:
|
||||
return new StartGamePacket;
|
||||
case PACKET_ADD_PLAYER:
|
||||
return new AddPlayerPacket;
|
||||
case PACKET_REMOVE_ENTITY:
|
||||
return new RemoveEntityPacket;
|
||||
case PACKET_MOVE_PLAYER:
|
||||
return new MovePlayerPacket;
|
||||
case PACKET_PLACE_BLOCK:
|
||||
return new PlaceBlockPacket;
|
||||
case PACKET_REMOVE_BLOCK:
|
||||
return new RemoveBlockPacket;
|
||||
case PACKET_UPDATE_BLOCK:
|
||||
return new UpdateBlockPacket;
|
||||
case PACKET_REQUEST_CHUNK:
|
||||
return new RequestChunkPacket;
|
||||
case PACKET_CHUNK_DATA:
|
||||
return new ChunkDataPacket;
|
||||
case PACKET_PLAYER_EQUIPMENT:
|
||||
return new PlayerEquipmentPacket;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
10
source/Network/MinecraftPackets.hpp
Normal file
10
source/Network/MinecraftPackets.hpp
Normal file
@@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include "Packet.hpp"
|
||||
|
||||
class MinecraftPackets
|
||||
{
|
||||
public:
|
||||
static Packet* createPacket(int type);
|
||||
};
|
||||
|
||||
70
source/Network/NetEventCallback.cpp
Normal file
70
source/Network/NetEventCallback.cpp
Normal file
@@ -0,0 +1,70 @@
|
||||
#include "NetEventCallback.hpp"
|
||||
|
||||
void NetEventCallback::levelGenerated(Level* level)
|
||||
{
|
||||
}
|
||||
|
||||
void NetEventCallback::onConnect(const RakNet::RakNetGUID& guid)
|
||||
{
|
||||
}
|
||||
|
||||
void NetEventCallback::onUnableToConnect()
|
||||
{
|
||||
}
|
||||
|
||||
void NetEventCallback::onNewClient(const RakNet::RakNetGUID& guid)
|
||||
{
|
||||
}
|
||||
|
||||
void NetEventCallback::onDisconnect(const RakNet::RakNetGUID& guid)
|
||||
{
|
||||
}
|
||||
|
||||
void NetEventCallback::handle(const RakNet::RakNetGUID& guid, LoginPacket* packet)
|
||||
{
|
||||
}
|
||||
|
||||
void NetEventCallback::handle(const RakNet::RakNetGUID& guid, MessagePacket* packet)
|
||||
{
|
||||
}
|
||||
|
||||
void NetEventCallback::handle(const RakNet::RakNetGUID& guid, StartGamePacket* packet)
|
||||
{
|
||||
}
|
||||
|
||||
void NetEventCallback::handle(const RakNet::RakNetGUID& guid, AddPlayerPacket* packet)
|
||||
{
|
||||
}
|
||||
|
||||
void NetEventCallback::handle(const RakNet::RakNetGUID& guid, RemoveEntityPacket* packet)
|
||||
{
|
||||
}
|
||||
|
||||
void NetEventCallback::handle(const RakNet::RakNetGUID& guid, MovePlayerPacket* packet)
|
||||
{
|
||||
}
|
||||
|
||||
void NetEventCallback::handle(const RakNet::RakNetGUID& guid, PlaceBlockPacket* packet)
|
||||
{
|
||||
}
|
||||
|
||||
void NetEventCallback::handle(const RakNet::RakNetGUID& guid, RemoveBlockPacket* packet)
|
||||
{
|
||||
}
|
||||
|
||||
void NetEventCallback::handle(const RakNet::RakNetGUID& guid, UpdateBlockPacket* packet)
|
||||
{
|
||||
}
|
||||
|
||||
void NetEventCallback::handle(const RakNet::RakNetGUID& guid, RequestChunkPacket* packet)
|
||||
{
|
||||
}
|
||||
|
||||
void NetEventCallback::handle(const RakNet::RakNetGUID& guid, ChunkDataPacket* packet)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void NetEventCallback::handle(const RakNet::RakNetGUID& guid, PlayerEquipmentPacket* packet)
|
||||
{
|
||||
}
|
||||
43
source/Network/NetEventCallback.hpp
Normal file
43
source/Network/NetEventCallback.hpp
Normal file
@@ -0,0 +1,43 @@
|
||||
#pragma once
|
||||
|
||||
#include "RakNetTypes.h"
|
||||
#include "Packet.hpp"
|
||||
class Packet;
|
||||
class LoginPacket;
|
||||
class MessagePacket;
|
||||
class StartGamePacket;
|
||||
class AddPlayerPacket;
|
||||
class RemoveEntityPacket;
|
||||
class MovePlayerPacket;
|
||||
class PlaceBlockPacket;
|
||||
class RemoveBlockPacket;
|
||||
class UpdateBlockPacket;
|
||||
class RequestChunkPacket;
|
||||
class ChunkDataPacket;
|
||||
class PlayerEquipmentPacket;
|
||||
#include "Level.hpp"
|
||||
class Level;
|
||||
|
||||
class NetEventCallback
|
||||
{
|
||||
public:
|
||||
virtual ~NetEventCallback() {}
|
||||
virtual void levelGenerated(Level*);
|
||||
virtual void onConnect(const RakNet::RakNetGUID&);
|
||||
virtual void onUnableToConnect();
|
||||
virtual void onNewClient(const RakNet::RakNetGUID&);
|
||||
virtual void onDisconnect(const RakNet::RakNetGUID&);
|
||||
virtual void handle(const RakNet::RakNetGUID&, LoginPacket*);
|
||||
virtual void handle(const RakNet::RakNetGUID&, MessagePacket*);
|
||||
virtual void handle(const RakNet::RakNetGUID&, StartGamePacket*);
|
||||
virtual void handle(const RakNet::RakNetGUID&, AddPlayerPacket*);
|
||||
virtual void handle(const RakNet::RakNetGUID&, RemoveEntityPacket*);
|
||||
virtual void handle(const RakNet::RakNetGUID&, MovePlayerPacket*);
|
||||
virtual void handle(const RakNet::RakNetGUID&, PlaceBlockPacket*);
|
||||
virtual void handle(const RakNet::RakNetGUID&, RemoveBlockPacket*);
|
||||
virtual void handle(const RakNet::RakNetGUID&, UpdateBlockPacket*);
|
||||
virtual void handle(const RakNet::RakNetGUID&, RequestChunkPacket*);
|
||||
virtual void handle(const RakNet::RakNetGUID&, ChunkDataPacket*);
|
||||
virtual void handle(const RakNet::RakNetGUID&, PlayerEquipmentPacket*);
|
||||
};
|
||||
|
||||
225
source/Network/Packet.hpp
Normal file
225
source/Network/Packet.hpp
Normal file
@@ -0,0 +1,225 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include "RakNetTypes.h"
|
||||
#include "BitStream.h"
|
||||
#include "MessageIdentifiers.h"
|
||||
#include "NetEventCallback.hpp"
|
||||
|
||||
class NetEventCallback;
|
||||
class LevelChunk;
|
||||
|
||||
enum ePacketType : uint8_t
|
||||
{
|
||||
PACKET_LOGIN = ID_USER_PACKET_ENUM,
|
||||
PACKET_MESSAGE,
|
||||
PACKET_START_GAME,
|
||||
PACKET_ADD_PLAYER,
|
||||
PACKET_REMOVE_ENTITY,
|
||||
PACKET_MOVE_PLAYER,
|
||||
PACKET_PLACE_BLOCK,
|
||||
PACKET_REMOVE_BLOCK,
|
||||
PACKET_UPDATE_BLOCK,
|
||||
PACKET_REQUEST_CHUNK,
|
||||
PACKET_CHUNK_DATA,
|
||||
PACKET_PLAYER_EQUIPMENT,
|
||||
};
|
||||
|
||||
class Packet
|
||||
{
|
||||
public:
|
||||
virtual ~Packet() {}
|
||||
virtual void write(RakNet::BitStream*) = 0;
|
||||
virtual void read(RakNet::BitStream*) = 0;
|
||||
virtual void handle(const RakNet::RakNetGUID&, NetEventCallback*) = 0;
|
||||
};
|
||||
|
||||
class LoginPacket : public Packet
|
||||
{
|
||||
public:
|
||||
LoginPacket() {}
|
||||
LoginPacket(const std::string& uname) { m_str = RakNet::RakString(uname.c_str()); }
|
||||
|
||||
void handle(const RakNet::RakNetGUID&, NetEventCallback* pCallback) override;
|
||||
void write(RakNet::BitStream*);
|
||||
void read(RakNet::BitStream*);
|
||||
public:
|
||||
RakNet::RakString m_str;
|
||||
};
|
||||
|
||||
class MessagePacket : public Packet
|
||||
{
|
||||
public:
|
||||
MessagePacket() {}
|
||||
MessagePacket(const std::string& msg)
|
||||
{
|
||||
m_str = msg.c_str();
|
||||
}
|
||||
|
||||
void handle(const RakNet::RakNetGUID&, NetEventCallback* pCallback) override;
|
||||
void write(RakNet::BitStream*);
|
||||
void read(RakNet::BitStream*);
|
||||
public:
|
||||
RakNet::RakString m_str;
|
||||
};
|
||||
|
||||
class StartGamePacket : public Packet
|
||||
{
|
||||
public:
|
||||
void handle(const RakNet::RakNetGUID&, NetEventCallback* pCallback) override;
|
||||
void write(RakNet::BitStream*);
|
||||
void read(RakNet::BitStream*);
|
||||
public:
|
||||
long field_4;
|
||||
int field_8;
|
||||
int field_C;
|
||||
float field_10;
|
||||
float field_14;
|
||||
float field_18;
|
||||
};
|
||||
|
||||
class AddPlayerPacket : public Packet
|
||||
{
|
||||
public:
|
||||
AddPlayerPacket() {}
|
||||
AddPlayerPacket(const RakNet::RakNetGUID& guid, RakNet::RakString name, int id, float x, float y, float z);
|
||||
void handle(const RakNet::RakNetGUID&, NetEventCallback* pCallback) override;
|
||||
void write(RakNet::BitStream*);
|
||||
void read(RakNet::BitStream*);
|
||||
public:
|
||||
int field_4;
|
||||
RakNet::RakNetGUID m_guid;
|
||||
int field_14;
|
||||
RakNet::RakString m_name;
|
||||
int m_id;
|
||||
float m_x;
|
||||
float m_y;
|
||||
float m_z;
|
||||
};
|
||||
|
||||
class RemoveEntityPacket : public Packet
|
||||
{
|
||||
public:
|
||||
RemoveEntityPacket() {}
|
||||
RemoveEntityPacket(int id) { m_id = id; }
|
||||
|
||||
void handle(const RakNet::RakNetGUID&, NetEventCallback* pCallback) override;
|
||||
void write(RakNet::BitStream*);
|
||||
void read(RakNet::BitStream*);
|
||||
public:
|
||||
int m_id;
|
||||
};
|
||||
|
||||
class MovePlayerPacket : public Packet
|
||||
{
|
||||
public:
|
||||
MovePlayerPacket() {}
|
||||
MovePlayerPacket(int id, float x, float y, float z, float pitch, float yaw): m_id(id), m_x(x), m_y(y), m_z(z), m_pitch(pitch), m_yaw(yaw) {}
|
||||
void handle(const RakNet::RakNetGUID&, NetEventCallback* pCallback) override;
|
||||
void write(RakNet::BitStream*);
|
||||
void read(RakNet::BitStream*);
|
||||
public:
|
||||
int m_id;
|
||||
float m_x;
|
||||
float m_y;
|
||||
float m_z;
|
||||
float m_pitch;
|
||||
float m_yaw;
|
||||
};
|
||||
|
||||
class PlaceBlockPacket : public Packet
|
||||
{
|
||||
public:
|
||||
PlaceBlockPacket() {}
|
||||
PlaceBlockPacket(int playerID, int x, uint8_t y, int z, uint8_t tile, uint8_t face)
|
||||
{
|
||||
m_playerID = playerID;
|
||||
m_x = x;
|
||||
m_y = y;
|
||||
m_z = z;
|
||||
m_tile = tile;
|
||||
m_face = face;
|
||||
}
|
||||
|
||||
void handle(const RakNet::RakNetGUID&, NetEventCallback* pCallback) override;
|
||||
void write(RakNet::BitStream*);
|
||||
void read(RakNet::BitStream*);
|
||||
public:
|
||||
int m_playerID;
|
||||
int m_x;
|
||||
int m_z;
|
||||
uint8_t m_y;
|
||||
uint8_t m_tile;
|
||||
uint8_t m_face;
|
||||
};
|
||||
|
||||
class RemoveBlockPacket : public Packet
|
||||
{
|
||||
public:
|
||||
RemoveBlockPacket() {}
|
||||
RemoveBlockPacket(int id, int x, int y, int z) :m_playerID(id), m_x(x), m_y(uint8_t(y)), m_z(z) {}
|
||||
|
||||
void handle(const RakNet::RakNetGUID&, NetEventCallback* pCallback) override;
|
||||
void write(RakNet::BitStream*);
|
||||
void read(RakNet::BitStream*);
|
||||
public:
|
||||
int m_playerID;
|
||||
int m_x;
|
||||
int m_z;
|
||||
uint8_t m_y;
|
||||
};
|
||||
|
||||
class UpdateBlockPacket : public Packet
|
||||
{
|
||||
public:
|
||||
void handle(const RakNet::RakNetGUID&, NetEventCallback* pCallback) override;
|
||||
void write(RakNet::BitStream*);
|
||||
void read(RakNet::BitStream*);
|
||||
public:
|
||||
int m_x;
|
||||
int m_z;
|
||||
uint8_t m_y;
|
||||
uint8_t m_tile;
|
||||
uint8_t m_data;
|
||||
};
|
||||
|
||||
class RequestChunkPacket : public Packet
|
||||
{
|
||||
public:
|
||||
RequestChunkPacket() {}
|
||||
RequestChunkPacket(int x, int z) { m_x = x; m_z = z; }
|
||||
void handle(const RakNet::RakNetGUID&, NetEventCallback* pCallback) override;
|
||||
void write(RakNet::BitStream*);
|
||||
void read(RakNet::BitStream*);
|
||||
public:
|
||||
int m_x;
|
||||
int m_z;
|
||||
};
|
||||
|
||||
class ChunkDataPacket : public Packet
|
||||
{
|
||||
public:
|
||||
ChunkDataPacket() {}
|
||||
ChunkDataPacket(int x, int z, LevelChunk* c) :m_x(x), m_z(z), m_pChunk(c) {}
|
||||
void handle(const RakNet::RakNetGUID&, NetEventCallback* pCallback) override;
|
||||
void write(RakNet::BitStream*);
|
||||
void read(RakNet::BitStream*);
|
||||
public:
|
||||
int m_x;
|
||||
int m_z;
|
||||
RakNet::BitStream m_data;
|
||||
LevelChunk* m_pChunk;
|
||||
};
|
||||
|
||||
class PlayerEquipmentPacket : public Packet
|
||||
{
|
||||
public:
|
||||
PlayerEquipmentPacket() {}
|
||||
PlayerEquipmentPacket(int playerID, int itemID): m_playerID(playerID), m_itemID(itemID) {}
|
||||
void handle(const RakNet::RakNetGUID&, NetEventCallback* pCallback) override;
|
||||
void write(RakNet::BitStream*);
|
||||
void read(RakNet::BitStream*);
|
||||
public:
|
||||
int m_playerID;
|
||||
uint8_t m_itemID;
|
||||
};
|
||||
37
source/Network/Packets/AddPlayerPacket.cpp
Normal file
37
source/Network/Packets/AddPlayerPacket.cpp
Normal file
@@ -0,0 +1,37 @@
|
||||
#include "Packet.hpp"
|
||||
|
||||
AddPlayerPacket::AddPlayerPacket(const RakNet::RakNetGUID& guid, RakNet::RakString name, int id, float x, float y, float z)
|
||||
{
|
||||
m_guid = guid;
|
||||
m_name = name;
|
||||
m_id = id;
|
||||
m_x = x;
|
||||
m_y = y;
|
||||
m_z = z;
|
||||
}
|
||||
|
||||
void AddPlayerPacket::handle(const RakNet::RakNetGUID& guid, NetEventCallback* pCallback)
|
||||
{
|
||||
pCallback->handle(guid, this);
|
||||
}
|
||||
|
||||
void AddPlayerPacket::write(RakNet::BitStream* bs)
|
||||
{
|
||||
bs->Write(PACKET_ADD_PLAYER);
|
||||
bs->Write(m_guid);
|
||||
bs->Write(m_name);
|
||||
bs->Write(m_id);
|
||||
bs->Write(m_x);
|
||||
bs->Write(m_y);
|
||||
bs->Write(m_z);
|
||||
}
|
||||
|
||||
void AddPlayerPacket::read(RakNet::BitStream* bs)
|
||||
{
|
||||
bs->Read(m_guid);
|
||||
bs->Read(m_name);
|
||||
bs->Read(m_id);
|
||||
bs->Read(m_x);
|
||||
bs->Read(m_y);
|
||||
bs->Read(m_z);
|
||||
}
|
||||
47
source/Network/Packets/ChunkDataPacket.cpp
Normal file
47
source/Network/Packets/ChunkDataPacket.cpp
Normal file
@@ -0,0 +1,47 @@
|
||||
#include "Packet.hpp"
|
||||
#include "LevelChunk.hpp"
|
||||
|
||||
void ChunkDataPacket::handle(const RakNet::RakNetGUID& guid, NetEventCallback* pCallback)
|
||||
{
|
||||
pCallback->handle(guid, this);
|
||||
}
|
||||
|
||||
void ChunkDataPacket::write(RakNet::BitStream* bs)
|
||||
{
|
||||
bs->Write(PACKET_CHUNK_DATA);
|
||||
bs->Write(m_x);
|
||||
bs->Write(m_z);
|
||||
|
||||
// Well, we first have to prepare the data.
|
||||
m_data.Reset();
|
||||
|
||||
for (int i = 0; i < 256; i++)
|
||||
{
|
||||
m_data.Write(m_pChunk->m_updateMap[i]);
|
||||
|
||||
// if nothing was updated:
|
||||
if (!m_pChunk->m_updateMap[i])
|
||||
continue;
|
||||
|
||||
for (int y = 0; y < 8; y++)
|
||||
{
|
||||
if ((m_pChunk->m_updateMap[i] >> y) & 1)
|
||||
{
|
||||
int idx = ((i & 0xF) << 11) | ((i >> 4) << 7) + (y * 16);
|
||||
//write the tile data
|
||||
|
||||
m_data.Write((const char*) &m_pChunk->m_pBlockData[idx], 16 * sizeof(TileID));
|
||||
m_data.Write((const char*) &m_pChunk->m_tileData [idx >> 1], 8);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bs->Write(m_data);
|
||||
}
|
||||
|
||||
void ChunkDataPacket::read(RakNet::BitStream* bs)
|
||||
{
|
||||
bs->Read(m_x);
|
||||
bs->Read(m_z);
|
||||
bs->Read(m_data);
|
||||
}
|
||||
17
source/Network/Packets/LoginPacket.cpp
Normal file
17
source/Network/Packets/LoginPacket.cpp
Normal file
@@ -0,0 +1,17 @@
|
||||
#include "Packet.hpp"
|
||||
|
||||
void LoginPacket::handle(const RakNet::RakNetGUID& guid, NetEventCallback* pCallback)
|
||||
{
|
||||
pCallback->handle(guid, this);
|
||||
}
|
||||
|
||||
void LoginPacket::write(RakNet::BitStream* bs)
|
||||
{
|
||||
bs->Write(PACKET_LOGIN);
|
||||
bs->Write(m_str);
|
||||
}
|
||||
|
||||
void LoginPacket::read(RakNet::BitStream* bs)
|
||||
{
|
||||
bs->Read(m_str);
|
||||
}
|
||||
17
source/Network/Packets/MessagePacket.cpp
Normal file
17
source/Network/Packets/MessagePacket.cpp
Normal file
@@ -0,0 +1,17 @@
|
||||
#include "Packet.hpp"
|
||||
|
||||
void MessagePacket::handle(const RakNet::RakNetGUID& guid, NetEventCallback* pCallback)
|
||||
{
|
||||
pCallback->handle(guid, this);
|
||||
}
|
||||
|
||||
void MessagePacket::write(RakNet::BitStream* bs)
|
||||
{
|
||||
bs->Write(PACKET_MESSAGE);
|
||||
bs->Write(m_str);
|
||||
}
|
||||
|
||||
void MessagePacket::read(RakNet::BitStream* bs)
|
||||
{
|
||||
bs->Read(m_str);
|
||||
}
|
||||
27
source/Network/Packets/MovePlayerPacket.cpp
Normal file
27
source/Network/Packets/MovePlayerPacket.cpp
Normal file
@@ -0,0 +1,27 @@
|
||||
#include "Packet.hpp"
|
||||
|
||||
void MovePlayerPacket::handle(const RakNet::RakNetGUID& guid, NetEventCallback* pCallback)
|
||||
{
|
||||
pCallback->handle(guid, this);
|
||||
}
|
||||
|
||||
void MovePlayerPacket::write(RakNet::BitStream* bs)
|
||||
{
|
||||
bs->Write(PACKET_MOVE_PLAYER);
|
||||
bs->Write(m_id);
|
||||
bs->Write(m_x);
|
||||
bs->Write(m_y);
|
||||
bs->Write(m_z);
|
||||
bs->Write(m_pitch);
|
||||
bs->Write(m_yaw);
|
||||
}
|
||||
|
||||
void MovePlayerPacket::read(RakNet::BitStream* bs)
|
||||
{
|
||||
bs->Read(m_id);
|
||||
bs->Read(m_x);
|
||||
bs->Read(m_y);
|
||||
bs->Read(m_z);
|
||||
bs->Read(m_pitch);
|
||||
bs->Read(m_yaw);
|
||||
}
|
||||
27
source/Network/Packets/PlaceBlockPacket.cpp
Normal file
27
source/Network/Packets/PlaceBlockPacket.cpp
Normal file
@@ -0,0 +1,27 @@
|
||||
#include "Packet.hpp"
|
||||
|
||||
void PlaceBlockPacket::handle(const RakNet::RakNetGUID& guid, NetEventCallback* pCallback)
|
||||
{
|
||||
pCallback->handle(guid, this);
|
||||
}
|
||||
|
||||
void PlaceBlockPacket::write(RakNet::BitStream* bs)
|
||||
{
|
||||
bs->Write(PACKET_PLACE_BLOCK);
|
||||
bs->Write(m_playerID);
|
||||
bs->Write(m_x);
|
||||
bs->Write(m_z);
|
||||
bs->Write(m_y);
|
||||
bs->Write(m_tile);
|
||||
bs->Write(m_face);
|
||||
}
|
||||
|
||||
void PlaceBlockPacket::read(RakNet::BitStream* bs)
|
||||
{
|
||||
bs->Read(m_playerID);
|
||||
bs->Read(m_x);
|
||||
bs->Read(m_z);
|
||||
bs->Read(m_y);
|
||||
bs->Read(m_tile);
|
||||
bs->Read(m_face);
|
||||
}
|
||||
19
source/Network/Packets/PlayerEquipmentPacket.cpp
Normal file
19
source/Network/Packets/PlayerEquipmentPacket.cpp
Normal file
@@ -0,0 +1,19 @@
|
||||
#include "Packet.hpp"
|
||||
|
||||
void PlayerEquipmentPacket::handle(const RakNet::RakNetGUID& guid, NetEventCallback* pCallback)
|
||||
{
|
||||
pCallback->handle(guid, this);
|
||||
}
|
||||
|
||||
void PlayerEquipmentPacket::write(RakNet::BitStream* bs)
|
||||
{
|
||||
bs->Write(PACKET_PLAYER_EQUIPMENT);
|
||||
bs->Write(m_playerID);
|
||||
bs->Write(m_itemID);
|
||||
}
|
||||
|
||||
void PlayerEquipmentPacket::read(RakNet::BitStream* bs)
|
||||
{
|
||||
bs->Read(m_playerID);
|
||||
bs->Read(m_itemID);
|
||||
}
|
||||
23
source/Network/Packets/RemoveBlockPacket.cpp
Normal file
23
source/Network/Packets/RemoveBlockPacket.cpp
Normal file
@@ -0,0 +1,23 @@
|
||||
#include "Packet.hpp"
|
||||
|
||||
void RemoveBlockPacket::handle(const RakNet::RakNetGUID& guid, NetEventCallback* pCallback)
|
||||
{
|
||||
pCallback->handle(guid, this);
|
||||
}
|
||||
|
||||
void RemoveBlockPacket::write(RakNet::BitStream* bs)
|
||||
{
|
||||
bs->Write(PACKET_REMOVE_BLOCK);
|
||||
bs->Write(m_playerID);
|
||||
bs->Write(m_x);
|
||||
bs->Write(m_z);
|
||||
bs->Write(m_y);
|
||||
}
|
||||
|
||||
void RemoveBlockPacket::read(RakNet::BitStream* bs)
|
||||
{
|
||||
bs->Read(m_playerID);
|
||||
bs->Read(m_x);
|
||||
bs->Read(m_z);
|
||||
bs->Read(m_y);
|
||||
}
|
||||
17
source/Network/Packets/RemoveEntityPacket.cpp
Normal file
17
source/Network/Packets/RemoveEntityPacket.cpp
Normal file
@@ -0,0 +1,17 @@
|
||||
#include "Packet.hpp"
|
||||
|
||||
void RemoveEntityPacket::handle(const RakNet::RakNetGUID& guid, NetEventCallback* pCallback)
|
||||
{
|
||||
pCallback->handle(guid, this);
|
||||
}
|
||||
|
||||
void RemoveEntityPacket::write(RakNet::BitStream* bs)
|
||||
{
|
||||
bs->Write(PACKET_REMOVE_ENTITY);
|
||||
bs->Write(m_id);
|
||||
}
|
||||
|
||||
void RemoveEntityPacket::read(RakNet::BitStream* bs)
|
||||
{
|
||||
bs->Read(m_id);
|
||||
}
|
||||
19
source/Network/Packets/RequestChunkPacket.cpp
Normal file
19
source/Network/Packets/RequestChunkPacket.cpp
Normal file
@@ -0,0 +1,19 @@
|
||||
#include "Packet.hpp"
|
||||
|
||||
void RequestChunkPacket::handle(const RakNet::RakNetGUID& guid, NetEventCallback* pCallback)
|
||||
{
|
||||
pCallback->handle(guid, this);
|
||||
}
|
||||
|
||||
void RequestChunkPacket::write(RakNet::BitStream* bs)
|
||||
{
|
||||
bs->Write(PACKET_REQUEST_CHUNK);
|
||||
bs->Write(m_x);
|
||||
bs->Write(m_z);
|
||||
}
|
||||
|
||||
void RequestChunkPacket::read(RakNet::BitStream* bs)
|
||||
{
|
||||
bs->Read(m_x);
|
||||
bs->Read(m_z);
|
||||
}
|
||||
27
source/Network/Packets/StartGamePacket.cpp
Normal file
27
source/Network/Packets/StartGamePacket.cpp
Normal file
@@ -0,0 +1,27 @@
|
||||
#include "Packet.hpp"
|
||||
|
||||
void StartGamePacket::handle(const RakNet::RakNetGUID& guid, NetEventCallback* pCallback)
|
||||
{
|
||||
pCallback->handle(guid, this);
|
||||
}
|
||||
|
||||
void StartGamePacket::write(RakNet::BitStream* bs)
|
||||
{
|
||||
bs->Write(PACKET_START_GAME);
|
||||
bs->Write(field_4);
|
||||
bs->Write(field_8);
|
||||
bs->Write(field_C);
|
||||
bs->Write(field_10);
|
||||
bs->Write(field_14);
|
||||
bs->Write(field_18);
|
||||
}
|
||||
|
||||
void StartGamePacket::read(RakNet::BitStream* bs)
|
||||
{
|
||||
bs->Read(field_4);
|
||||
bs->Read(field_8);
|
||||
bs->Read(field_C);
|
||||
bs->Read(field_10);
|
||||
bs->Read(field_14);
|
||||
bs->Read(field_18);
|
||||
}
|
||||
25
source/Network/Packets/UpdateBlockPacket.cpp
Normal file
25
source/Network/Packets/UpdateBlockPacket.cpp
Normal file
@@ -0,0 +1,25 @@
|
||||
#include "Packet.hpp"
|
||||
|
||||
void UpdateBlockPacket::handle(const RakNet::RakNetGUID& guid, NetEventCallback* pCallback)
|
||||
{
|
||||
pCallback->handle(guid, this);
|
||||
}
|
||||
|
||||
void UpdateBlockPacket::write(RakNet::BitStream* bs)
|
||||
{
|
||||
bs->Write(PACKET_UPDATE_BLOCK);
|
||||
bs->Write(m_x);
|
||||
bs->Write(m_z);
|
||||
bs->Write(m_y);
|
||||
bs->Write(m_tile);
|
||||
bs->Write(m_data);
|
||||
}
|
||||
|
||||
void UpdateBlockPacket::read(RakNet::BitStream* bs)
|
||||
{
|
||||
bs->Read(m_x);
|
||||
bs->Read(m_z);
|
||||
bs->Read(m_y);
|
||||
bs->Read(m_tile);
|
||||
bs->Read(m_data);
|
||||
}
|
||||
13
source/Network/PingedCompatibleServer.hpp
Normal file
13
source/Network/PingedCompatibleServer.hpp
Normal file
@@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include "RakNetTypes.h"
|
||||
#include "RakString.h"
|
||||
|
||||
|
||||
struct PingedCompatibleServer
|
||||
{
|
||||
RakNet::RakString m_name;
|
||||
RakNet::SystemAddress m_address;
|
||||
int m_lastPinged;
|
||||
};
|
||||
268
source/Network/RakNetInstance.cpp
Normal file
268
source/Network/RakNetInstance.cpp
Normal file
@@ -0,0 +1,268 @@
|
||||
#include "RakNetInstance.hpp"
|
||||
#include "MinecraftPackets.hpp"
|
||||
#include "GetTime.h"
|
||||
|
||||
RakNetInstance::RakNetInstance()
|
||||
{
|
||||
m_pRakPeerInterface = RakNet::RakPeerInterface::GetInstance();
|
||||
m_pRakPeerInterface->SetOccasionalPing(true);
|
||||
}
|
||||
|
||||
RakNetInstance::~RakNetInstance()
|
||||
{
|
||||
if (m_pRakPeerInterface)
|
||||
{
|
||||
m_pRakPeerInterface->Shutdown(100);
|
||||
RakNet::RakPeerInterface::DestroyInstance(m_pRakPeerInterface);
|
||||
m_pRakPeerInterface = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void RakNetInstance::announceServer(const std::string& name)
|
||||
{
|
||||
if (m_bIsHost && m_pRakPeerInterface->IsActive())
|
||||
{
|
||||
RakNet::RakString rs;
|
||||
rs += "MCCPP;Demo;"; // @NOTE: still adding 'Demo' despite not actually being a demo.
|
||||
rs += name.c_str();
|
||||
|
||||
RakNet::BitStream bs;
|
||||
rs.Serialize(&bs);
|
||||
|
||||
m_pRakPeerInterface->SetOfflinePingResponse((const char*)bs.GetData(), bs.GetNumberOfBytesUsed());
|
||||
}
|
||||
}
|
||||
|
||||
void RakNetInstance::clearServerList()
|
||||
{
|
||||
m_servers.clear();
|
||||
}
|
||||
|
||||
bool RakNetInstance::connect(const char* host, int port)
|
||||
{
|
||||
RakNet::SocketDescriptor sd;
|
||||
|
||||
disconnect();
|
||||
|
||||
if (m_pRakPeerInterface->Startup(4, &sd, 1) != RakNet::RAKNET_STARTED)
|
||||
return false;
|
||||
|
||||
return m_pRakPeerInterface->Connect(host, port, nullptr, 0);
|
||||
}
|
||||
|
||||
void RakNetInstance::disconnect()
|
||||
{
|
||||
if (m_pRakPeerInterface->IsActive())
|
||||
m_pRakPeerInterface->Shutdown(500);
|
||||
|
||||
m_bIsHost = false;
|
||||
m_bPingingForHosts = false;
|
||||
}
|
||||
|
||||
RakNet::RakPeerInterface* RakNetInstance::getPeer()
|
||||
{
|
||||
return m_pRakPeerInterface;
|
||||
}
|
||||
|
||||
std::vector<PingedCompatibleServer>* RakNetInstance::getServerList()
|
||||
{
|
||||
return &m_servers;
|
||||
}
|
||||
|
||||
bool RakNetInstance::host(const std::string& name, int port, int maxConnections)
|
||||
{
|
||||
if (m_pRakPeerInterface->IsActive())
|
||||
m_pRakPeerInterface->Shutdown(500);
|
||||
|
||||
RakNet::SocketDescriptor sd(port, nullptr);
|
||||
|
||||
m_pRakPeerInterface->SetMaximumIncomingConnections(maxConnections);
|
||||
int result = m_pRakPeerInterface->Startup(maxConnections, &sd, 1);
|
||||
|
||||
m_bIsHost = true;
|
||||
m_bPingingForHosts = false;
|
||||
|
||||
return result == RakNet::RAKNET_STARTED;
|
||||
}
|
||||
|
||||
bool RakNetInstance::isMyLocalGuid(const RakNet::RakNetGUID& guid)
|
||||
{
|
||||
if (!m_pRakPeerInterface->IsActive())
|
||||
return false;
|
||||
|
||||
return m_pRakPeerInterface->GetMyGUID() == guid;
|
||||
}
|
||||
|
||||
void RakNetInstance::pingForHosts(int port)
|
||||
{
|
||||
if (!m_pRakPeerInterface->IsActive())
|
||||
{
|
||||
RakNet::SocketDescriptor sd;
|
||||
m_pRakPeerInterface->Startup(4, &sd, 1);
|
||||
}
|
||||
|
||||
m_hostPingPort = port;
|
||||
m_bPingingForHosts = true;
|
||||
m_startedPingingAt = RakNet::GetTimeMS();
|
||||
|
||||
m_pRakPeerInterface->Ping("255.255.255.255", port, true, 0);
|
||||
}
|
||||
|
||||
void RakNetInstance::runEvents(NetEventCallback* callback)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
RakNet::Packet* pPacket = m_pRakPeerInterface->Receive();
|
||||
|
||||
if (!pPacket)
|
||||
break;
|
||||
|
||||
int packetType = *pPacket->data;
|
||||
|
||||
RakNet::BitStream* pBitStream = new RakNet::BitStream(pPacket->data + 1, pPacket->length - 1, 0);
|
||||
|
||||
// @NOTE: why -1?
|
||||
if (packetType >= PACKET_LOGIN - 1)
|
||||
{
|
||||
Packet* pUserPacket = MinecraftPackets::createPacket(packetType);
|
||||
if (pUserPacket)
|
||||
{
|
||||
pUserPacket->read(pBitStream);
|
||||
pUserPacket->handle(pPacket->guid, callback);
|
||||
delete pUserPacket;
|
||||
}
|
||||
}
|
||||
else switch (packetType)
|
||||
{
|
||||
case ID_CONNECTION_REQUEST_ACCEPTED:
|
||||
{
|
||||
// @BUG: Two players sending connection requests at the same time could cause one of them to fail to connect
|
||||
m_guid = pPacket->guid;
|
||||
callback->onConnect(pPacket->guid);
|
||||
break;
|
||||
}
|
||||
case ID_CONNECTION_ATTEMPT_FAILED:
|
||||
{
|
||||
callback->onUnableToConnect();
|
||||
break;
|
||||
}
|
||||
case ID_NEW_INCOMING_CONNECTION:
|
||||
{
|
||||
callback->onNewClient(pPacket->guid);
|
||||
break;
|
||||
}
|
||||
case ID_DISCONNECTION_NOTIFICATION:
|
||||
case ID_CONNECTION_LOST:
|
||||
{
|
||||
callback->onDisconnect(pPacket->guid);
|
||||
break;
|
||||
}
|
||||
case ID_UNCONNECTED_PONG:
|
||||
{
|
||||
unsigned int thing;
|
||||
RakNet::RakString serverInfo, mccppDemo = "MCCPP;Demo;";
|
||||
pBitStream->Read(thing);
|
||||
pBitStream->Read(serverInfo);
|
||||
|
||||
// check if the server info starts with MCCPP;Demo;
|
||||
if (serverInfo.GetLength() < mccppDemo.GetLength())
|
||||
break;
|
||||
|
||||
RakNet::RakString headerSubstr = serverInfo.SubStr(0, unsigned(mccppDemo.GetLength()));
|
||||
if (mccppDemo.StrCmp(headerSubstr) != 0)
|
||||
break;
|
||||
|
||||
// update the info of a pinged compatible server, if possible.
|
||||
for (PingedCompatibleServer& server : m_servers)
|
||||
{
|
||||
if (server.m_address == pPacket->systemAddress)
|
||||
{
|
||||
server.m_lastPinged = RakNet::GetTimeMS();
|
||||
server.m_name = serverInfo.SubStr(unsigned(mccppDemo.GetLength()), unsigned(serverInfo.GetLength() - mccppDemo.GetLength()));
|
||||
goto SKIP_ADDING_NEW_ENTRY;
|
||||
}
|
||||
}
|
||||
|
||||
// Add a new entry.
|
||||
{
|
||||
PingedCompatibleServer pcs;
|
||||
pcs.m_address = pPacket->systemAddress;
|
||||
pcs.m_lastPinged = RakNet::GetTimeMS();
|
||||
pcs.m_name = serverInfo.SubStr(unsigned(mccppDemo.GetLength()), unsigned(serverInfo.GetLength() - mccppDemo.GetLength()));
|
||||
m_servers.push_back(pcs);
|
||||
}
|
||||
|
||||
|
||||
SKIP_ADDING_NEW_ENTRY:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
m_pRakPeerInterface->DeallocatePacket(pPacket);
|
||||
if (pBitStream)
|
||||
delete pBitStream;
|
||||
}
|
||||
|
||||
if (m_bPingingForHosts)
|
||||
{
|
||||
int timeDiff = RakNet::GetTimeMS() - m_startedPingingAt;
|
||||
if (timeDiff > 1000)
|
||||
{
|
||||
for (auto it = m_servers.begin(); it != m_servers.end(); )
|
||||
{
|
||||
if (RakNet::GetTimeMS() - it->m_lastPinged <= 3000)
|
||||
{
|
||||
it++;
|
||||
continue;
|
||||
}
|
||||
|
||||
it = m_servers.erase(it);
|
||||
}
|
||||
|
||||
pingForHosts(m_hostPingPort);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// this broadcasts a packet to all other connected peers
|
||||
void RakNetInstance::send(Packet* packet)
|
||||
{
|
||||
RakNet::BitStream bs;
|
||||
packet->write(&bs);
|
||||
|
||||
if (m_bIsHost)
|
||||
{
|
||||
m_pRakPeerInterface->Send(&bs, HIGH_PRIORITY, RELIABLE, 0, RakNet::AddressOrGUID(), true);
|
||||
}
|
||||
else
|
||||
{
|
||||
// send it to the host instead
|
||||
m_pRakPeerInterface->Send(&bs, HIGH_PRIORITY, RELIABLE, 0, m_guid, false);
|
||||
}
|
||||
|
||||
delete packet;
|
||||
// return 1300; --- ida tells me this returns 1300. Huh
|
||||
}
|
||||
|
||||
// this sends a specific peer a message
|
||||
void RakNetInstance::send(const RakNet::RakNetGUID& guid, Packet* packet)
|
||||
{
|
||||
RakNet::BitStream bs;
|
||||
packet->write(&bs);
|
||||
|
||||
m_pRakPeerInterface->Send(&bs, HIGH_PRIORITY, RELIABLE, 0, guid, true);
|
||||
|
||||
delete packet;
|
||||
// return 1300; --- ida tells me this returns 1300. Huh
|
||||
}
|
||||
|
||||
void RakNetInstance::stopPingForHosts()
|
||||
{
|
||||
if (!m_bPingingForHosts)
|
||||
return;
|
||||
|
||||
m_pRakPeerInterface->Shutdown(0);
|
||||
m_bPingingForHosts = false;
|
||||
}
|
||||
|
||||
|
||||
42
source/Network/RakNetInstance.hpp
Normal file
42
source/Network/RakNetInstance.hpp
Normal file
@@ -0,0 +1,42 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "PingedCompatibleServer.hpp"
|
||||
#include "BitStream.h"
|
||||
#include "RakPeerInterface.h"
|
||||
#include "Packet.hpp"
|
||||
|
||||
class Packet;
|
||||
|
||||
class RakNetInstance
|
||||
{
|
||||
public:
|
||||
RakNetInstance();
|
||||
~RakNetInstance();
|
||||
void announceServer(const std::string& name);
|
||||
void clearServerList();
|
||||
bool connect(const char* host, int port);
|
||||
void disconnect();
|
||||
RakNet::RakPeerInterface* getPeer();
|
||||
std::vector<PingedCompatibleServer>* getServerList();
|
||||
bool host(const std::string& name, int port, int maxConnections);
|
||||
bool isMyLocalGuid(const RakNet::RakNetGUID& guid);
|
||||
void pingForHosts(int port);
|
||||
void runEvents(NetEventCallback*);
|
||||
void send(Packet* packet);
|
||||
void send(const RakNet::RakNetGUID& guid, Packet* packet);
|
||||
void stopPingForHosts();
|
||||
|
||||
public:
|
||||
RakNet::RakPeerInterface* m_pRakPeerInterface = nullptr;
|
||||
bool m_bIsHost = false;
|
||||
int field_C;
|
||||
RakNet::RakNetGUID m_guid;
|
||||
int field_1C;
|
||||
std::vector<PingedCompatibleServer> m_servers;
|
||||
bool m_bPingingForHosts;
|
||||
int m_hostPingPort;
|
||||
int m_startedPingingAt;
|
||||
};
|
||||
|
||||
270
source/Network/ServerSideNetworkHandler.cpp
Normal file
270
source/Network/ServerSideNetworkHandler.cpp
Normal file
@@ -0,0 +1,270 @@
|
||||
#include "ServerSideNetworkHandler.hpp"
|
||||
|
||||
// This lets you make the server shut up and not log events in the debug console.
|
||||
#define VERBOSE_SERVER
|
||||
|
||||
#if defined(ORIGINAL_CODE) || defined(VERBOSE_SERVER)
|
||||
#define puts_ignorable(str) puts(str)
|
||||
#define printf_ignorable(str, ...) printf(str, __VA_ARGS__)
|
||||
#else
|
||||
#define puts_ignorable(str)
|
||||
#define printf_ignorable(str, ...)
|
||||
#endif
|
||||
|
||||
ServerSideNetworkHandler::ServerSideNetworkHandler(Minecraft* minecraft, RakNetInstance* rakNetInstance)
|
||||
{
|
||||
m_pMinecraft = minecraft;
|
||||
m_pRakNetInstance = rakNetInstance;
|
||||
allowIncomingConnections(false);
|
||||
m_pRakNetPeer = m_pRakNetInstance->getPeer();
|
||||
}
|
||||
|
||||
ServerSideNetworkHandler::~ServerSideNetworkHandler()
|
||||
{
|
||||
if (m_pLevel)
|
||||
m_pLevel->removeListener(this);
|
||||
}
|
||||
|
||||
void ServerSideNetworkHandler::levelGenerated(Level* level)
|
||||
{
|
||||
m_pLevel = level;
|
||||
|
||||
if (m_pMinecraft->m_pLocalPlayer)
|
||||
{
|
||||
m_pMinecraft->m_pLocalPlayer->m_guid = m_pRakNetPeer->GetMyGUID();
|
||||
}
|
||||
|
||||
level->addListener(this);
|
||||
|
||||
allowIncomingConnections(m_pMinecraft->m_options.m_bServerVisibleDefault);
|
||||
}
|
||||
|
||||
void ServerSideNetworkHandler::onNewClient(const RakNet::RakNetGUID& guid)
|
||||
{
|
||||
printf_ignorable("onNewClient, client guid: %s\n", guid.ToString());
|
||||
}
|
||||
|
||||
void ServerSideNetworkHandler::onDisconnect(const RakNet::RakNetGUID& guid)
|
||||
{
|
||||
puts_ignorable("onDisconnect");
|
||||
|
||||
for (Player* pPlayer : m_pLevel->m_players)
|
||||
{
|
||||
if (pPlayer->m_guid != guid)
|
||||
continue;
|
||||
|
||||
displayGameMessage(pPlayer->m_name + " disconnected from the game");
|
||||
|
||||
m_pRakNetInstance->send(new RemoveEntityPacket(pPlayer->m_EntityID));
|
||||
|
||||
m_pLevel->removeEntity(pPlayer);
|
||||
}
|
||||
}
|
||||
|
||||
void ServerSideNetworkHandler::handle(const RakNet::RakNetGUID& guid, LoginPacket* packet)
|
||||
{
|
||||
if (!m_bAllowIncoming)
|
||||
return;
|
||||
|
||||
puts_ignorable("LoginPacket");
|
||||
|
||||
Player* pPlayer = new Player(m_pLevel);
|
||||
pPlayer->m_guid = guid;
|
||||
pPlayer->m_name = std::string(packet->m_str.C_String());
|
||||
|
||||
StartGamePacket sgp;
|
||||
sgp.field_4 = m_pLevel->getSeed();
|
||||
sgp.field_8 = m_pLevel->getLevelData()->field_20;
|
||||
sgp.field_C = pPlayer->m_EntityID;
|
||||
sgp.field_10 = pPlayer->m_pos.x;
|
||||
sgp.field_14 = pPlayer->m_pos.y - pPlayer->field_84;
|
||||
sgp.field_18 = pPlayer->m_pos.z;
|
||||
|
||||
RakNet::BitStream sgpbs;
|
||||
sgp.write(&sgpbs);
|
||||
m_pRakNetPeer->Send(&sgpbs, HIGH_PRIORITY, RELIABLE_ORDERED, 0, guid, false);
|
||||
|
||||
// send the connecting player info about all other players in the world
|
||||
for (Player* player : m_pLevel->m_players)
|
||||
{
|
||||
AddPlayerPacket app(player->m_guid, RakNet::RakString(player->m_name.c_str()), player->m_EntityID, player->m_pos.x, player->m_pos.y - player->field_84, player->m_pos.z);
|
||||
RakNet::BitStream appbs;
|
||||
app.write(&appbs);
|
||||
m_pRakNetPeer->Send(&appbs, HIGH_PRIORITY, RELIABLE_ORDERED, 0, guid, false);
|
||||
}
|
||||
|
||||
m_pLevel->addEntity(pPlayer);
|
||||
|
||||
m_pMinecraft->m_gui.addMessage(pPlayer->m_name + " joined the game");
|
||||
|
||||
AddPlayerPacket app(guid, RakNet::RakString(pPlayer->m_name.c_str()), pPlayer->m_EntityID, pPlayer->m_pos.x, pPlayer->m_pos.y - pPlayer->field_84, pPlayer->m_pos.z);
|
||||
RakNet::BitStream appbs;
|
||||
app.write(&appbs);
|
||||
m_pRakNetPeer->Send(&appbs, HIGH_PRIORITY, RELIABLE_ORDERED, 0, guid, true);
|
||||
}
|
||||
|
||||
void ServerSideNetworkHandler::handle(const RakNet::RakNetGUID& guid, MovePlayerPacket* packet)
|
||||
{
|
||||
//not in the original
|
||||
puts_ignorable("MovePlayerPacket");
|
||||
|
||||
Entity* pEntity = m_pLevel->getEntity(packet->m_id);
|
||||
if (pEntity)
|
||||
pEntity->lerpTo(packet->m_x, packet->m_y, packet->m_z, packet->m_yaw, packet->m_pitch, 3);
|
||||
|
||||
redistributePacket(packet, guid);
|
||||
}
|
||||
|
||||
void ServerSideNetworkHandler::handle(const RakNet::RakNetGUID& guid, PlaceBlockPacket* packet)
|
||||
{
|
||||
puts_ignorable("PlaceBlockPacket");
|
||||
|
||||
Mob* pMob = (Mob*)m_pLevel->getEntity(packet->m_playerID);
|
||||
if (!pMob)
|
||||
return;
|
||||
|
||||
TileID tile = packet->m_tile;
|
||||
int face = packet->m_face;
|
||||
int x = packet->m_x;
|
||||
int y = packet->m_y;
|
||||
int z = packet->m_z;
|
||||
|
||||
if (!m_pLevel->mayPlace(tile, x, y, z, true))
|
||||
return;
|
||||
|
||||
if (m_pLevel->setTile(x, y, z, tile))
|
||||
{
|
||||
Tile::tiles[tile]->setPlacedOnFace(m_pLevel, x, y, z, face);
|
||||
Tile::tiles[tile]->setPlacedBy(m_pLevel, x, y, z, pMob);
|
||||
|
||||
const Tile::SoundType* pSound = Tile::tiles[tile]->m_pSound;
|
||||
m_pLevel->playSound(float(x) + 0.5f, float(y) + 0.5f, float(z) + 0.5f, "step." + pSound->m_name, 0.5f * (pSound->field_18 + 1.0f), pSound->field_1C * 0.8f);
|
||||
}
|
||||
|
||||
redistributePacket(packet, guid);
|
||||
}
|
||||
|
||||
void ServerSideNetworkHandler::handle(const RakNet::RakNetGUID& guid, RemoveBlockPacket* packet)
|
||||
{
|
||||
puts_ignorable("RemoveBlockPacket");
|
||||
|
||||
Player* pPlayer = (Player*)m_pLevel->getEntity(packet->m_playerID);
|
||||
if (!pPlayer)
|
||||
return;
|
||||
|
||||
int x = packet->m_x;
|
||||
int y = packet->m_y;
|
||||
int z = packet->m_z;
|
||||
|
||||
Tile* pTile = Tile::tiles[m_pLevel->getTile(x, y, z)];
|
||||
int data = m_pLevel->getData(x, y, z);
|
||||
bool setTileResult = m_pLevel->setTile(x, y, z, TILE_AIR);
|
||||
if (pTile && setTileResult)
|
||||
{
|
||||
const Tile::SoundType* pSound = pTile->m_pSound;
|
||||
m_pMinecraft->m_pSoundEngine->play("step." + pSound->m_name, float(x) + 0.5f, float(y) + 0.5f, float(z) + 0.5f, 0.5f * (pSound->field_18 + 1.0f), pSound->field_1C * 0.8f);
|
||||
|
||||
// redistribute the packet only if needed
|
||||
redistributePacket(packet, guid);
|
||||
}
|
||||
}
|
||||
|
||||
void ServerSideNetworkHandler::handle(const RakNet::RakNetGUID& guid, PlayerEquipmentPacket* packet)
|
||||
{
|
||||
Player* pPlayer = (Player*)m_pLevel->getEntity(packet->m_playerID);
|
||||
if (!pPlayer)
|
||||
{
|
||||
LogMsg("No player with id %d", packet->m_playerID);
|
||||
return;
|
||||
}
|
||||
|
||||
#ifndef ORIGINAL_CODE
|
||||
if (!Item::items[packet->m_itemID])
|
||||
{
|
||||
LogMsg("That item %d doesn't actually exist!", packet->m_itemID);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (pPlayer->m_guid == m_pRakNetPeer->GetMyGUID())
|
||||
{
|
||||
puts("Attempted to modify local player's inventory");
|
||||
return;
|
||||
}
|
||||
|
||||
pPlayer->m_pInventory->setSelectionSlotItemId(0, packet->m_itemID);
|
||||
pPlayer->m_pInventory->selectSlot(0);
|
||||
|
||||
redistributePacket(packet, guid);
|
||||
}
|
||||
|
||||
void ServerSideNetworkHandler::handle(const RakNet::RakNetGUID& guid, RequestChunkPacket* packet)
|
||||
{
|
||||
puts_ignorable("RequestChunkPacket");
|
||||
|
||||
LevelChunk* pChunk = m_pLevel->getChunk(packet->m_x, packet->m_z);
|
||||
if (!pChunk)
|
||||
{
|
||||
LogMsg("No chunk at %d, %d", packet->m_x, packet->m_z);
|
||||
return;
|
||||
}
|
||||
|
||||
// @NOTE: this allows the client to request empty chunks. Is that okay?
|
||||
ChunkDataPacket cdp(pChunk->m_chunkX, pChunk->m_chunkZ, pChunk);
|
||||
|
||||
RakNet::BitStream bs;
|
||||
cdp.write(&bs);
|
||||
|
||||
m_pRakNetPeer->Send(&bs, HIGH_PRIORITY, RELIABLE_ORDERED, 0, guid, false);
|
||||
}
|
||||
|
||||
void ServerSideNetworkHandler::tileBrightnessChanged(int x, int y, int z)
|
||||
{
|
||||
}
|
||||
|
||||
void ServerSideNetworkHandler::tileChanged(int x, int y, int z)
|
||||
{
|
||||
UpdateBlockPacket ubp;
|
||||
|
||||
int tile = m_pLevel->getTile(x, y, z);
|
||||
int data = m_pLevel->getData(x, y, z);
|
||||
|
||||
ubp.m_x = x;
|
||||
ubp.m_y = y;
|
||||
ubp.m_z = z;
|
||||
ubp.m_tile = uint8_t(tile);
|
||||
ubp.m_data = uint8_t(data);
|
||||
|
||||
RakNet::BitStream bs;
|
||||
ubp.write(&bs);
|
||||
|
||||
m_pRakNetPeer->Send(&bs, HIGH_PRIORITY, RELIABLE_ORDERED, 0, RakNet::AddressOrGUID(), true);
|
||||
}
|
||||
|
||||
void ServerSideNetworkHandler::allowIncomingConnections(bool b)
|
||||
{
|
||||
if (b)
|
||||
{
|
||||
m_pRakNetInstance->announceServer(m_pMinecraft->m_options.m_playerName);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pRakNetInstance->announceServer("");
|
||||
}
|
||||
|
||||
m_bAllowIncoming = b;
|
||||
}
|
||||
|
||||
void ServerSideNetworkHandler::displayGameMessage(const std::string& msg)
|
||||
{
|
||||
m_pMinecraft->m_gui.addMessage(msg);
|
||||
m_pRakNetInstance->send(new MessagePacket(msg));
|
||||
}
|
||||
|
||||
void ServerSideNetworkHandler::redistributePacket(Packet* packet, const RakNet::RakNetGUID& source)
|
||||
{
|
||||
RakNet::BitStream bs;
|
||||
packet->write(&bs);
|
||||
|
||||
m_pRakNetPeer->Send(&bs, HIGH_PRIORITY, RELIABLE_ORDERED, 0, source, true);
|
||||
}
|
||||
41
source/Network/ServerSideNetworkHandler.hpp
Normal file
41
source/Network/ServerSideNetworkHandler.hpp
Normal file
@@ -0,0 +1,41 @@
|
||||
#pragma once
|
||||
|
||||
#include "NetEventCallback.hpp"
|
||||
#include "Minecraft.hpp"
|
||||
#include "RakNetInstance.hpp"
|
||||
#include "LevelListener.hpp"
|
||||
class Minecraft;
|
||||
|
||||
class ServerSideNetworkHandler : public NetEventCallback, public LevelListener
|
||||
{
|
||||
public:
|
||||
ServerSideNetworkHandler(Minecraft*, RakNetInstance*);
|
||||
~ServerSideNetworkHandler();
|
||||
|
||||
// Overridden from NetEventCallback
|
||||
void levelGenerated(Level*) override;
|
||||
void onNewClient(const RakNet::RakNetGUID&) override;
|
||||
void onDisconnect(const RakNet::RakNetGUID&) override;
|
||||
void handle(const RakNet::RakNetGUID&, LoginPacket*) override;
|
||||
void handle(const RakNet::RakNetGUID&, MovePlayerPacket*) override;
|
||||
void handle(const RakNet::RakNetGUID&, PlaceBlockPacket*) override;
|
||||
void handle(const RakNet::RakNetGUID&, RemoveBlockPacket*) override;
|
||||
void handle(const RakNet::RakNetGUID&, PlayerEquipmentPacket*) override;
|
||||
void handle(const RakNet::RakNetGUID&, RequestChunkPacket*) override;
|
||||
|
||||
// Overridden from LevelListener
|
||||
void tileBrightnessChanged(int x, int y, int z) override;
|
||||
void tileChanged(int x, int y, int z) override;
|
||||
|
||||
void allowIncomingConnections(bool b);
|
||||
void displayGameMessage(const std::string&);
|
||||
void redistributePacket(Packet* packet, const RakNet::RakNetGUID& source);
|
||||
|
||||
public:
|
||||
Minecraft* m_pMinecraft = nullptr;
|
||||
Level* m_pLevel = nullptr;
|
||||
RakNetInstance* m_pRakNetInstance = nullptr;
|
||||
RakNet::RakPeerInterface* m_pRakNetPeer = nullptr;
|
||||
bool m_bAllowIncoming = false;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user