Первый коммит
This commit is contained in:
36
Src/Client/Abstract.cpp
Normal file
36
Src/Client/Abstract.cpp
Normal file
@@ -0,0 +1,36 @@
|
||||
#include "Abstract.hpp"
|
||||
|
||||
|
||||
namespace AL::Client {
|
||||
|
||||
void IRenderSession::onChunksChange(WorldId_t worldId, const std::vector<Pos::GlobalChunk> &changeOrAddList, const std::vector<Pos::GlobalChunk> &remove) {}
|
||||
void IRenderSession::attachCameraToEntity(EntityId_t id) {}
|
||||
void IRenderSession::onWorldAdd(WorldId_t id) {}
|
||||
void IRenderSession::onWorldRemove(WorldId_t id) {}
|
||||
void IRenderSession::onWorldChange(WorldId_t id) {}
|
||||
void IRenderSession::onEntitysAdd(const std::vector<EntityId_t> &list) {}
|
||||
void IRenderSession::onEntitysRemove(const std::vector<EntityId_t> &list) {}
|
||||
void IRenderSession::onEntitysPosQuatChanges(const std::vector<EntityId_t> &list) {}
|
||||
void IRenderSession::onEntitysStateChanges(const std::vector<EntityId_t> &list) {}
|
||||
TextureId_t IRenderSession::allocateTexture() { return 0; }
|
||||
void IRenderSession::freeTexture(TextureId_t id) {}
|
||||
void IRenderSession::setTexture(TextureId_t id, TextureInfo info) {}
|
||||
ModelId_t IRenderSession::allocateModel() { return 0; }
|
||||
void IRenderSession::freeModel(ModelId_t id) {}
|
||||
void IRenderSession::setModel(ModelId_t id, ModelInfo info) {}
|
||||
IRenderSession::~IRenderSession() = default;
|
||||
|
||||
IServerSession::~IServerSession() = default;
|
||||
|
||||
void ISurfaceEventListener::onResize(uint32_t width, uint32_t height) {}
|
||||
void ISurfaceEventListener::onChangeFocusState(bool isFocused) {}
|
||||
void ISurfaceEventListener::onCursorPosChange(int32_t width, int32_t height) {}
|
||||
void ISurfaceEventListener::onCursorMove(float xMove, float yMove) {}
|
||||
void ISurfaceEventListener::onFrameRendering() {}
|
||||
void ISurfaceEventListener::onFrameRenderEnd() {}
|
||||
void ISurfaceEventListener::onCursorBtn(EnumCursorBtn btn, bool state) {}
|
||||
void ISurfaceEventListener::onKeyboardBtn(int btn, int state) {}
|
||||
void ISurfaceEventListener::onJoystick() {}
|
||||
ISurfaceEventListener::~ISurfaceEventListener() = default;
|
||||
|
||||
}
|
||||
174
Src/Client/Abstract.hpp
Normal file
174
Src/Client/Abstract.hpp
Normal file
@@ -0,0 +1,174 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
#include <Common/Abstract.hpp>
|
||||
|
||||
|
||||
namespace AL::Client {
|
||||
|
||||
using VoxelId_t = uint16_t;
|
||||
|
||||
struct VoxelCube {
|
||||
Pos::Local256 Left, Right;
|
||||
VoxelId_t Material;
|
||||
};
|
||||
|
||||
using NodeId_t = uint16_t;
|
||||
|
||||
struct Node {
|
||||
NodeId_t NodeId;
|
||||
uint8_t Rotate : 6;
|
||||
};
|
||||
|
||||
// 16 метров ребро
|
||||
// 256 вокселей ребро
|
||||
struct Chunk {
|
||||
// Кубы вокселей в чанке
|
||||
std::vector<VoxelCube> Voxels;
|
||||
// Ноды
|
||||
std::unordered_map<Pos::Local16_u, Node> Nodes;
|
||||
// Ограничения прохождения света, идущего от солнца (от верха карты до верхней плоскости чанка)
|
||||
LightPrism Lights[16][16];
|
||||
};
|
||||
|
||||
using WorldId_t = uint8_t;
|
||||
using PortalId_t = uint16_t;
|
||||
using EntityId_t = uint16_t;
|
||||
|
||||
class Entity {
|
||||
public:
|
||||
// PosQuat
|
||||
WorldId_t WorldId;
|
||||
PortalId_t LastUsedPortal;
|
||||
Pos::Object Pos;
|
||||
glm::quat Quat;
|
||||
static constexpr uint16_t HP_BS = 4096, HP_BS_Bit = 12;
|
||||
uint32_t HP = 0;
|
||||
|
||||
// State
|
||||
std::unordered_map<std::string, float> Tags;
|
||||
// m_attached_particle_spawners
|
||||
// states
|
||||
};
|
||||
|
||||
using TextureId_t = uint16_t;
|
||||
|
||||
struct TextureInfo {
|
||||
|
||||
};
|
||||
|
||||
using ModelId_t = uint16_t;
|
||||
|
||||
struct ModelInfo {
|
||||
|
||||
};
|
||||
|
||||
/* Интерфейс рендера текущего подключения к серверу */
|
||||
class IRenderSession {
|
||||
public:
|
||||
// Сообщаем об изменившихся чанках
|
||||
virtual void onChunksChange(WorldId_t worldId, const std::vector<Pos::GlobalChunk> &changeOrAddList, const std::vector<Pos::GlobalChunk> &remove);
|
||||
// Подключаем камеру к сущности
|
||||
virtual void attachCameraToEntity(EntityId_t id);
|
||||
|
||||
//
|
||||
|
||||
// Мир уже есть в глобальном списке
|
||||
virtual void onWorldAdd(WorldId_t id);
|
||||
// Мира уже нет в списке
|
||||
virtual void onWorldRemove(WorldId_t id);
|
||||
// Изменение состояния мира
|
||||
virtual void onWorldChange(WorldId_t id);
|
||||
|
||||
// Сущности уже есть в глобальном списке
|
||||
virtual void onEntitysAdd(const std::vector<EntityId_t> &list);
|
||||
//
|
||||
virtual void onEntitysRemove(const std::vector<EntityId_t> &list);
|
||||
//
|
||||
virtual void onEntitysPosQuatChanges(const std::vector<EntityId_t> &list);
|
||||
//
|
||||
virtual void onEntitysStateChanges(const std::vector<EntityId_t> &list);
|
||||
|
||||
virtual TextureId_t allocateTexture();
|
||||
virtual void freeTexture(TextureId_t id);
|
||||
virtual void setTexture(TextureId_t id, TextureInfo info);
|
||||
|
||||
virtual ModelId_t allocateModel();
|
||||
virtual void freeModel(ModelId_t id);
|
||||
virtual void setModel(ModelId_t id, ModelInfo info);
|
||||
|
||||
virtual ~IRenderSession();
|
||||
};
|
||||
|
||||
|
||||
struct Region {
|
||||
std::unordered_map<Pos::Local4_u::Key, Chunk[4][4][4]> Subs;
|
||||
};
|
||||
|
||||
|
||||
struct World {
|
||||
std::vector<EntityId_t> Entitys;
|
||||
std::unordered_map<Pos::GlobalRegion::Key, Region> Regions;
|
||||
};
|
||||
|
||||
|
||||
class ChunksIterator {
|
||||
public:
|
||||
};
|
||||
|
||||
struct VoxelInfo {
|
||||
|
||||
};
|
||||
|
||||
struct NodeInfo {
|
||||
|
||||
};
|
||||
|
||||
/* Интерфейс обработчика сессии с сервером */
|
||||
class IServerSession {
|
||||
public:
|
||||
std::unordered_map<EntityId_t, Entity> Entitys;
|
||||
std::unordered_map<WorldId_t, World> Worlds;
|
||||
std::unordered_map<VoxelId_t, VoxelInfo> VoxelRegistry;
|
||||
std::unordered_map<NodeId_t, NodeInfo> NodeRegistry;
|
||||
|
||||
virtual ~IServerSession();
|
||||
};
|
||||
|
||||
|
||||
/* Интерфейс получателя событий от модуля вывода графики в ОС */
|
||||
class ISurfaceEventListener {
|
||||
public:
|
||||
enum struct EnumCursorMoveMode {
|
||||
Default, MoveAndHidden
|
||||
} CursorMode = EnumCursorMoveMode::Default;
|
||||
|
||||
enum struct EnumCursorBtn {
|
||||
Left, Middle, Right, One, Two
|
||||
};
|
||||
|
||||
public:
|
||||
// Изменение размера окна вывода графики
|
||||
virtual void onResize(uint32_t width, uint32_t height);
|
||||
// Приобретение или потеря фокуса приложением
|
||||
virtual void onChangeFocusState(bool isFocused);
|
||||
// Абсолютное изменение позиции курсора (вызывается только если CursorMode == EnumCursorMoveMode::Default)
|
||||
virtual void onCursorPosChange(int32_t width, int32_t height);
|
||||
// Относительное перемещение курсора (вызывается только если CursorMode == EnumCursorMoveMode::MoveAndHidden)
|
||||
virtual void onCursorMove(float xMove, float yMove);
|
||||
// Когда на GPU отправлены команды на отрисовку мира и мир рисуется
|
||||
virtual void onFrameRendering(); // Здесь пока неизвестно что можно делать, но тут есть свободное время
|
||||
// Когда GPU завершил кадр
|
||||
virtual void onFrameRenderEnd(); // Изменять игровые данные можно только здесь
|
||||
|
||||
virtual void onCursorBtn(EnumCursorBtn btn, bool state);
|
||||
virtual void onKeyboardBtn(int btn, int state);
|
||||
virtual void onJoystick();
|
||||
|
||||
virtual ~ISurfaceEventListener();
|
||||
};
|
||||
|
||||
}
|
||||
112
Src/Client/ServerSession.cpp
Normal file
112
Src/Client/ServerSession.cpp
Normal file
@@ -0,0 +1,112 @@
|
||||
#include "ServerSession.hpp"
|
||||
#include "Common/Net.hpp"
|
||||
#include <boost/asio/deadline_timer.hpp>
|
||||
#include <boost/asio/this_coro.hpp>
|
||||
#include <boost/date_time/posix_time/posix_time_duration.hpp>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
|
||||
namespace AL::Client {
|
||||
|
||||
using namespace TOS;
|
||||
|
||||
ServerSession::~ServerSession() = default;
|
||||
|
||||
coro<> ServerSession::asyncAuthorizeWithServer(tcp::socket &socket, const std::string username, const std::string token, int a_ar_r, std::function<void(const std::string&)> onProgress) {
|
||||
assert(a_ar_r >= 0 && a_ar_r <= 2);
|
||||
|
||||
std::string progress;
|
||||
auto addLog = [&](const std::string &msg) {
|
||||
progress += '\n';
|
||||
progress += msg;
|
||||
|
||||
if(onProgress)
|
||||
onProgress('\n'+msg);
|
||||
};
|
||||
|
||||
if(username.size() > 255) {
|
||||
addLog("Имя пользователя слишком велико (>255)");
|
||||
MAKE_ERROR(progress);
|
||||
}
|
||||
|
||||
if(token.size() > 255) {
|
||||
addLog("Пароль слишком велик (>255)");
|
||||
MAKE_ERROR(progress);
|
||||
}
|
||||
|
||||
|
||||
Net::Packet packet;
|
||||
|
||||
packet.write((const std::byte*) "AlterLuanti", 11);
|
||||
packet << uint8_t(0) << uint8_t(a_ar_r) << username << token;
|
||||
|
||||
addLog("Отправляем первый пакет, авторизация или регистрация");
|
||||
co_await packet.sendAndFastClear(socket);
|
||||
|
||||
addLog("Ожидаем код ответа");
|
||||
uint8_t code = co_await Net::AsyncSocket::read<uint8_t>(socket);
|
||||
|
||||
if(code == 0) {
|
||||
addLog("Код = Авторизированы");
|
||||
} else if(code == 1) {
|
||||
addLog("Код = Зарегистрированы и авторизированы");
|
||||
} else if(code == 2 || code == 3) {
|
||||
if(code == 2)
|
||||
addLog("Код = Не удалось зарегистрироваться");
|
||||
else
|
||||
addLog("Код = Не удалось авторизоваться");
|
||||
|
||||
std::string reason = co_await Net::AsyncSocket::read<std::string>(socket);
|
||||
addLog(reason);
|
||||
|
||||
if(code == 2)
|
||||
MAKE_ERROR("Не удалось зарегистрироваться, причина: " << reason);
|
||||
else
|
||||
MAKE_ERROR("Не удалось авторизоваться, причина: " << reason);
|
||||
} else {
|
||||
addLog("Получен неизвестный код ответа (может это не игровой сервер?), прерываем");
|
||||
MAKE_ERROR(progress);
|
||||
}
|
||||
}
|
||||
|
||||
coro<std::unique_ptr<Net::AsyncSocket>> ServerSession::asyncInitGameProtocol(asio::io_context &ioc, tcp::socket &&socket, std::function<void(const std::string&)> onProgress) {
|
||||
std::string progress;
|
||||
auto addLog = [&](const std::string &msg) {
|
||||
progress += '\n';
|
||||
progress += msg;
|
||||
|
||||
if(onProgress)
|
||||
onProgress('\n'+msg);
|
||||
};
|
||||
|
||||
addLog("Инициализируем игровой протокол");
|
||||
uint8_t code = 0;
|
||||
co_await Net::AsyncSocket::write<>(socket, code);
|
||||
asio::deadline_timer timer(socket.get_executor());
|
||||
|
||||
while(true) {
|
||||
code = co_await Net::AsyncSocket::read<uint8_t>(socket);
|
||||
|
||||
if(code == 0) {
|
||||
addLog("Код = Успешно");
|
||||
break;
|
||||
} else if(code == 1) {
|
||||
addLog("Код = Ошибка с причиной");
|
||||
addLog(co_await Net::AsyncSocket::read<std::string>(socket));
|
||||
MAKE_ERROR(progress);
|
||||
} else if(code == 2) {
|
||||
addLog("Код = Подождать 4 секунды");
|
||||
timer.expires_from_now(boost::posix_time::seconds(4));
|
||||
co_await timer.async_wait();
|
||||
addLog("Ожидаем новый код");
|
||||
} else {
|
||||
addLog("Получен неизвестный код ответа (может это не игровой сервер?), прерываем");
|
||||
MAKE_ERROR(progress);
|
||||
}
|
||||
}
|
||||
|
||||
co_return std::make_unique<Net::AsyncSocket>(ioc, std::move(socket));
|
||||
}
|
||||
|
||||
}
|
||||
51
Src/Client/ServerSession.hpp
Normal file
51
Src/Client/ServerSession.hpp
Normal file
@@ -0,0 +1,51 @@
|
||||
#pragma once
|
||||
|
||||
#include "Abstract.hpp"
|
||||
#include "Common/Net.hpp"
|
||||
#include <TOSLib.hpp>
|
||||
#include <boost/asio/io_context.hpp>
|
||||
|
||||
|
||||
namespace AL::Client {
|
||||
|
||||
class ServerSession : public AsyncObject, public IServerSession, public ISurfaceEventListener {
|
||||
std::unique_ptr<Net::AsyncSocket> _Socket;
|
||||
Net::AsyncSocket &Socket;
|
||||
IRenderSession *RS = nullptr;
|
||||
|
||||
public:
|
||||
// Нужен сокет, на котором только что был согласован игровой протокол (asyncInitGameProtocol)
|
||||
ServerSession(asio::io_context &ioc, std::unique_ptr<Net::AsyncSocket> &&socket, IRenderSession *rs = nullptr)
|
||||
: AsyncObject(ioc), _Socket(std::move(socket)), Socket(*socket), RS(rs)
|
||||
{
|
||||
assert(socket.get());
|
||||
co_spawn(run());
|
||||
}
|
||||
|
||||
virtual ~ServerSession();
|
||||
|
||||
// Авторизоваться или (зарегистрироваться и авторизоваться) или зарегистрироваться
|
||||
static coro<> asyncAuthorizeWithServer(tcp::socket &socket, const std::string username, const std::string token, int a_ar_r, std::function<void(const std::string&)> onProgress = nullptr);
|
||||
// Начать игровой протокол в авторизированном сокете
|
||||
static coro<std::unique_ptr<Net::AsyncSocket>> asyncInitGameProtocol(asio::io_context &ioc, tcp::socket &&socket, std::function<void(const std::string&)> onProgress = nullptr);
|
||||
|
||||
|
||||
|
||||
// ISurfaceEventListener
|
||||
|
||||
// virtual void onResize(uint32_t width, uint32_t height) override;
|
||||
// virtual void onChangeFocusState(bool isFocused) override;
|
||||
// virtual void onCursorPosChange(int32_t width, int32_t height) override;
|
||||
// virtual void onCursorMove(float xMove, float yMove) override;
|
||||
// virtual void onFrameRendering() override;
|
||||
// virtual void onFrameRenderEnd() override;
|
||||
|
||||
// virtual void onCursorBtn(EnumCursorBtn btn, bool state) override;
|
||||
// virtual void onKeyboardBtn(int btn, int state) override;
|
||||
// virtual void onJoystick() override;
|
||||
|
||||
private:
|
||||
coro<> run();
|
||||
};
|
||||
|
||||
}
|
||||
2300
Src/Client/Vulkan/VkSymbols.cpp
Normal file
2300
Src/Client/Vulkan/VkSymbols.cpp
Normal file
File diff suppressed because it is too large
Load Diff
4287
Src/Client/Vulkan/Vulkan.cpp
Normal file
4287
Src/Client/Vulkan/Vulkan.cpp
Normal file
File diff suppressed because it is too large
Load Diff
1008
Src/Client/Vulkan/Vulkan.hpp
Normal file
1008
Src/Client/Vulkan/Vulkan.hpp
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user