vectozavr-shooter/network/ShooterClient.cpp

357 lines
15 KiB
C++
Raw Normal View History

2021-09-13 15:53:43 +03:00
//
// Created by Иван Ильин on 25.05.2021.
//
2021-10-28 17:06:10 +03:00
#include "ShooterClient.h"
2021-10-02 20:36:07 +03:00
2022-07-23 13:07:29 +03:00
#include <SFML/Network/Ftp.hpp>
#include <string>
2021-10-02 20:36:07 +03:00
#include <utility>
#include "../3dzavr/engine/utils/Log.h"
#include "../3dzavr/engine/animation/Timeline.h"
2021-10-28 16:58:02 +03:00
#include "ShooterMsgType.h"
#include "../3dzavr/engine/animation/Animations.h"
#include "../3dzavr/engine/utils/EventHandler.h"
ShooterClient::ShooterClient(std::shared_ptr<Player> player) : _player(player) {
EventHandler::listen<void(const std::string&)>(
Event("take_bonus"),
[this](const std::string& name){ this->takeBonus(name); }
);
EventHandler::listen<void(sf::Uint16, double)>(
Event("damage_player"),
[this](sf::Uint16 targetId, double damage) { damagePlayer(targetId, damage); } );
EventHandler::listen<void(const Vec3D&, const Vec3D&)>(
Event("your_bullet"),
[this](const Vec3D &from, const Vec3D &to) {
sendTrace(from, to);
});
EventHandler::listen<void(const std::string&)>(
Event("change_weapon"),
[this](const std::string &name){ changeWeapon(name); }
);
}
2021-10-31 22:11:04 +03:00
2021-10-28 17:06:10 +03:00
void ShooterClient::updatePacket() {
2021-09-13 15:53:43 +03:00
sf::Packet packet;
2021-10-31 11:39:08 +03:00
packet << MsgType::ClientUpdate << _player->position().x() << _player->position().y() << _player->position().z()
<< _player->angle().y() << _player->headAngle() << _player->playerNickName();
2021-09-13 15:53:43 +03:00
_socket.send(packet, _socket.serverId());
}
2021-10-31 11:39:08 +03:00
void ShooterClient::processInit(sf::Packet &packet) {
2021-09-13 15:53:43 +03:00
sf::Uint16 targetId;
2022-02-23 17:29:42 +03:00
double x, y, z, health;
2021-10-26 10:08:41 +03:00
int kills, deaths;
2021-09-13 15:53:43 +03:00
2022-02-23 17:29:42 +03:00
while (packet >> targetId >> x >> y >> z >> health >> kills >> deaths) {
2021-10-31 11:39:08 +03:00
if (targetId != _socket.ownId()) {
EventHandler::call<void(sf::Uint16)>(Event("spawn_player"), targetId);
2022-02-23 17:29:42 +03:00
_players[targetId]->translateToPoint(Vec3D{x, y, z});
_players[targetId]->setHealth(health);
2021-10-26 10:08:41 +03:00
_players[targetId]->setKills(kills);
_players[targetId]->setDeaths(deaths);
2021-09-13 15:53:43 +03:00
}
}
}
2021-10-31 11:39:08 +03:00
void ShooterClient::processUpdate(sf::Packet &packet) {
2021-09-13 15:53:43 +03:00
sf::Uint16 targetId;
2022-02-23 17:29:42 +03:00
double x, y, z, health, bodyAngle, headAngle;
2021-10-26 09:40:35 +03:00
std::string playerName;
2021-09-13 15:53:43 +03:00
2022-02-23 17:29:42 +03:00
while (packet >> targetId >> x >> y >> z >> health >> bodyAngle >> headAngle >> playerName) {
2021-09-13 15:53:43 +03:00
if (_players.count(targetId)) {
2021-10-28 16:58:02 +03:00
std::string name = "Enemy_" + std::to_string(targetId);
2022-07-22 22:52:54 +03:00
2022-02-23 17:29:42 +03:00
Vec3D newPosition = Vec3D{x, y, z};
2021-11-06 22:11:06 +03:00
bool isAnimate = (_players[targetId]->position() - newPosition).sqrAbs() > 0.2;
_players[targetId]->translateToPoint(newPosition);
2021-10-25 22:32:55 +03:00
2022-02-23 17:29:42 +03:00
_players[targetId]->setHealth(health);
_players[targetId]->rotateToAngle(Vec3D{0, bodyAngle, 0});
2021-10-28 16:58:02 +03:00
_players[targetId]->setPlayerNickName(playerName);
2021-10-31 11:39:08 +03:00
auto head = _players[targetId]->attached(ObjectNameTag(name + "_head"));
2021-10-28 16:58:02 +03:00
auto weapon = _players[targetId]->attached(ObjectNameTag("Enemy_" + std::to_string(targetId) + "_weapon"));
2021-11-06 22:11:06 +03:00
auto foot1 = _players[targetId]->attached(ObjectNameTag(name + "_foot_1"));
auto foot2 = _players[targetId]->attached(ObjectNameTag(name + "_foot_2"));
2021-10-31 11:39:08 +03:00
if (head != nullptr) {
2022-02-23 17:29:42 +03:00
head->rotateLeft(headAngle - _players[targetId]->headAngle());
2021-10-28 16:58:02 +03:00
}
2021-10-31 11:39:08 +03:00
if (weapon != nullptr) {
2022-02-23 17:29:42 +03:00
weapon->rotateLeft(headAngle - _players[targetId]->headAngle());
2021-11-06 22:11:06 +03:00
}
2021-11-09 22:54:20 +03:00
if (isAnimate) {
if (foot1 != nullptr && foot2 != nullptr &&
!Timeline::isInAnimList(AnimationListTag(name + "_foot1_rotation"))) {
Timeline::addAnimation<ARotateLeft>(AnimationListTag(name + "_foot1_rotation"),
foot1, 0.6, 0.2, Animation::LoopOut::None,
Animation::InterpolationType::Linear);
Timeline::addAnimation<AWait>(AnimationListTag(name + "_foot1_rotation"), 0);
Timeline::addAnimation<ARotateLeft>(AnimationListTag(name + "_foot1_rotation"),
foot1, -1.2, 0.2, Animation::LoopOut::None,
Animation::InterpolationType::Linear);
Timeline::addAnimation<AWait>(AnimationListTag(name + "_foot1_rotation"), 0);
Timeline::addAnimation<ARotateLeft>(AnimationListTag(name + "_foot1_rotation"),
foot1, 0.6, 0.2, Animation::LoopOut::None,
Animation::InterpolationType::Linear);
Timeline::addAnimation<ARotateLeft>(AnimationListTag(name + "_foot2_rotation"),
foot2, -0.6, 0.2, Animation::LoopOut::None,
Animation::InterpolationType::Linear);
Timeline::addAnimation<AWait>(AnimationListTag(name + "_foot2_rotation"), 0);
Timeline::addAnimation<ARotateLeft>(AnimationListTag(name + "_foot2_rotation"),
foot2, 1.2, 0.2, Animation::LoopOut::None,
Animation::InterpolationType::Linear);
Timeline::addAnimation<AWait>(AnimationListTag(name + "_foot2_rotation"), 0);
Timeline::addAnimation<ARotateLeft>(AnimationListTag(name + "_foot2_rotation"),
foot2, -0.6, 0.2, Animation::LoopOut::None,
Animation::InterpolationType::Linear);
2021-11-06 22:11:06 +03:00
}
2021-10-28 16:58:02 +03:00
}
2021-10-02 20:36:07 +03:00
2022-02-23 17:29:42 +03:00
_players[targetId]->setHeadAngle(headAngle);
2021-09-13 15:53:43 +03:00
} else if (targetId == _socket.ownId()) {
2022-02-23 17:29:42 +03:00
_player->setHealth(health);
2021-09-13 15:53:43 +03:00
}
}
}
2021-10-31 11:39:08 +03:00
void ShooterClient::processNewClient(sf::Packet &packet) {
2021-09-13 15:53:43 +03:00
sf::Uint16 targetId;
packet >> targetId;
EventHandler::call<void(sf::Uint16)>(Event("spawn_player"), targetId);
2021-09-13 15:53:43 +03:00
}
2021-10-28 17:06:10 +03:00
void ShooterClient::processDisconnect(sf::Uint16 targetId) {
2021-09-13 15:53:43 +03:00
if (targetId != _socket.ownId() && _players.count(targetId)) {
_players.erase(targetId);
EventHandler::call<void(sf::Uint16)>(Event("remove_player"), targetId);
2021-09-13 15:53:43 +03:00
}
}
2022-07-22 22:52:54 +03:00
void ShooterClient::sendMessage(string message){
if (message.length() == 0)
return;
2022-07-22 22:52:54 +03:00
chatManager->addNewMessage(_player->playerNickName(), message);
sf::Packet packet;
packet << MsgType::Custom << ShooterMsgType::newMessage << message;
_socket.send(packet, _socket.serverId());
}
void ShooterClient::sendChatMessage(string message, string name) {
2022-07-22 22:52:54 +03:00
chatManager->addNewMessage(name, message);
}
2021-09-13 15:53:43 +03:00
2021-10-31 11:39:08 +03:00
void ShooterClient::processCustomPacket(sf::Packet &packet) {
2021-09-13 15:53:43 +03:00
sf::Uint16 buffId[2];
double dbuff[10];
std::string tmp, tmp2;
2021-10-28 16:58:02 +03:00
ShooterMsgType type;
packet >> type;
2022-07-22 22:52:54 +03:00
string name, message;
2021-10-28 16:58:02 +03:00
2021-09-13 15:53:43 +03:00
switch (type) {
2021-10-28 16:58:02 +03:00
case ShooterMsgType::Kill:
2021-09-13 15:53:43 +03:00
packet >> buffId[0] >> buffId[1];
2021-10-26 09:50:59 +03:00
_lastEvent = "";
2021-10-31 11:39:08 +03:00
if (buffId[1] == _socket.ownId()) {
2021-10-26 09:50:59 +03:00
_player->addKill();
2022-02-23 17:29:42 +03:00
SoundController::loadAndPlay(SoundTag("kill"), ShooterConsts::KILL_SOUND);
2021-10-28 16:58:02 +03:00
_lastEvent += _player->playerNickName();
2021-10-31 11:39:08 +03:00
} else {
2021-10-26 09:50:59 +03:00
_players[buffId[1]]->addKill();
2021-10-28 16:58:02 +03:00
_lastEvent += _players[buffId[1]]->playerNickName();
2021-10-26 09:50:59 +03:00
}
2021-10-26 14:51:14 +03:00
_lastEvent += " ~> ";
2021-10-26 09:50:59 +03:00
2021-10-31 11:39:08 +03:00
if (buffId[0] == _socket.ownId()) {
2021-09-13 15:53:43 +03:00
_player->addDeath();
2021-10-31 22:11:04 +03:00
auto camera = _player->attached(ObjectNameTag("Camera"));
2021-11-09 22:54:20 +03:00
if (camera == nullptr) {
2021-11-01 09:47:51 +03:00
break;
}
2021-10-31 22:11:04 +03:00
_player->unattach(ObjectNameTag("Camera"));
_player->translateToPoint(Vec3D{10000});
2021-11-03 18:06:41 +03:00
camera->rotateLeft(-camera->angleLeftUpLookAt().x());
camera->transform(Matrix4x4::Rotation(-_player->angle()));
2021-10-31 22:11:04 +03:00
2021-11-09 22:54:20 +03:00
Timeline::addAnimation<ATranslateToPoint>(AnimationListTag("camera_anim"),
camera, Vec3D(0, 30, -100));
Timeline::addAnimation<AWait>(AnimationListTag("camera_anim"), 0);
Timeline::addAnimation<ARotateRelativePoint>(AnimationListTag("camera_anim"),
camera, Vec3D(0), Vec3D{0, Consts::PI, 0},
5, Animation::LoopOut::None,
Animation::InterpolationType::Linear);
Timeline::addAnimation<AWait>(AnimationListTag("camera_anim"), 0);
Timeline::addAnimation<AFunction>(AnimationListTag("camera_anim"), [this, camera]() {
2021-10-31 22:11:04 +03:00
// respawn
2021-11-09 22:54:20 +03:00
_player->translateToPoint(
Vec3D{50.0 * (-1 + 2.0 * (double) rand() / RAND_MAX), 30.0 * (double) rand() / RAND_MAX,
50.0 * (-1 + 2.0 * (double) rand() / RAND_MAX)});
2021-10-31 22:11:04 +03:00
_player->reInitWeapons();
_player->setFullAbility();
camera->rotateToAngle(Vec3D(0));
camera->transform(Matrix4x4::Rotation(Vec3D(_player->angle())));
camera->rotateLeft(_player->headAngle());
camera->translateToPoint(_player->position() + Vec3D{0, 1.8, 0});
_player->attach(camera);
2021-11-09 22:54:20 +03:00
}, 1, 0.1);
2021-10-31 22:11:04 +03:00
2022-02-23 17:29:42 +03:00
SoundController::loadAndPlay(SoundTag("death"), ShooterConsts::DEATH_SOUND);
2021-10-28 16:58:02 +03:00
_lastEvent += _player->playerNickName();
2021-10-31 11:39:08 +03:00
} else {
2021-09-13 15:53:43 +03:00
_players[buffId[0]]->addDeath();
2021-10-28 16:58:02 +03:00
_lastEvent += _players[buffId[0]]->playerNickName();
2021-09-13 15:53:43 +03:00
}
break;
2021-10-28 16:58:02 +03:00
case ShooterMsgType::FireTrace:
2021-09-13 15:53:43 +03:00
if (buffId[0] != _socket.ownId()) {
packet >> dbuff[0] >> dbuff[1] >> dbuff[2] >> dbuff[3] >> dbuff[4] >> dbuff[5];
EventHandler::call<void(const Vec3D&, const Vec3D&)>(
Event("enemy_bullet"),
Vec3D(dbuff[0], dbuff[1], dbuff[2]), Vec3D(dbuff[3], dbuff[4], dbuff[5]));
2021-10-28 16:58:02 +03:00
}
2021-09-13 15:53:43 +03:00
break;
2021-10-28 16:58:02 +03:00
case ShooterMsgType::InitBonuses:
2021-09-13 15:53:43 +03:00
while (packet >> tmp >> dbuff[0] >> dbuff[1] >> dbuff[2]) {
EventHandler::call<void(const string&, const Vec3D&)>(
Event("add_bonus"), tmp, Vec3D(dbuff[0], dbuff[1], dbuff[2]));
2021-09-13 15:53:43 +03:00
}
break;
2021-10-28 16:58:02 +03:00
case ShooterMsgType::AddBonus:
2021-09-13 15:53:43 +03:00
packet >> tmp >> dbuff[0] >> dbuff[1] >> dbuff[2];
EventHandler::call<void(const string&, const Vec3D&)>(
Event("add_bonus"), tmp, Vec3D(dbuff[0], dbuff[1], dbuff[2]));
2021-09-13 15:53:43 +03:00
break;
2021-10-28 16:58:02 +03:00
case ShooterMsgType::RemoveBonus:
2021-09-13 15:53:43 +03:00
packet >> tmp;
EventHandler::call<void(const ObjectNameTag &)>(
Event("remove_bonus"), ObjectNameTag(tmp));
2021-09-13 15:53:43 +03:00
break;
2021-10-28 16:58:02 +03:00
case ShooterMsgType::ChangeWeapon:
packet >> buffId[0] >> tmp;
EventHandler::call<void(const std::string&, sf::Uint16)>(
Event("change_enemy_weapon"), tmp, buffId[0]);
break;
2022-07-22 22:52:54 +03:00
case ShooterMsgType::newMessage:
packet >> name >> message;
sendChatMessage(message, name);
2022-07-22 22:52:54 +03:00
break;
2021-10-17 10:21:10 +03:00
default:
2021-10-31 11:39:08 +03:00
Log::log("ShooterClient::processCustomPacket: unknown message type " +
std::to_string(static_cast<int>(type)));
2021-10-17 10:44:17 +03:00
return;
2021-09-13 15:53:43 +03:00
}
}
2021-10-28 17:06:10 +03:00
void ShooterClient::processDisconnected() {
2021-09-13 15:53:43 +03:00
for (auto it = _players.begin(); it != _players.end();) {
2021-10-02 20:36:07 +03:00
processDisconnect(it++->first);
2021-09-13 15:53:43 +03:00
}
}
2021-10-28 17:06:10 +03:00
void ShooterClient::damagePlayer(sf::Uint16 targetId, double damage) {
2021-09-13 15:53:43 +03:00
sf::Packet packet;
2021-10-28 16:58:02 +03:00
packet << MsgType::Custom << ShooterMsgType::Damage << targetId << damage;
_socket.sendRely(packet, _socket.serverId());
2021-09-13 15:53:43 +03:00
2021-10-28 17:06:10 +03:00
Log::log("ShooterClient: damagePlayer " + std::to_string(targetId) + " ( -" + std::to_string(damage) + "hp )");
2021-09-13 15:53:43 +03:00
}
void ShooterClient::sendTrace(const Vec3D &from, const Vec3D &to) {
2021-09-13 15:53:43 +03:00
sf::Packet packet;
2021-10-31 11:39:08 +03:00
packet << MsgType::Custom << ShooterMsgType::FireTrace << from.x() << from.y() << from.z() << to.x() << to.y()
<< to.z();
2021-09-13 15:53:43 +03:00
_socket.send(packet, _socket.serverId());
}
2021-10-31 11:39:08 +03:00
void ShooterClient::takeBonus(const std::string &bonusName) {
2021-09-13 15:53:43 +03:00
sf::Packet packet;
2021-10-28 16:58:02 +03:00
packet << MsgType::Custom << ShooterMsgType::RemoveBonus << bonusName;
_socket.sendRely(packet, _socket.serverId());
2021-10-02 20:36:07 +03:00
EventHandler::call<void(const ObjectNameTag &)>(
Event("remove_bonus"), ObjectNameTag(bonusName));
2021-10-02 20:36:07 +03:00
}
2021-10-28 17:06:10 +03:00
void ShooterClient::changeWeapon(const std::string &weaponName) {
sf::Packet packet;
2021-10-28 16:58:02 +03:00
packet << MsgType::Custom << ShooterMsgType::ChangeWeapon << weaponName;
_socket.sendRely(packet, _socket.serverId());
}
2021-10-28 17:06:10 +03:00
void ShooterClient::addPlayer(sf::Uint16 id, std::shared_ptr<Player> player) {
2021-10-31 11:39:08 +03:00
_players.insert({id, player});
2021-10-02 20:36:07 +03:00
}
2023-05-21 16:34:55 +03:00
void ShooterClient::requestMap(const std::string& clientIp, std::string *current_map) {
2022-07-23 13:07:29 +03:00
Log::log("---------[FTP server]---------");
sf::Ftp ftp;
sf::Ftp::Response connectResponse = ftp.connect(clientIp, 21);
if (connectResponse.isOk()) {
ftp.login();
sf::Ftp::ListingResponse dirResponse = ftp.getDirectoryListing("current_map/");
Log::log("Response code: "+std::to_string(dirResponse.getStatus())+" | Message: "+dirResponse.getMessage());
if (dirResponse.isOk()) {
const std::vector<std::string>& listing = dirResponse.getListing();
2023-05-21 16:34:55 +03:00
if (listing.size() != 0) {
2022-07-23 13:07:29 +03:00
for (std::vector<std::string>::const_iterator it = listing.begin(); it != listing.end(); ++it)
Log::log("- "+*it);
sf::Ftp::Response downloadResponse = ftp.download(listing.at(0), "./obj/maps/", sf::Ftp::Ascii);
Log::log("Response code: "+std::to_string(downloadResponse.getStatus())+" | Message: "+downloadResponse.getMessage());
if (downloadResponse.isOk()) {
std::string map_path = listing.at(0);
map_path = "./obj/maps"+map_path.substr(map_path.find("/"));
Log::log("Map set to: "+map_path);
2023-05-21 16:34:55 +03:00
*current_map = map_path;
2022-07-23 13:07:29 +03:00
}
} else {
Log::log("there is no map file");
}
2023-05-21 16:34:55 +03:00
}
2022-07-23 13:07:29 +03:00
ftp.disconnect();
} else {
Log::log("Couldn't connect to FTP server with ip: "+clientIp+" and port: 21");
}
Log::log("------------------------------");
}