fixing minor bugs, fixing velocity not changed after death, fixing server crash

This commit is contained in:
Vladislav Khorev committed 2026-03-09 19:27:20 +03:00
1 parent 84a5e888a0
commit 3e8dba36a4
4 files changed
+150 -9

No files matched your search

+125 -2
View File
@@ -31,8 +31,8 @@ bool Session::is_timed_out(std::chrono::system_clock::time_point now) const {
}
void Session::force_disconnect() {
ws_.async_close(websocket::close_code::normal,
[self = shared_from_this()](beast::error_code) {});
beast::error_code ec;
ws_.next_layer().socket().close(ec);
}
int Session::get_id() const { return id_; }
@@ -346,6 +346,64 @@ void Session::process_message(const std::string& msg) {
std::cout << "Server: Player " << id_ << " respawned, broadcasted RESPAWN_ACK, PLAYERINFO and initial UPD\n";
}
}
else if (parts[0] == "BOX_PICKUP") {
if (parts.size() < 2) return;
if (this->shipType != 1) {
std::cout << "Server: Player " << id_ << " tried BOX_PICKUP but is not a cargo ship\n";
return;
}
int boxIdx = -1;
try { boxIdx = std::stoi(parts[1]); } catch (...) { return; }
std::lock_guard<std::mutex> bm(server_.g_boxes_mutex);
if (boxIdx < 0 || boxIdx >= (int)server_.g_serverBoxes.size()) return;
if (server_.g_serverBoxes[boxIdx].destroyed) return;
if (timedClientStates.timedStates.empty()) return;
const ClientState& playerState = timedClientStates.timedStates.back();
Eigen::Vector3f boxWorld = server_.g_serverBoxes[boxIdx].position + kWorldOffset;
float distSq = (playerState.position - boxWorld).squaredNorm();
if (distSq > BOX_PICKUP_RADIUS * BOX_PICKUP_RADIUS) {
std::cout << "Server: Player " << id_ << " too far to pick up box " << boxIdx << "\n";
return;
}
server_.g_serverBoxes[boxIdx].destroyed = true;
std::string pickedUpMsg = "BOX_PICKED_UP:" + std::to_string(boxIdx) + ":" + std::to_string(id_);
server_.broadcastToAll(pickedUpMsg);
std::cout << "Server: Box " << boxIdx << " picked up by player " << id_ << "\n";
// Respawn box
{
static thread_local std::mt19937 rng{ std::random_device{}() };
static thread_local std::uniform_real_distribution<float> angleDist(0.f, static_cast<float>(M_PI * 2.0));
Eigen::Vector3f newPos = server_.PickSafeBoxPos(boxIdx);
Eigen::Vector3f axis = Eigen::Vector3f::Random().normalized();
Eigen::Matrix3f newRot = Eigen::AngleAxisf(angleDist(rng), axis).toRotationMatrix();
server_.g_serverBoxes[boxIdx].position = newPos;
server_.g_serverBoxes[boxIdx].rotation = newRot;
server_.g_serverBoxes[boxIdx].destroyed = false;
Eigen::Quaternionf q(newRot);
std::string respawnMsg = "BOX_RESPAWN:" +
std::to_string(boxIdx) + ":" +
std::to_string(newPos.x()) + ":" +
std::to_string(newPos.y()) + ":" +
std::to_string(newPos.z()) + ":" +
std::to_string(q.w()) + ":" +
std::to_string(q.x()) + ":" +
std::to_string(q.y()) + ":" +
std::to_string(q.z());
server_.broadcastToAll(respawnMsg);
std::cout << "Server: Box " << boxIdx << " respawned after pickup\n";
}
}
else if (parts[0] == "FIRE") {
if (parts.size() < 10) return;
@@ -377,6 +435,28 @@ void Session::process_message(const std::string& msg) {
}
}
Eigen::Vector3f Server::PickSafeBoxPos(int skipIdx)
{
// Assumes g_boxes_mutex is already held by the caller
static thread_local std::mt19937 rng{ std::random_device{}() };
std::uniform_real_distribution<float> dist(-1000.f, 1000.f);
for (int attempt = 0; attempt < 500; ++attempt) {
Eigen::Vector3f cand(dist(rng), dist(rng), dist(rng));
bool safe = true;
for (int i = 0; i < (int)g_serverBoxes.size(); ++i) {
if (i == skipIdx) continue;
if (g_serverBoxes[i].destroyed) continue;
if ((cand - g_serverBoxes[i].position).squaredNorm() < 9.f) {
safe = false;
break;
}
}
if (safe) return cand;
}
return Eigen::Vector3f(dist(rng), dist(rng), dist(rng));
}
Eigen::Vector3f Server::PickSafeSpawnPos(int forPlayerId)
{
static thread_local std::mt19937 rng{ std::random_device{}() };
@@ -608,6 +688,8 @@ void Server::update_world() {
std::vector<int> boxesToRespawn;
// --- Tick: box-projectile collisions ---
{
std::lock_guard<std::mutex> bm(g_boxes_mutex);
@@ -632,6 +714,7 @@ void Server::update_world() {
}
for (const auto& [boxIdx, projIdx] : boxProjectileCollisions) {
if (g_serverBoxes[boxIdx].destroyed) continue;
g_serverBoxes[boxIdx].destroyed = true;
Eigen::Vector3f boxWorld = g_serverBoxes[boxIdx].position + Eigen::Vector3f(0.0f, 0.0f, 45000.0f);
@@ -647,6 +730,8 @@ void Server::update_world() {
g_boxDestructions.push_back(destruction);
}
boxesToRespawn.push_back(static_cast<int>(boxIdx));
std::cout << "Server: Box " << boxIdx << " destroyed by projectile from player "
<< g_projectiles[projIdx].shooterId << std::endl;
}
@@ -690,6 +775,8 @@ void Server::update_world() {
g_boxDestructions.push_back(destruction);
}
boxesToRespawn.push_back(static_cast<int>(bi));
std::cout << "Server: Box " << bi << " destroyed by ship collision with player "
<< session->get_id() << std::endl;
break;
@@ -732,6 +819,41 @@ void Server::update_world() {
g_boxDestructions.clear();
}
// --- Respawn destroyed boxes ---
if (!boxesToRespawn.empty()) {
static thread_local std::mt19937 rng{ std::random_device{}() };
static thread_local std::uniform_real_distribution<float> angleDist(0.f, static_cast<float>(M_PI * 2.0));
std::vector<std::string> respawnMsgs;
{
std::lock_guard<std::mutex> bm(g_boxes_mutex);
for (int idx : boxesToRespawn) {
if (idx < 0 || idx >= (int)g_serverBoxes.size()) continue;
Eigen::Vector3f newPos = PickSafeBoxPos(idx);
Eigen::Vector3f axis = Eigen::Vector3f::Random().normalized();
Eigen::Matrix3f newRot = Eigen::AngleAxisf(angleDist(rng), axis).toRotationMatrix();
g_serverBoxes[idx].position = newPos;
g_serverBoxes[idx].rotation = newRot;
g_serverBoxes[idx].destroyed = false;
Eigen::Quaternionf q(newRot);
std::string respawnMsg = "BOX_RESPAWN:" +
std::to_string(idx) + ":" +
std::to_string(newPos.x()) + ":" +
std::to_string(newPos.y()) + ":" +
std::to_string(newPos.z()) + ":" +
std::to_string(q.w()) + ":" +
std::to_string(q.x()) + ":" +
std::to_string(q.y()) + ":" +
std::to_string(q.z());
respawnMsgs.push_back(respawnMsg);
std::cout << "Server: Box " << idx << " respawned" << std::endl;
}
}
for (const auto& msg : respawnMsgs) {
broadcastToAll(msg);
}
}
// --- Schedule next tick in 50ms ---
timer.expires_after(std::chrono::milliseconds(50));
timer.async_wait([this](const boost::system::error_code& ec) {
@@ -820,6 +942,7 @@ int main() {
Server server(acceptor, ioc);
server.init();
server.accept();
std::cout << "Server started on port 8081...\n";
+2
View File
@@ -135,6 +135,8 @@ public:
void createProjectile(int id, Eigen::Vector3f pos, Eigen::Quaternionf dir, float velocity);
void update_world();
Eigen::Vector3f PickSafeSpawnPos(int forPlayerId);
// Caller must hold g_boxes_mutex
Eigen::Vector3f PickSafeBoxPos(int skipIdx);
void init();
void accept();
};