164 lines
6.2 KiB
C++
164 lines
6.2 KiB
C++
//
|
|
// Created by aurailus on 11/01/19.
|
|
//
|
|
|
|
#include <iostream>
|
|
|
|
#include "ClientNetworkInterpreter.h"
|
|
|
|
#include "../PacketView.h"
|
|
#include "../Serializer.h"
|
|
#include "../NetHandler.h"
|
|
#include "../../util/Log.h"
|
|
#include "NetPlayerField.h"
|
|
#include "../../game/entity/Model.h"
|
|
#include "../../game/scene/world/Player.h"
|
|
#include "../../game/scene/world/LocalWorld.h"
|
|
|
|
ClientNetworkInterpreter::ClientNetworkInterpreter(ServerConnection &connection, LocalSubgame &defs, Player& player) :
|
|
player(player),
|
|
connection(connection),
|
|
playerModel(std::make_shared<Model>()) {
|
|
playerModel->fromSerialized(defs.models.models["zeus:default:player"], { defs.textures["zeus:default:player"] });
|
|
}
|
|
|
|
void ClientNetworkInterpreter::init(LocalWorld *world, std::function<void(std::unique_ptr<PacketView>)> invCallback) {
|
|
this->world = world;
|
|
this->onInvPacket = invCallback;
|
|
}
|
|
|
|
void ClientNetworkInterpreter::update() {
|
|
recvPackets = 0;
|
|
|
|
ENetEvent event;
|
|
while (connection.pollEvents(&event)) {
|
|
recvPackets++;
|
|
|
|
switch (event.type) {
|
|
default: break;
|
|
case ENET_EVENT_TYPE_CONNECT: {
|
|
std::cout << Log::info << "Connected to server "
|
|
<< NetHandler::intToIPString(event.peer->address.host)
|
|
<< ":" << event.peer->address.port << "." << Log::endl;
|
|
break;
|
|
}
|
|
case ENET_EVENT_TYPE_RECEIVE: {
|
|
std::unique_ptr<PacketView> p = std::make_unique<PacketView>(event.packet);
|
|
receivedPacket(std::move(p));
|
|
break;
|
|
}
|
|
case ENET_EVENT_TYPE_DISCONNECT: {
|
|
std::cout << Log::info << "Disconnected from server "
|
|
<< event.peer->address.host << ":" << event.peer->address.port << "." << Log::endl;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
//Send Player Position
|
|
Packet p(PacketType::PLAYER_INFO);
|
|
p.data = Serializer()
|
|
.append(player.getPos())
|
|
.append(player.getPitch())
|
|
.append(player.getYaw())
|
|
.data;
|
|
|
|
p.sendTo(connection.getPeer(), PacketChannel::INTERACT);
|
|
}
|
|
|
|
void ClientNetworkInterpreter::receivedPacket(std::unique_ptr<PacketView> p) {
|
|
switch (p->type) {
|
|
default:
|
|
std::cout << Log::err << "Received unknown packet of type " << static_cast<int>(p->type)
|
|
<< ". Is the server on a different protocol version?" << Log::endl; break;
|
|
|
|
case PacketType::SERVER_INFO:
|
|
serverSideChunkGens = p->d.read<unsigned int>(); break;
|
|
|
|
case PacketType::THIS_PLAYER_INFO:
|
|
player.handleAssertion(p->d); break;
|
|
|
|
case PacketType::PLAYER_INFO: {
|
|
unsigned int cid = p->d.read<unsigned int>();
|
|
if (player.id == cid) break;
|
|
|
|
bool found = false;
|
|
for (auto& entity : world->dimension.playerEntities) {
|
|
if (entity.getCid() == cid) {
|
|
entity.interpPos(p->d.read<glm::vec3>());
|
|
entity.interpRotateZ(-p->d.read<float>() + 90);
|
|
entity.interpRotateY(-p->d.read<float>() + 90);
|
|
|
|
found = true;
|
|
break;
|
|
}
|
|
}
|
|
if (found) break;
|
|
|
|
// Instantiate a new PlayerEntity
|
|
world->dimension.playerEntities.emplace_back(p->d.read<glm::vec3>(), cid, playerModel);
|
|
break; }
|
|
|
|
case PacketType::CHUNK:
|
|
case PacketType::MAPBLOCK:
|
|
world->loadWorldPacket(std::move(p)); break;
|
|
|
|
case PacketType::BLOCK_SET: {
|
|
auto pos = p->d.read<glm::ivec3>();
|
|
auto block = p->d.read<unsigned int>();
|
|
world->setBlock(pos, block);
|
|
break; }
|
|
|
|
case PacketType::ENTITY_INFO:
|
|
world->dimension.serverEntityInfo(*p); break;
|
|
|
|
case PacketType::ENTITY_REMOVED:
|
|
world->dimension.serverEntityRemoved(p->d.read<unsigned int>()); break;
|
|
|
|
case PacketType::INV_DATA:
|
|
onInvPacket(std::move(p));
|
|
break;
|
|
|
|
case PacketType::INV_INVALID: {
|
|
std::string source = p->d.read<std::string>();
|
|
std::string list = p->d.read<std::string>();
|
|
throw std::runtime_error("Invalid inventory " + source + ":" + list + " was request by client.");
|
|
break; }
|
|
}
|
|
}
|
|
|
|
void ClientNetworkInterpreter::blockPlace(Target &target) {
|
|
Serializer().append<glm::ivec3>(target.pos).append(static_cast<unsigned short>(target.face))
|
|
.packet(PacketType::BLOCK_PLACE).sendTo(connection.getPeer(), PacketChannel::INTERACT);
|
|
}
|
|
|
|
void ClientNetworkInterpreter::blockInteract(Target &target) {
|
|
Serializer().append<glm::ivec3>(target.pos).append(static_cast<unsigned short>(target.face))
|
|
.packet(PacketType::BLOCK_INTERACT).sendTo(connection.getPeer(), PacketChannel::INTERACT);
|
|
}
|
|
|
|
void ClientNetworkInterpreter::blockPlaceOrInteract(Target &target) {
|
|
Serializer().append<glm::ivec3>(target.pos).append(static_cast<unsigned short>(target.face))
|
|
.packet(PacketType::BLOCK_PLACE_OR_INTERACT).sendTo(connection.getPeer(), PacketChannel::INTERACT);
|
|
}
|
|
|
|
void ClientNetworkInterpreter::invWatch(const std::string& inv, const std::string& list) {
|
|
Serializer().append(inv).append(list).packet(PacketType::INV_WATCH)
|
|
.sendTo(connection.getPeer(), PacketChannel::INVENTORY);
|
|
}
|
|
|
|
void ClientNetworkInterpreter::invUnwatch(const std::string& inv, const std::string& list) {
|
|
Serializer().append(inv).append(list).packet(PacketType::INV_UNWATCH)
|
|
.sendTo(connection.getPeer(), PacketChannel::INVENTORY);
|
|
}
|
|
|
|
void ClientNetworkInterpreter::invInteractPrimary(const std::string &inv, const std::string &list, unsigned short ind) {
|
|
Serializer().append<unsigned short>(0).append(inv).append(list).append<unsigned short>(ind).packet(PacketType::INV_INTERACT)
|
|
.sendTo(connection.getPeer(), PacketChannel::INVENTORY);
|
|
}
|
|
|
|
void ClientNetworkInterpreter::invInteractSecondary(const std::string &inv, const std::string &list, unsigned short ind) {
|
|
Serializer().append<unsigned short>(1).append(inv).append(list).append<unsigned short>(ind).packet(PacketType::INV_INTERACT)
|
|
.sendTo(connection.getPeer(), PacketChannel::INVENTORY);
|
|
}
|