feat: 강화 결과 채팅으로 모든 클라이언트가 같이 공유
This commit is contained in:
parent
1e922ca3e8
commit
b9c5a22989
3 changed files with 109 additions and 41 deletions
|
|
@ -67,16 +67,60 @@ bool BaseClient::Login(const std::string &nickname) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BaseClient::StartReceive() {
|
||||||
|
isRunning_ = true;
|
||||||
|
receiveThread_ = std::jthread(&BaseClient::ReceiveLoop, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BaseClient::StopReceive() {
|
||||||
|
isRunning_ = false;
|
||||||
|
socket_.close();
|
||||||
|
receiveThread_.request_stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
void BaseClient::ReceiveLoop(std::stop_token stopToken) {
|
||||||
|
try {
|
||||||
|
while (!stopToken.stop_requested() && isRunning_) {
|
||||||
|
PacketHeader header;
|
||||||
|
if (!ReceiveHeader(header))
|
||||||
|
break;
|
||||||
|
HandlePacket(header);
|
||||||
|
}
|
||||||
|
} catch (...) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void BaseClient::HandlePacket(const PacketHeader &header) {
|
||||||
|
PacketID id = static_cast<PacketID>(header.id);
|
||||||
|
switch (id) {
|
||||||
|
case PacketID::Chat: {
|
||||||
|
std::vector<char> buffer(header.size + 1, 0);
|
||||||
|
boost::asio::read(socket_, boost::asio::buffer(buffer.data(), header.size));
|
||||||
|
std::cout << "\n" << buffer.data() << std::endl;
|
||||||
|
} break;
|
||||||
|
case PacketID::SC_UpgradeResult:
|
||||||
|
HandleUpgradeResult();
|
||||||
|
break;
|
||||||
|
case PacketID::SC_SellResult:
|
||||||
|
HandleSellResult();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// 처리하지 않는 패킷은 페이로드만 건너뜀
|
||||||
|
if (header.size > 0) {
|
||||||
|
std::vector<uint8_t> dummy(header.size);
|
||||||
|
boost::asio::read(socket_,
|
||||||
|
boost::asio::buffer(dummy.data(), header.size));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void BaseClient::HandleUpgradeResult() {
|
void BaseClient::HandleUpgradeResult() {
|
||||||
PKT_SC_UpgradeResult res;
|
PKT_SC_UpgradeResult res;
|
||||||
if (ReceivePayload(res)) {
|
if (ReceivePayload(res)) {
|
||||||
currentLevel_ = res.currentLevel;
|
currentLevel_ = res.currentLevel;
|
||||||
currentGold_ = res.currentGold;
|
currentGold_ = res.currentGold;
|
||||||
std::string resultStr =
|
// 강화 결과 출력은 채팅으로
|
||||||
(res.result == 1) ? "성공" : (res.result == 0 ? "파괴!!!" : "실패");
|
|
||||||
std::cout << ">> 강화 결과: " << resultStr
|
|
||||||
<< " (현재레벨: " << currentLevel_
|
|
||||||
<< ", 남은골드: " << currentGold_ << ")" << std::endl;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -85,8 +129,9 @@ void BaseClient::HandleSellResult() {
|
||||||
if (ReceivePayload(res)) {
|
if (ReceivePayload(res)) {
|
||||||
currentLevel_ = 0;
|
currentLevel_ = 0;
|
||||||
currentGold_ = res.totalGold;
|
currentGold_ = res.totalGold;
|
||||||
std::cout << ">> 판매 결과: " << res.earnedGold
|
// 판매 결과는 본인에게만
|
||||||
<< " 골드 획득! (총 골드: " << currentGold_ << ")" << std::endl;
|
std::cout << "\n>> 판매 완료: " << res.earnedGold << " 골드 획득!"
|
||||||
|
<< std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -98,9 +143,13 @@ void InteractiveClient::Run() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 로그인 후 비동기 수신 시작
|
||||||
|
StartReceive();
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
if (currentLevel_ == 0) {
|
if (currentLevel_ == 0) {
|
||||||
std::cout << "\n[현재 검 없음] 1. 검 구매 시도, 2. 종료\n입력: ";
|
std::cout << "\n[현재 검 없음, 골드: " << currentGold_
|
||||||
|
<< "] 1. 검 구매 시도 (1000골드), 2. 종료\n입력: ";
|
||||||
} else {
|
} else {
|
||||||
std::cout << "\n[현재 검 레벨: " << currentLevel_
|
std::cout << "\n[현재 검 레벨: " << currentLevel_
|
||||||
<< ", 골드: " << currentGold_
|
<< ", 골드: " << currentGold_
|
||||||
|
|
@ -114,34 +163,24 @@ void InteractiveClient::Run() {
|
||||||
if (currentLevel_ == 0) {
|
if (currentLevel_ == 0) {
|
||||||
if (choice == 1) {
|
if (choice == 1) {
|
||||||
SendPacket(PacketID::CS_UpgradeSword);
|
SendPacket(PacketID::CS_UpgradeSword);
|
||||||
PacketHeader header;
|
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||||
if (ReceiveHeader(header) &&
|
|
||||||
header.id == static_cast<uint16_t>(PacketID::SC_UpgradeResult)) {
|
|
||||||
HandleUpgradeResult();
|
|
||||||
}
|
|
||||||
} else if (choice == 2) {
|
} else if (choice == 2) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (choice == 1) {
|
if (choice == 1) {
|
||||||
SendPacket(PacketID::CS_UpgradeSword);
|
SendPacket(PacketID::CS_UpgradeSword);
|
||||||
PacketHeader header;
|
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||||
if (ReceiveHeader(header) &&
|
|
||||||
header.id == static_cast<uint16_t>(PacketID::SC_UpgradeResult)) {
|
|
||||||
HandleUpgradeResult();
|
|
||||||
}
|
|
||||||
} else if (choice == 2) {
|
} else if (choice == 2) {
|
||||||
SendPacket(PacketID::CS_SellSword);
|
SendPacket(PacketID::CS_SellSword);
|
||||||
PacketHeader header;
|
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||||
if (ReceiveHeader(header) &&
|
|
||||||
header.id == static_cast<uint16_t>(PacketID::SC_SellResult)) {
|
|
||||||
HandleSellResult();
|
|
||||||
}
|
|
||||||
} else if (choice == 3) {
|
} else if (choice == 3) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
StopReceive();
|
||||||
}
|
}
|
||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
|
@ -161,6 +200,9 @@ void ScenarioClient::Run() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 비동기 수신 시작
|
||||||
|
StartReceive();
|
||||||
|
|
||||||
std::string line;
|
std::string line;
|
||||||
while (is >> line) {
|
while (is >> line) {
|
||||||
int choice = std::stoi(line);
|
int choice = std::stoi(line);
|
||||||
|
|
@ -169,33 +211,23 @@ void ScenarioClient::Run() {
|
||||||
if (currentLevel_ == 0) {
|
if (currentLevel_ == 0) {
|
||||||
if (choice == 1) {
|
if (choice == 1) {
|
||||||
SendPacket(PacketID::CS_UpgradeSword);
|
SendPacket(PacketID::CS_UpgradeSword);
|
||||||
PacketHeader header;
|
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||||
if (ReceiveHeader(header) &&
|
|
||||||
header.id == static_cast<uint16_t>(PacketID::SC_UpgradeResult)) {
|
|
||||||
HandleUpgradeResult();
|
|
||||||
}
|
|
||||||
} else if (choice == 2) {
|
} else if (choice == 2) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (choice == 1) {
|
if (choice == 1) {
|
||||||
SendPacket(PacketID::CS_UpgradeSword);
|
SendPacket(PacketID::CS_UpgradeSword);
|
||||||
PacketHeader header;
|
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||||
if (ReceiveHeader(header) &&
|
|
||||||
header.id == static_cast<uint16_t>(PacketID::SC_UpgradeResult)) {
|
|
||||||
HandleUpgradeResult();
|
|
||||||
}
|
|
||||||
} else if (choice == 2) {
|
} else if (choice == 2) {
|
||||||
SendPacket(PacketID::CS_SellSword);
|
SendPacket(PacketID::CS_SellSword);
|
||||||
PacketHeader header;
|
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||||
if (ReceiveHeader(header) &&
|
|
||||||
header.id == static_cast<uint16_t>(PacketID::SC_SellResult)) {
|
|
||||||
HandleSellResult();
|
|
||||||
}
|
|
||||||
} else if (choice == 3) {
|
} else if (choice == 3) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
StopReceive();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,10 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Packet.h"
|
#include "Packet.h"
|
||||||
|
#include <atomic>
|
||||||
#include <boost/asio.hpp>
|
#include <boost/asio.hpp>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
using boost::asio::ip::tcp;
|
using boost::asio::ip::tcp;
|
||||||
|
|
||||||
|
|
@ -29,6 +31,10 @@ public:
|
||||||
|
|
||||||
bool Login(const std::string &nickname);
|
bool Login(const std::string &nickname);
|
||||||
|
|
||||||
|
// 비동기 수신 시작
|
||||||
|
void StartReceive();
|
||||||
|
void StopReceive();
|
||||||
|
|
||||||
virtual void Run() = 0;
|
virtual void Run() = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
@ -37,6 +43,12 @@ protected:
|
||||||
uint64_t currentGold_ = 0;
|
uint64_t currentGold_ = 0;
|
||||||
std::string nickname_;
|
std::string nickname_;
|
||||||
|
|
||||||
|
std::jthread receiveThread_;
|
||||||
|
std::atomic<bool> isRunning_{false};
|
||||||
|
|
||||||
|
void ReceiveLoop(std::stop_token stopToken);
|
||||||
|
void HandlePacket(const PacketHeader &header);
|
||||||
|
|
||||||
void HandleUpgradeResult();
|
void HandleUpgradeResult();
|
||||||
void HandleSellResult();
|
void HandleSellResult();
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -103,6 +103,7 @@ PacketHandler::HandlePacket(std::shared_ptr<Session> session,
|
||||||
res.currentLevel = session->GetSwordLevel();
|
res.currentLevel = session->GetSwordLevel();
|
||||||
res.currentGold = session->GetGold();
|
res.currentGold = session->GetGold();
|
||||||
|
|
||||||
|
// 결과 패킷 전송
|
||||||
PacketHeader header;
|
PacketHeader header;
|
||||||
header.id = static_cast<uint16_t>(PacketID::SC_UpgradeResult);
|
header.id = static_cast<uint16_t>(PacketID::SC_UpgradeResult);
|
||||||
header.size = sizeof(PKT_SC_UpgradeResult);
|
header.size = sizeof(PKT_SC_UpgradeResult);
|
||||||
|
|
@ -112,11 +113,34 @@ PacketHandler::HandlePacket(std::shared_ptr<Session> session,
|
||||||
std::memcpy(buffer.data(), &header, sizeof(PacketHeader));
|
std::memcpy(buffer.data(), &header, sizeof(PacketHeader));
|
||||||
std::memcpy(buffer.data() + sizeof(PacketHeader), &res,
|
std::memcpy(buffer.data() + sizeof(PacketHeader), &res,
|
||||||
sizeof(PKT_SC_UpgradeResult));
|
sizeof(PKT_SC_UpgradeResult));
|
||||||
|
|
||||||
session->Send(buffer);
|
session->Send(buffer);
|
||||||
|
|
||||||
Logger::Log("강화 시도 [", session->GetNickname(), "]: ", (int)res.result,
|
// 브로드캐스트
|
||||||
" (레벨: ", currentLevel, "->", res.currentLevel, ")");
|
if (currentGold >= cost) {
|
||||||
|
uint32_t attemptedLevel = currentLevel + 1;
|
||||||
|
std::string resultText;
|
||||||
|
if (res.result == 1) {
|
||||||
|
resultText = "를 달성했습니다!";
|
||||||
|
} else if (res.result == 0) {
|
||||||
|
resultText = " 시도 중 검이 파괴되었습니다!";
|
||||||
|
} else {
|
||||||
|
resultText = " 달성에 실패했습니다!";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string chatMsg = "채팅] " + session->GetNickname() +
|
||||||
|
" 님이 검 강화 단계 " +
|
||||||
|
std::to_string(attemptedLevel) + resultText;
|
||||||
|
|
||||||
|
PacketHeader chatHeader;
|
||||||
|
chatHeader.id = static_cast<uint16_t>(PacketID::Chat);
|
||||||
|
chatHeader.size = static_cast<uint16_t>(chatMsg.size());
|
||||||
|
|
||||||
|
std::vector<uint8_t> chatPayload(chatMsg.begin(), chatMsg.end());
|
||||||
|
SessionManager::GetInstance().Broadcast(chatHeader, chatPayload);
|
||||||
|
|
||||||
|
Logger::Log("강화 시도 [", session->GetNickname(), "]: ", (int)res.result,
|
||||||
|
" (레벨: ", currentLevel, "->", res.currentLevel, ")");
|
||||||
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case PacketID::CS_SellSword: {
|
case PacketID::CS_SellSword: {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue