Merge branch 'main' into linux
This commit is contained in:
commit
9e6ff5e08f
@ -31,8 +31,8 @@ bool Session::is_timed_out(std::chrono::system_clock::time_point now) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Session::force_disconnect() {
|
void Session::force_disconnect() {
|
||||||
ws_.async_close(websocket::close_code::normal,
|
beast::error_code ec;
|
||||||
[self = shared_from_this()](beast::error_code) {});
|
ws_.next_layer().socket().close(ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
int Session::get_id() const { return id_; }
|
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";
|
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") {
|
else if (parts[0] == "FIRE") {
|
||||||
if (parts.size() < 10) return;
|
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)
|
Eigen::Vector3f Server::PickSafeSpawnPos(int forPlayerId)
|
||||||
{
|
{
|
||||||
static thread_local std::mt19937 rng{ std::random_device{}() };
|
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 ---
|
// --- Tick: box-projectile collisions ---
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> bm(g_boxes_mutex);
|
std::lock_guard<std::mutex> bm(g_boxes_mutex);
|
||||||
@ -632,6 +714,7 @@ void Server::update_world() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (const auto& [boxIdx, projIdx] : boxProjectileCollisions) {
|
for (const auto& [boxIdx, projIdx] : boxProjectileCollisions) {
|
||||||
|
if (g_serverBoxes[boxIdx].destroyed) continue;
|
||||||
g_serverBoxes[boxIdx].destroyed = true;
|
g_serverBoxes[boxIdx].destroyed = true;
|
||||||
|
|
||||||
Eigen::Vector3f boxWorld = g_serverBoxes[boxIdx].position + Eigen::Vector3f(0.0f, 0.0f, 45000.0f);
|
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);
|
g_boxDestructions.push_back(destruction);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boxesToRespawn.push_back(static_cast<int>(boxIdx));
|
||||||
|
|
||||||
std::cout << "Server: Box " << boxIdx << " destroyed by projectile from player "
|
std::cout << "Server: Box " << boxIdx << " destroyed by projectile from player "
|
||||||
<< g_projectiles[projIdx].shooterId << std::endl;
|
<< g_projectiles[projIdx].shooterId << std::endl;
|
||||||
}
|
}
|
||||||
@ -690,6 +775,8 @@ void Server::update_world() {
|
|||||||
g_boxDestructions.push_back(destruction);
|
g_boxDestructions.push_back(destruction);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boxesToRespawn.push_back(static_cast<int>(bi));
|
||||||
|
|
||||||
std::cout << "Server: Box " << bi << " destroyed by ship collision with player "
|
std::cout << "Server: Box " << bi << " destroyed by ship collision with player "
|
||||||
<< session->get_id() << std::endl;
|
<< session->get_id() << std::endl;
|
||||||
break;
|
break;
|
||||||
@ -732,6 +819,41 @@ void Server::update_world() {
|
|||||||
g_boxDestructions.clear();
|
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 ---
|
// --- Schedule next tick in 50ms ---
|
||||||
timer.expires_after(std::chrono::milliseconds(50));
|
timer.expires_after(std::chrono::milliseconds(50));
|
||||||
timer.async_wait([this](const boost::system::error_code& ec) {
|
timer.async_wait([this](const boost::system::error_code& ec) {
|
||||||
@ -820,6 +942,7 @@ int main() {
|
|||||||
|
|
||||||
Server server(acceptor, ioc);
|
Server server(acceptor, ioc);
|
||||||
|
|
||||||
|
server.init();
|
||||||
server.accept();
|
server.accept();
|
||||||
|
|
||||||
std::cout << "Server started on port 8010...\n";
|
std::cout << "Server started on port 8010...\n";
|
||||||
|
|||||||
@ -135,6 +135,8 @@ public:
|
|||||||
void createProjectile(int id, Eigen::Vector3f pos, Eigen::Quaternionf dir, float velocity);
|
void createProjectile(int id, Eigen::Vector3f pos, Eigen::Quaternionf dir, float velocity);
|
||||||
void update_world();
|
void update_world();
|
||||||
Eigen::Vector3f PickSafeSpawnPos(int forPlayerId);
|
Eigen::Vector3f PickSafeSpawnPos(int forPlayerId);
|
||||||
|
// Caller must hold g_boxes_mutex
|
||||||
|
Eigen::Vector3f PickSafeBoxPos(int skipIdx);
|
||||||
void init();
|
void init();
|
||||||
void accept();
|
void accept();
|
||||||
};
|
};
|
||||||
|
|||||||
@ -265,6 +265,7 @@ namespace ZL
|
|||||||
Environment::shipState.position = Vector3f{ 0, 0, 45000.f };
|
Environment::shipState.position = Vector3f{ 0, 0, 45000.f };
|
||||||
Environment::shipState.velocity = 0.0f;
|
Environment::shipState.velocity = 0.0f;
|
||||||
Environment::shipState.selectedVelocity = 0;
|
Environment::shipState.selectedVelocity = 0;
|
||||||
|
newShipVelocity = 0;
|
||||||
Environment::shipState.rotation = Eigen::Matrix3f::Identity();
|
Environment::shipState.rotation = Eigen::Matrix3f::Identity();
|
||||||
Environment::inverseShipMatrix = Eigen::Matrix3f::Identity();
|
Environment::inverseShipMatrix = Eigen::Matrix3f::Identity();
|
||||||
Environment::zoom = DEFAULT_ZOOM;
|
Environment::zoom = DEFAULT_ZOOM;
|
||||||
@ -274,7 +275,21 @@ namespace ZL
|
|||||||
{
|
{
|
||||||
menuManager.uiManager.findButton("minusButton")->state = ButtonState::Disabled;
|
menuManager.uiManager.findButton("minusButton")->state = ButtonState::Disabled;
|
||||||
}
|
}
|
||||||
|
if (menuManager.uiManager.findButton("plusButton"))
|
||||||
|
{
|
||||||
|
menuManager.uiManager.findButton("plusButton")->state = ButtonState::Normal;
|
||||||
|
}
|
||||||
|
if (Environment::shipState.shipType == 0)
|
||||||
|
{
|
||||||
|
if (menuManager.uiManager.findButton("shootButton"))
|
||||||
|
{
|
||||||
|
menuManager.uiManager.findButton("shootButton")->state = ButtonState::Normal;
|
||||||
|
}
|
||||||
|
if (menuManager.uiManager.findButton("shootButton2"))
|
||||||
|
{
|
||||||
|
menuManager.uiManager.findButton("shootButton2")->state = ButtonState::Normal;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Space::setup() {
|
void Space::setup() {
|
||||||
@ -1702,6 +1717,7 @@ namespace ZL
|
|||||||
gameOver = true;
|
gameOver = true;
|
||||||
Environment::shipState.selectedVelocity = 0;
|
Environment::shipState.selectedVelocity = 0;
|
||||||
Environment::shipState.velocity = 0.0f;
|
Environment::shipState.velocity = 0.0f;
|
||||||
|
newShipVelocity = 0;
|
||||||
showExplosion = true;
|
showExplosion = true;
|
||||||
|
|
||||||
explosionEmitter.setUseWorldSpace(true);
|
explosionEmitter.setUseWorldSpace(true);
|
||||||
@ -1803,7 +1819,7 @@ namespace ZL
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool canPickup = false;
|
bool canPickup = false;
|
||||||
if (Environment::shipState.shipType == 1) {
|
if (Environment::shipState.shipType == 1 && Environment::shipState.velocity < 0.1f) {
|
||||||
for (size_t i = 0; i < boxCoordsArr.size(); ++i) {
|
for (size_t i = 0; i < boxCoordsArr.size(); ++i) {
|
||||||
if (i >= boxAlive.size() || !boxAlive[i]) continue;
|
if (i >= boxAlive.size() || !boxAlive[i]) continue;
|
||||||
Vector3f boxWorld = boxCoordsArr[i].pos + Vector3f{ 0.f, 0.f, 45000.f };
|
Vector3f boxWorld = boxCoordsArr[i].pos + Vector3f{ 0.f, 0.f, 45000.f };
|
||||||
|
|||||||
@ -31,11 +31,11 @@ constexpr long long PLAYER_TIMEOUT_MS = 10000; //ms — disconnect if no UPD rec
|
|||||||
constexpr float PROJECTILE_VELOCITY = 600.f;
|
constexpr float PROJECTILE_VELOCITY = 600.f;
|
||||||
constexpr float PROJECTILE_LIFE = 15000.f; //ms
|
constexpr float PROJECTILE_LIFE = 15000.f; //ms
|
||||||
|
|
||||||
const float projectileHitRadius = 1.5f * 5;
|
const float projectileHitRadius = 1.5f * 4;
|
||||||
const float boxCollisionRadius = 2.0f * 5;
|
const float boxCollisionRadius = 2.0f * 4;
|
||||||
const float shipCollisionRadius = 15.0f * 5;
|
const float shipCollisionRadius = 15.0f * 3;
|
||||||
const float BOX_PICKUP_RADIUS = shipCollisionRadius * 5;
|
const float BOX_PICKUP_RADIUS = shipCollisionRadius * 3;
|
||||||
const float npcCollisionRadius = 5.0f * 5;
|
const float npcCollisionRadius = 5.0f * 3;
|
||||||
|
|
||||||
uint32_t fnv1a_hash(const std::string& data);
|
uint32_t fnv1a_hash(const std::string& data);
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user