Первый коммит

This commit is contained in:
2025-02-03 15:16:12 +06:00
commit d40c3bad86
287 changed files with 124575 additions and 0 deletions

36
Src/Client/Abstract.cpp Normal file
View 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
View 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();
};
}

View 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));
}
}

View 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();
};
}

File diff suppressed because it is too large Load Diff

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

File diff suppressed because it is too large Load Diff