Compare commits
4 Commits
35008f9304
...
c6d9a2cd77
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c6d9a2cd77 | ||
|
|
e1f9212d3c | ||
|
|
473de216f2 | ||
|
|
e0ec50cadb |
39
shell.html
39
shell.html
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<title>PortalGame</title>
|
<title>Fekalni gtacko</title>
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
@ -14,6 +14,7 @@
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
background: black;
|
background: black;
|
||||||
|
color: aqua;
|
||||||
}
|
}
|
||||||
|
|
||||||
canvas {
|
canvas {
|
||||||
@ -25,15 +26,30 @@
|
|||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<canvas id="canvas" oncontextmenu="event.preventDefault()"></canvas>
|
<canvas id="canvas" oncontextmenu="event.preventDefault()" style="display:none"></canvas>
|
||||||
|
|
||||||
|
<div id="loginform">
|
||||||
|
<h1>fekální gtačko</h1>
|
||||||
|
|
||||||
|
<form>
|
||||||
|
kdo <input type="text" name="name" id="name"><br>
|
||||||
|
kam <input type="text" name="url" id="url"><br>
|
||||||
|
<input type="button" value="0k" onclick="ok()">
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
var inited = false;
|
||||||
|
|
||||||
var Module = {
|
var Module = {
|
||||||
preRun: [],
|
preRun: [],
|
||||||
postRun: [],
|
postRun: [],
|
||||||
canvas: (function() {
|
canvas: (function() {
|
||||||
return document.getElementById('canvas');
|
return document.getElementById('canvas');
|
||||||
})()
|
})(),
|
||||||
|
onRuntimeInitialized: function() {
|
||||||
|
inited = true;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Resize canvas to fit the window and inform SDL (via Emscripten)
|
// Resize canvas to fit the window and inform SDL (via Emscripten)
|
||||||
@ -51,6 +67,23 @@
|
|||||||
|
|
||||||
window.addEventListener('resize', resizeCanvas);
|
window.addEventListener('resize', resizeCanvas);
|
||||||
window.addEventListener('load', resizeCanvas);
|
window.addEventListener('load', resizeCanvas);
|
||||||
|
|
||||||
|
function ok()
|
||||||
|
{
|
||||||
|
if (!inited)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const name = document.getElementById("name").value;
|
||||||
|
const url = document.getElementById("url").value;
|
||||||
|
|
||||||
|
Module.ccall("SetName", name);
|
||||||
|
Module.ccall("SetUrl", url);
|
||||||
|
|
||||||
|
document.getElementById("loginform").style = "display:none";
|
||||||
|
document.getElementById("canvas").style = "";
|
||||||
|
|
||||||
|
Module.ccall("RunMain");
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{{{ SCRIPT }}}
|
{{{ SCRIPT }}}
|
||||||
|
|||||||
@ -4,13 +4,13 @@
|
|||||||
|
|
||||||
#include "utils/bufferput.hpp"
|
#include "utils/bufferput.hpp"
|
||||||
|
|
||||||
assets::MeshBuilder::MeshBuilder(gfx::MeshFlags mflags) : mflags_(mflags) {}
|
assets::MeshBuilder::MeshBuilder(gfx::MeshFlags mflags) : mflags_(mflags)
|
||||||
|
{
|
||||||
|
mesh_ = std::make_shared<Mesh>();
|
||||||
|
}
|
||||||
|
|
||||||
void assets::MeshBuilder::BeginSurface(gfx::SurfaceFlags sflags, const std::string& name, std::shared_ptr<const gfx::Texture> texture)
|
void assets::MeshBuilder::BeginSurface(gfx::SurfaceFlags sflags, const std::string& name, std::shared_ptr<const gfx::Texture> texture)
|
||||||
{
|
{
|
||||||
if (!mesh_)
|
|
||||||
mesh_ = std::make_shared<Mesh>();
|
|
||||||
|
|
||||||
FinalizeSurface();
|
FinalizeSurface();
|
||||||
|
|
||||||
gfx::Surface surface;
|
gfx::Surface surface;
|
||||||
|
|||||||
@ -34,6 +34,9 @@ public:
|
|||||||
void SetTime(float time) { time_ = time; }
|
void SetTime(float time) { time_ = time; }
|
||||||
void SetViewportSize(int width, int height) { viewport_size_ = {width, height}; }
|
void SetViewportSize(int width, int height) { viewport_size_ = {width, height}; }
|
||||||
|
|
||||||
|
void SetUserName(const std::string& username) { username_ = username; }
|
||||||
|
const std::string& GetUserName() const { return username_; }
|
||||||
|
|
||||||
void Input(game::PlayerInputType in, bool pressed, bool repeated);
|
void Input(game::PlayerInputType in, bool pressed, bool repeated);
|
||||||
void MouseMove(const glm::vec2& delta);
|
void MouseMove(const glm::vec2& delta);
|
||||||
|
|
||||||
@ -71,6 +74,7 @@ private:
|
|||||||
|
|
||||||
audio::Master audiomaster_;
|
audio::Master audiomaster_;
|
||||||
|
|
||||||
|
std::string username_;
|
||||||
std::unique_ptr<game::view::ClientSession> session_;
|
std::unique_ptr<game::view::ClientSession> session_;
|
||||||
|
|
||||||
std::deque<ChatMessage> chat_;
|
std::deque<ChatMessage> chat_;
|
||||||
|
|||||||
@ -28,11 +28,20 @@
|
|||||||
#include "app.hpp"
|
#include "app.hpp"
|
||||||
#include "gl.hpp"
|
#include "gl.hpp"
|
||||||
|
|
||||||
|
static std::string s_username;
|
||||||
|
static std::string s_url;
|
||||||
|
|
||||||
static SDL_Window *s_window = nullptr;
|
static SDL_Window *s_window = nullptr;
|
||||||
static SDL_GLContext s_context = nullptr;
|
static SDL_GLContext s_context = nullptr;
|
||||||
static bool s_quit = false;
|
static bool s_quit = false;
|
||||||
static std::unique_ptr<App> s_app;
|
static std::unique_ptr<App> s_app;
|
||||||
|
|
||||||
|
struct ClientConfig
|
||||||
|
{
|
||||||
|
std::string username;
|
||||||
|
std::string url;
|
||||||
|
};
|
||||||
|
|
||||||
static void ThrowSDLError(const std::string& message)
|
static void ThrowSDLError(const std::string& message)
|
||||||
{
|
{
|
||||||
std::string error = SDL_GetError();
|
std::string error = SDL_GetError();
|
||||||
@ -66,7 +75,7 @@ static void InitSDL()
|
|||||||
|
|
||||||
std::cout << "Creating SDL window..." << std::endl;
|
std::cout << "Creating SDL window..." << std::endl;
|
||||||
s_window =
|
s_window =
|
||||||
SDL_CreateWindow("PortalGame", 100, 100, 640, 480,
|
SDL_CreateWindow("Fekalni gtacko", 100, 100, 640, 480,
|
||||||
SDL_WINDOW_SHOWN /* | SDL_WINDOW_MAXIMIZED */| SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE);
|
SDL_WINDOW_SHOWN /* | SDL_WINDOW_MAXIMIZED */| SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE);
|
||||||
if (!s_window)
|
if (!s_window)
|
||||||
{
|
{
|
||||||
@ -145,6 +154,7 @@ static const std::map<SDL_Scancode, game::PlayerInputType> s_inputmap = {
|
|||||||
{ SDL_SCANCODE_A, game::IN_LEFT },
|
{ SDL_SCANCODE_A, game::IN_LEFT },
|
||||||
{ SDL_SCANCODE_D, game::IN_RIGHT },
|
{ SDL_SCANCODE_D, game::IN_RIGHT },
|
||||||
{ SDL_SCANCODE_SPACE, game::IN_JUMP },
|
{ SDL_SCANCODE_SPACE, game::IN_JUMP },
|
||||||
|
{ SDL_SCANCODE_LSHIFT, game::IN_SPRINT },
|
||||||
{ SDL_SCANCODE_LCTRL, game::IN_CROUCH },
|
{ SDL_SCANCODE_LCTRL, game::IN_CROUCH },
|
||||||
{ SDL_SCANCODE_E, game::IN_USE },
|
{ SDL_SCANCODE_E, game::IN_USE },
|
||||||
{ SDL_SCANCODE_F3, game::IN_DEBUG1 },
|
{ SDL_SCANCODE_F3, game::IN_DEBUG1 },
|
||||||
@ -383,7 +393,10 @@ static void Frame()
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void Main() {
|
static void Main() {
|
||||||
if (!WSInit(WS_URL))
|
if (s_url.empty())
|
||||||
|
s_url = WS_URL;
|
||||||
|
|
||||||
|
if (!WSInit(s_url.c_str()))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
InitSDL();
|
InitSDL();
|
||||||
@ -400,8 +413,10 @@ static void Main() {
|
|||||||
|
|
||||||
SDL_SetRelativeMouseMode(SDL_TRUE);
|
SDL_SetRelativeMouseMode(SDL_TRUE);
|
||||||
|
|
||||||
|
|
||||||
s_app = std::make_unique<App>();
|
s_app = std::make_unique<App>();
|
||||||
s_app->AddChatMessagePrefix("WebSocket", "připojování na " + std::string(WS_URL));
|
s_app->SetUserName(s_username);
|
||||||
|
s_app->AddChatMessagePrefix("WebSocket", "připojování na " + s_url);
|
||||||
|
|
||||||
#ifdef EMSCRIPTEN
|
#ifdef EMSCRIPTEN
|
||||||
emscripten_set_main_loop(Frame, 0, true);
|
emscripten_set_main_loop(Frame, 0, true);
|
||||||
@ -438,7 +453,10 @@ static void Main() {
|
|||||||
#endif // EMSCRIPTEN
|
#endif // EMSCRIPTEN
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
extern "C"
|
||||||
|
{
|
||||||
|
|
||||||
|
void RunMain()
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
Main();
|
Main();
|
||||||
@ -446,8 +464,35 @@ int main(int argc, char *argv[])
|
|||||||
catch (const std::exception& e) {
|
catch (const std::exception& e) {
|
||||||
std::cerr << "[ERROR] " << e.what() << std::endl;
|
std::cerr << "[ERROR] " << e.what() << std::endl;
|
||||||
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Error", e.what(), nullptr);
|
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Error", e.what(), nullptr);
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return EXIT_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SetName(const char* name)
|
||||||
|
{
|
||||||
|
s_username = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetUrl(const char* url)
|
||||||
|
{
|
||||||
|
s_url = url;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef EMSCRIPTEN
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
SetName("random guvno");
|
||||||
|
RunMain();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|||||||
@ -155,7 +155,9 @@ void game::Character::SyncTransformFromController()
|
|||||||
void game::Character::UpdateMovement()
|
void game::Character::UpdateMovement()
|
||||||
{
|
{
|
||||||
constexpr float dt = 1.0f / 25.0f;
|
constexpr float dt = 1.0f / 25.0f;
|
||||||
|
constexpr float running_mult = 3.0f;
|
||||||
bool walking = false;
|
bool walking = false;
|
||||||
|
bool running = false;
|
||||||
glm::vec2 movedir(0.0f);
|
glm::vec2 movedir(0.0f);
|
||||||
|
|
||||||
if (in_ & (1 << CIN_FORWARD))
|
if (in_ & (1 << CIN_FORWARD))
|
||||||
@ -175,11 +177,19 @@ void game::Character::UpdateMovement()
|
|||||||
if (movedir.x != 0.0f || movedir.y != 0.0f)
|
if (movedir.x != 0.0f || movedir.y != 0.0f)
|
||||||
{
|
{
|
||||||
walking = true;
|
walking = true;
|
||||||
|
|
||||||
|
if (in_ & (1 << CIN_SPRINT))
|
||||||
|
running = true;
|
||||||
|
|
||||||
float target_yaw = forward_yaw_ + std::atan2(movedir.y, movedir.x);
|
float target_yaw = forward_yaw_ + std::atan2(movedir.y, movedir.x);
|
||||||
Turn(yaw_, target_yaw, 4.0f * dt);
|
Turn(yaw_, target_yaw, 8.0f * dt);
|
||||||
|
|
||||||
glm::vec3 forward_dir(glm::cos(yaw_), glm::sin(yaw_), 0.0f);
|
glm::vec3 forward_dir(glm::cos(yaw_), glm::sin(yaw_), 0.0f);
|
||||||
walkdir = forward_dir * walk_speed_ * dt;
|
walkdir = forward_dir * walk_speed_ * dt;
|
||||||
|
|
||||||
|
if (running)
|
||||||
|
walkdir *= running_mult;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (controller_)
|
if (controller_)
|
||||||
@ -197,6 +207,8 @@ void game::Character::UpdateMovement()
|
|||||||
float run_blend_target = walking ? 0.5f : 0.0f;
|
float run_blend_target = walking ? 0.5f : 0.0f;
|
||||||
MoveToward(animstate_.loco_blend, run_blend_target, dt * 2.0f);
|
MoveToward(animstate_.loco_blend, run_blend_target, dt * 2.0f);
|
||||||
float anim_speed = glm::mix(0.5f, 1.5f, UnMix(0.0f, 0.5f, animstate_.loco_blend));
|
float anim_speed = glm::mix(0.5f, 1.5f, UnMix(0.0f, 0.5f, animstate_.loco_blend));
|
||||||
|
if (running)
|
||||||
|
anim_speed *= running_mult;
|
||||||
animstate_.loco_phase = glm::mod(animstate_.loco_phase + anim_speed * dt, 1.0f);
|
animstate_.loco_phase = glm::mod(animstate_.loco_phase + anim_speed * dt, 1.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -19,6 +19,7 @@ enum CharacterInputType
|
|||||||
CIN_LEFT,
|
CIN_LEFT,
|
||||||
CIN_RIGHT,
|
CIN_RIGHT,
|
||||||
CIN_JUMP,
|
CIN_JUMP,
|
||||||
|
CIN_SPRINT,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CapsuleShape
|
struct CapsuleShape
|
||||||
|
|||||||
@ -18,7 +18,7 @@ namespace game
|
|||||||
|
|
||||||
static const char* GetRandomCarModel()
|
static const char* GetRandomCarModel()
|
||||||
{
|
{
|
||||||
const char* vehicles[] = {"pickup_hd", "passat", "twingo", "polskifiat"};
|
const char* vehicles[] = {"pickup_hd", "passat", "twingo", "polskifiat", "cow_static"};
|
||||||
return vehicles[rand() % (sizeof(vehicles) / sizeof(vehicles[0]))];
|
return vehicles[rand() % (sizeof(vehicles) / sizeof(vehicles[0]))];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,7 +52,7 @@ game::OpenWorld::OpenWorld() : World("openworld")
|
|||||||
|
|
||||||
constexpr size_t in_row = 20;
|
constexpr size_t in_row = 20;
|
||||||
|
|
||||||
for (size_t i = 0; i < 1500; ++i)
|
for (size_t i = 0; i < 100; ++i)
|
||||||
{
|
{
|
||||||
Schedule(i * 40, [this, i] {
|
Schedule(i * 40, [this, i] {
|
||||||
size_t col = i % in_row;
|
size_t col = i % in_row;
|
||||||
@ -173,7 +173,7 @@ void game::OpenWorld::CreatePlayerCharacter(Player& player)
|
|||||||
RemovePlayerCharacter(player);
|
RemovePlayerCharacter(player);
|
||||||
|
|
||||||
auto& character = SpawnRandomCharacter<PlayerCharacter>(*this, player);
|
auto& character = SpawnRandomCharacter<PlayerCharacter>(*this, player);
|
||||||
character.SetNametag("player (" + std::to_string(character.GetEntNum()) + ")");
|
// character.SetNametag("player (" + std::to_string(character.GetEntNum()) + ")");
|
||||||
character.SetPosition({100.0f, 100.0f, 5.0f});
|
character.SetPosition({100.0f, 100.0f, 5.0f});
|
||||||
|
|
||||||
player_characters_[&player] = &character;
|
player_characters_[&player] = &character;
|
||||||
|
|||||||
@ -65,7 +65,7 @@ void game::Player::SetCamera(net::EntNum entnum)
|
|||||||
msg.Write(entnum);
|
msg.Write(entnum);
|
||||||
}
|
}
|
||||||
|
|
||||||
void game::Player::SendChat(const std::string text)
|
void game::Player::SendChat(const std::string& text)
|
||||||
{
|
{
|
||||||
auto msg = BeginMsg(net::MSG_CHAT);
|
auto msg = BeginMsg(net::MSG_CHAT);
|
||||||
net::ChatMessage chatm = text;
|
net::ChatMessage chatm = text;
|
||||||
|
|||||||
@ -28,7 +28,9 @@ public:
|
|||||||
void SetWorld(std::shared_ptr<World> world);
|
void SetWorld(std::shared_ptr<World> world);
|
||||||
|
|
||||||
void SetCamera(net::EntNum entnum);
|
void SetCamera(net::EntNum entnum);
|
||||||
void SendChat(const std::string text);
|
void SendChat(const std::string& text);
|
||||||
|
|
||||||
|
const std::string& GetName() const { return name_; }
|
||||||
|
|
||||||
PlayerInputFlags GetInput() const { return in_; }
|
PlayerInputFlags GetInput() const { return in_; }
|
||||||
float GetViewYaw() const { return view_yaw_; }
|
float GetViewYaw() const { return view_yaw_; }
|
||||||
|
|||||||
@ -5,6 +5,8 @@ game::PlayerCharacter::PlayerCharacter(World& world, OpenWorld& openworld, Playe
|
|||||||
{
|
{
|
||||||
EnablePhysics(true);
|
EnablePhysics(true);
|
||||||
VehicleChanged();
|
VehicleChanged();
|
||||||
|
|
||||||
|
SetNametag(player.GetName());
|
||||||
}
|
}
|
||||||
|
|
||||||
void game::PlayerCharacter::Update()
|
void game::PlayerCharacter::Update()
|
||||||
@ -93,6 +95,11 @@ void game::PlayerCharacter::UpdateInputs()
|
|||||||
c_in |= 1 << CIN_JUMP;
|
c_in |= 1 << CIN_JUMP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (in & (1 << IN_SPRINT))
|
||||||
|
{
|
||||||
|
c_in |= 1 << CIN_SPRINT;
|
||||||
|
}
|
||||||
|
|
||||||
if (vehicle_)
|
if (vehicle_)
|
||||||
{
|
{
|
||||||
SetInputs(0);
|
SetInputs(0);
|
||||||
|
|||||||
@ -14,6 +14,7 @@ namespace game
|
|||||||
IN_RIGHT,
|
IN_RIGHT,
|
||||||
IN_JUMP,
|
IN_JUMP,
|
||||||
IN_CROUCH,
|
IN_CROUCH,
|
||||||
|
IN_SPRINT,
|
||||||
IN_USE,
|
IN_USE,
|
||||||
IN_ATTACK,
|
IN_ATTACK,
|
||||||
IN_DEBUG1,
|
IN_DEBUG1,
|
||||||
|
|||||||
@ -5,13 +5,14 @@
|
|||||||
// #include <glm/gtx/common.hpp>
|
// #include <glm/gtx/common.hpp>
|
||||||
|
|
||||||
#include "vehicleview.hpp"
|
#include "vehicleview.hpp"
|
||||||
|
#include "utils/version.hpp"
|
||||||
|
|
||||||
game::view::ClientSession::ClientSession(App& app) : app_(app)
|
game::view::ClientSession::ClientSession(App& app) : app_(app)
|
||||||
{
|
{
|
||||||
// send login
|
// send login
|
||||||
auto msg = BeginMsg(net::MSG_ID);
|
auto msg = BeginMsg(net::MSG_ID);
|
||||||
net::PlayerName name;
|
msg.Write<net::Version>(FEKAL_VERSION);
|
||||||
msg.Write(name);
|
msg.Write(net::PlayerName(app.GetUserName()));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool game::view::ClientSession::ProcessMessage(net::InMessage& msg)
|
bool game::view::ClientSession::ProcessMessage(net::InMessage& msg)
|
||||||
|
|||||||
@ -55,7 +55,7 @@ enum MessageType : uint8_t
|
|||||||
MSG_COUNT,
|
MSG_COUNT,
|
||||||
};
|
};
|
||||||
|
|
||||||
using PlayerName = FixedStr<24>;
|
using PlayerName = FixedStr<64>;
|
||||||
using MapName = FixedStr<32>;
|
using MapName = FixedStr<32>;
|
||||||
using ModelName = FixedStr<64>;
|
using ModelName = FixedStr<64>;
|
||||||
using ChatMessage = FixedStr<1024>;
|
using ChatMessage = FixedStr<1024>;
|
||||||
@ -131,4 +131,8 @@ using ObjCount = ObjNum;
|
|||||||
|
|
||||||
using NumTexels = uint16_t;
|
using NumTexels = uint16_t;
|
||||||
|
|
||||||
|
// version
|
||||||
|
|
||||||
|
using Version = uint32_t;
|
||||||
|
|
||||||
} // namespace net
|
} // namespace net
|
||||||
@ -1,7 +1,10 @@
|
|||||||
#include "client.hpp"
|
#include "client.hpp"
|
||||||
|
|
||||||
|
#include <format>
|
||||||
|
|
||||||
#include "server.hpp"
|
#include "server.hpp"
|
||||||
#include "utils/validate.hpp"
|
#include "utils/validate.hpp"
|
||||||
|
#include "utils/version.hpp"
|
||||||
|
|
||||||
sv::Client::Client(Server& server, WSConnId id) : server_(server), id_(id) {}
|
sv::Client::Client(Server& server, WSConnId id) : server_(server), id_(id) {}
|
||||||
|
|
||||||
@ -31,13 +34,7 @@ bool sv::Client::ProcessSingleMessage(net::MessageType type, net::InMessage& msg
|
|||||||
if (type != net::MSG_ID)
|
if (type != net::MSG_ID)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
net::PlayerName name;
|
return ProcessLoginMsg(msg);
|
||||||
if (!msg.Read(name) || !utils::IsAlphanumeric(name))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
player_ = std::make_unique<game::Player>(server_.GetGame(), name);
|
|
||||||
state_ = CS_PLAYER;
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@ -58,7 +55,45 @@ void sv::Client::Update()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void sv::Client::SendChat(const std::string& text)
|
||||||
|
{
|
||||||
|
// not buffering till update here (unlike in Player), sent instantly
|
||||||
|
static std::vector<char> msg_buf;
|
||||||
|
msg_buf.clear();
|
||||||
|
net::OutMessage msg(msg_buf);
|
||||||
|
msg.Write(net::MSG_CHAT);
|
||||||
|
msg.Write(net::ChatMessage(text));
|
||||||
|
|
||||||
|
Send(std::string(msg_buf.data(), msg_buf.size()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void sv::Client::Disconnect()
|
||||||
|
{
|
||||||
|
server_.Disconnect(*this);
|
||||||
|
}
|
||||||
|
|
||||||
void sv::Client::Send(std::string msg)
|
void sv::Client::Send(std::string msg)
|
||||||
{
|
{
|
||||||
server_.Send(*this, std::move(msg));
|
server_.Send(*this, std::move(msg));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool sv::Client::ProcessLoginMsg(net::InMessage& msg)
|
||||||
|
{
|
||||||
|
net::Version ver = 0;
|
||||||
|
msg.Read(ver);
|
||||||
|
|
||||||
|
// check ver
|
||||||
|
if (ver != FEKAL_VERSION)
|
||||||
|
{
|
||||||
|
SendChat(std::format("^f55špatná verze {}, server je na verzi {}", ver, FEKAL_VERSION));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
net::PlayerName name;
|
||||||
|
if (!msg.Read(name) || !utils::IsAlphanumeric(name))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
player_ = std::make_unique<game::Player>(server_.GetGame(), name);
|
||||||
|
state_ = CS_PLAYER;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|||||||
@ -28,7 +28,9 @@ public:
|
|||||||
|
|
||||||
void Update();
|
void Update();
|
||||||
|
|
||||||
// void Disconnect(const std::string& reason);
|
void SendChat(const std::string& text);
|
||||||
|
|
||||||
|
void Disconnect();
|
||||||
|
|
||||||
WSConnId GetConnId() const { return id_; }
|
WSConnId GetConnId() const { return id_; }
|
||||||
ClientState GetState() const { return state_; }
|
ClientState GetState() const { return state_; }
|
||||||
@ -39,6 +41,8 @@ public:
|
|||||||
private:
|
private:
|
||||||
void Send(std::string msg);
|
void Send(std::string msg);
|
||||||
|
|
||||||
|
bool ProcessLoginMsg(net::InMessage& msg);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Server& server_;
|
Server& server_;
|
||||||
WSConnId id_ = 0;
|
WSConnId id_ = 0;
|
||||||
|
|||||||
@ -61,6 +61,11 @@ void sv::Server::Send(Client& client, std::string msg)
|
|||||||
ws_.Send(client.GetConnId(), std::move(msg));
|
ws_.Send(client.GetConnId(), std::move(msg));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void sv::Server::Disconnect(Client& client)
|
||||||
|
{
|
||||||
|
ws_.Close(client.GetConnId());
|
||||||
|
}
|
||||||
|
|
||||||
void sv::Server::PollWSEvents()
|
void sv::Server::PollWSEvents()
|
||||||
{
|
{
|
||||||
WSEvent event;
|
WSEvent event;
|
||||||
@ -98,9 +103,10 @@ void sv::Server::HandleWSConnect(WSConnId conn)
|
|||||||
void sv::Server::HandleWSMessage(WSConnId conn, const std::string& data)
|
void sv::Server::HandleWSMessage(WSConnId conn, const std::string& data)
|
||||||
{
|
{
|
||||||
net::InMessage msg(data.data(), data.size());
|
net::InMessage msg(data.data(), data.size());
|
||||||
if (!clients_.at(conn)->ProcessMessage(msg))
|
auto& client = clients_.at(conn);
|
||||||
|
if (!client->ProcessMessage(msg))
|
||||||
{
|
{
|
||||||
// TODO: disconnect
|
client->Disconnect();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -21,6 +21,8 @@ public:
|
|||||||
|
|
||||||
void Send(Client& client, std::string msg);
|
void Send(Client& client, std::string msg);
|
||||||
|
|
||||||
|
void Disconnect(Client& client);
|
||||||
|
|
||||||
game::Game& GetGame() { return game_; }
|
game::Game& GetGame() { return game_; }
|
||||||
|
|
||||||
int64_t GetTime() const { return time_; }
|
int64_t GetTime() const { return time_; }
|
||||||
|
|||||||
@ -97,6 +97,20 @@ void sv::WSServer::Send(WSConnId conn_id, std::string data)
|
|||||||
(*it->second).send_binary(std::move(data));
|
(*it->second).send_binary(std::move(data));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void sv::WSServer::Close(WSConnId conn_id)
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(mtx_);
|
||||||
|
|
||||||
|
auto it = id2conn_.find(conn_id);
|
||||||
|
if (it == id2conn_.end())
|
||||||
|
{
|
||||||
|
std::cerr << "attempted to close unknown conn ID " << conn_id << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
(*it->second).close();
|
||||||
|
}
|
||||||
|
|
||||||
void sv::WSServer::Exit()
|
void sv::WSServer::Exit()
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock(mtx_);
|
std::lock_guard<std::mutex> lock(mtx_);
|
||||||
|
|||||||
@ -50,7 +50,7 @@ public:
|
|||||||
|
|
||||||
bool PollEvent(WSEvent& out_event);
|
bool PollEvent(WSEvent& out_event);
|
||||||
void Send(WSConnId conn_id, std::string data);
|
void Send(WSConnId conn_id, std::string data);
|
||||||
// void Close(WSConnId conn_id);
|
void Close(WSConnId conn_id);
|
||||||
|
|
||||||
void Exit();
|
void Exit();
|
||||||
|
|
||||||
|
|||||||
3
src/utils/version.hpp
Normal file
3
src/utils/version.hpp
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#define FEKAL_VERSION 2026031401
|
||||||
Loading…
x
Reference in New Issue
Block a user