// Created: 2018/1/24
// Describe:战斗逻辑
#ifndef CBATTLE_H
#define CBATTLE_H
// ========================================================================
// Include Files
// ========================================================================
#include "../IModule.h"
#include "../../message/ndmsg.pb.h"
#include "../../protocol/Protobuf.h"
#include "../../socket/ConnectionManager.h"
#include "../../socket/SocketLibTypes.h"
#include "PvpDao.h"
#include "PvpMgr.h"
#include "msg/pvp.pb.h"
using namespace std;
using namespace nd;
namespace nd
{
class Battle
{
public:
Battle()
{
}
void SET(BM_PTR BM);
~Battle()
{
}
nd::Battle Action(Battle B, BA_PTR action);
int Lv;
int ATK;
int HP;
int DEF;
int MP;
string RoleName;
};
}
#endif
#include<string>
#include<iostream>
#include"Battle.h"
using namespace std;
void nd::Battle::SET(BM_PTR BM)
{
this->Lv = BM->lv();
this->ATK = BM->atk();
this->HP = BM->hp();
this->DEF = BM->def();
this->MP = BM->mp();
this->RoleName = BM->rolename();
}
Battle Battle::Action(Battle B, BA_PTR action)
{
if (action->skill()=="fire")
{
B.HP -= this->ATK * 2-B.DEF;
return B ;
}
else if(action->skill() == "strike")
{
B.HP -= this->ATK;
return B;
}
return B;
}
// Created: 2018/1/24
// Describe:pvp战斗类
#ifndef CPVPMGR_H
#define CPVPMGR_H
// ========================================================================
// Include Files
// ========================================================================
#include "../IModule.h"
#include "../../message/ndmsg.pb.h"
#include "../../protocol/Protobuf.h"
#include "../../socket/ConnectionManager.h"
#include "../../socket/SocketLibTypes.h"
#include "PvpDao.h"
#include "msg/pvp.pb.h"
#include "Battle.h"
using namespace std;
using namespace nd;
namespace nd
{
/*class IUserStatusChangeEvent
{
public:
//virtual void UserOnline(const string& strAccount) = 0;
//virtual void UserOffline(const string& strAccount) = 0;
};*/
class CPvpMgr : public IModule, public SocketLib::IConnectionEvent
{
// UID <-> PLAYER
typedef std::map<int, PVPReq_PTR > PVPReq_MAP;
typedef std::map<int, PVPReq_PTR >::iterator PVPReq_ITER;
//typedef std::list< std::shared_ptr<IUserStatusChangeEvent> > USER_STATUS_LISTENNER_LIST;
//typedef typename std::list< std::shared_ptr<IUserStatusChangeEvent> >::iterator USER_STATUS_LISTENNER_LIST_ITR;
public:
CPvpMgr()
{
}
virtual bool Init() override
{
return true;
}
virtual bool Start() override
{
return true;
}
virtual bool Stop() override
{
return true;
}
virtual bool Reload() override
{
return true;
}
virtual void HandleMsg(std::shared_ptr<nd::SelfDescribingMessage> pMsg) override;
virtual string GetModuleName() override
{
return "nd.pvp";
}
virtual void ConnectionClosed(SocketLib::DataSocket sock) override;
// ------------------------------------------------------------------------
// Description: This add listener to m_listenners.
// ------------------------------------------------------------------------
/*void AddListener(std::shared_ptr<IUserStatusChangeEvent> pListenner)
{
m_listenerList.push_back(pListenner);
}
*/
// ------------------------------------------------------------------------
// Description: notify all listenners user status.
// ------------------------------------------------------------------------
/* void NotifyUserListenners(const string& strAccount, bool bOnline);*/
private:
void PVPReq(int iSocket, PVPReq_PTR pPvpReq);
void GameAction(int iSocket,BA_PTR pBAMsg);
BM_PTR BM1;
BM_PTR BM2;
PVPReq_MAP PVPReqMap;//用户列表
//USER_STATUS_LISTENNER_LIST m_listenerList;
};
} // end namespace BasicLib
#endif
#include "../../utils/StringUtils.h"
#include "../../basic/Basic.h"
#include "../../protocol/Protobuf.h"
#include "../../message/MsgMgr.h"
#include "../../socket/SocketLibSystem.h"
#include "PvpMgr.h"
#include "../../protocol/Protobuf.h"
#include "Battle.h"
using namespace nd;
Battle A;
Battle B;
void nd::CPvpMgr::HandleMsg(std::shared_ptr<nd::SelfDescribingMessage> pMsg)
{
//解码失败函数
CProtobuf::ErrorCode pErrorCode;
MessagePtr pInnerMsg = CProtobuf::parseInnerMsg(pMsg, pErrorCode);
if (nd::CProtobuf::ErrorCode::UNKNOWN_MESSAGE_TYPE == pErrorCode || nd::CProtobuf::ErrorCode::PARSE_ERROR == pErrorCode)
{
logger_error("CProtobuf parseInnerMsg failed");
std::shared_ptr<nd::SelfDescribingMessage> pPayload(NEW_ND nd::SelfDescribingMessage());
pPayload->add_socket(pMsg->socket(0));
std::shared_ptr<nd::ErrorMessage> pErrorMessage(NEW_ND nd::ErrorMessage());
pErrorMessage->set_desc("account already exist");
pPayload->set_message_data(pErrorMessage->SerializeAsString());
pPayload->set_type_name(pErrorMessage->GetTypeName());
CMsgMgr::Instance().InsertResponseMsg(pPayload);
return;
}
//pvp发起
if ("nd.pvp.PVPReq" == pMsg->type_name())
{
logger_debug("begin handle pvpreq msg");
if (NULL != pInnerMsg)
{
PVPReq_PTR pPvpReq = dynamic_pointer_cast<nd::pvp::PVPReq>(pInnerMsg);
PVPReq(pMsg->socket(0), pPvpReq);
}
}
else if("nd.pvp.BattleAction"==pMsg->type_name())
{
logger_debug("begin handle pvpreq msg");
if (NULL != pInnerMsg)
{
BA_PTR pBA = dynamic_pointer_cast<nd::pvp::BattleAction>(pInnerMsg);
GameAction(pMsg->socket(0),pBA);
}
}
else
{
logger_debug("discard unknown user module msg {}", pMsg->GetTypeName());
}
}
void nd::CPvpMgr::ConnectionClosed(SocketLib::DataSocket sock)
{
}
void nd::CPvpMgr::PVPReq(int iSocket, PVPReq_PTR pPvpReq)
{
std::shared_ptr<nd::SelfDescribingMessage> pPayload(NEW_ND nd::SelfDescribingMessage());
std::shared_ptr<nd::pvp::PVPReq> pPvpReqResult(NEW_ND nd::pvp::PVPReq);
pPayload->set_type_name(pPvpReqResult->GetTypeName());
pPayload->add_socket(iSocket);
if (!CPvpDao::Instance().IsONLINE(pPvpReq->account()))
{
logger_error("target offline");
pPvpReqResult = pPvpReq;
pPvpReqResult->set_pvpmsg("target offline");
pPayload->set_message_data(pPvpReqResult->SerializeAsString());
CMsgMgr::Instance().InsertResponseMsg(pPayload);
return;
}
pPvpReq->set_socket(iSocket);
PVPReqMap[pPvpReq->id()] = pPvpReq;
if (PVPReqMap.size()== 1)
{
BM1 = CPvpDao::Instance().BattleMsg(pPvpReq->rolename());
}
logger_debug("Player info: {}", pPvpReq->DebugString());
logger_debug("Battle info: {}", BM1->DebugString());
if (PVPReqMap.size() > 1)
{
BM2 = CPvpDao::Instance().BattleMsg(pPvpReq->rolename());
std::shared_ptr<nd::SelfDescribingMessage> pNotifyPayload(NEW_ND nd::SelfDescribingMessage());
std::shared_ptr<nd::SelfDescribingMessage> pNotifyPayload2(NEW_ND nd::SelfDescribingMessage());
std::shared_ptr<nd::pvp::GameStart> pGameStart(NEW_ND nd::pvp::GameStart());
std::shared_ptr<nd::pvp::GameStart> pGameStart2(NEW_ND nd::pvp::GameStart());
pNotifyPayload->set_type_name(pGameStart->GetTypeName());
pNotifyPayload2->set_type_name(pGameStart2->GetTypeName());
for each (auto player in PVPReqMap)
{
if (player.first != pPvpReq->id())
{
pNotifyPayload->add_socket((player.second)->socket());
}
}
pNotifyPayload2->add_socket(iSocket);
pGameStart->set_rolename(BM1->rolename());
pGameStart->set_lv(BM1->lv());
pGameStart->set_atk(BM1->atk());
pGameStart->set_hp(BM1->hp());
pGameStart->set_mp(BM1->mp());
pGameStart->set_def(BM1->def());
pGameStart->set_gamemsg("pvp start");
pGameStart2->set_rolename(BM2->rolename());
pGameStart2->set_lv(BM2->lv());
pGameStart2->set_atk(BM2->atk());
pGameStart2->set_hp(BM2->hp());
pGameStart2->set_mp(BM2->mp());
pGameStart2->set_def(BM2->def());
pGameStart2->set_gamemsg("pvp start");
pNotifyPayload->set_message_data(pGameStart->SerializeAsString());
pNotifyPayload2->set_message_data(pGameStart2->SerializeAsString());
CMsgMgr::Instance().InsertResponseMsg(pNotifyPayload);
CMsgMgr::Instance().InsertResponseMsg(pNotifyPayload2);
A.SET(BM1);
B.SET(BM2);
}
}
void nd::CPvpMgr::GameAction(int iSocket,BA_PTR pBAMsg)
{
if (pBAMsg->rolename()==BM1->rolename())
{
B=A.Action(B,pBAMsg);
std::shared_ptr<nd::SelfDescribingMessage> pGameA(NEW_ND nd::SelfDescribingMessage());
std::shared_ptr<nd::SelfDescribingMessage> pGameB(NEW_ND nd::SelfDescribingMessage());
std::shared_ptr<nd::pvp::BattleMsg>pBattleMsg1(NEW_ND nd::pvp::BattleMsg());
std::shared_ptr<nd::pvp::BattleMsg>pBattleMsg2(NEW_ND nd::pvp::BattleMsg());
pGameA->set_type_name(pBattleMsg2->GetTypeName());
pGameB->set_type_name(pBattleMsg1->GetTypeName());
for each (auto player in PVPReqMap)
{
pGameB->add_socket((player.second)->socket());
}
pGameA->add_socket(iSocket);
pBattleMsg1->set_rolename(A.RoleName);
pBattleMsg1->set_hp(A.HP);
pBattleMsg1->set_atk(A.ATK);
pBattleMsg1->set_def(A.DEF);
pGameB->set_message_data(pBattleMsg1->SerializeAsString());
CMsgMgr::Instance().InsertResponseMsg(pGameB);
pBattleMsg2->set_rolename(B.RoleName);
pBattleMsg2->set_hp(B.HP);
pBattleMsg2->set_atk(B.ATK);
pBattleMsg2->set_def(B.DEF);
pGameA->set_message_data(pBattleMsg2->SerializeAsString());
CMsgMgr::Instance().InsertResponseMsg(pGameA);
}
if(pBAMsg->rolename() == BM2->rolename())
{
A=B.Action(A, pBAMsg);
std::shared_ptr<nd::SelfDescribingMessage> pGameA(NEW_ND nd::SelfDescribingMessage());
std::shared_ptr<nd::SelfDescribingMessage> pGameB(NEW_ND nd::SelfDescribingMessage());
std::shared_ptr<nd::pvp::BattleMsg>pBattleMsg1(NEW_ND nd::pvp::BattleMsg());
std::shared_ptr<nd::pvp::BattleMsg>pBattleMsg2(NEW_ND nd::pvp::BattleMsg());
pGameA->set_type_name(pBattleMsg2->GetTypeName());
pGameB->set_type_name(pBattleMsg1->GetTypeName());
for each (auto player in PVPReqMap)
{
pGameB->add_socket((player.second)->socket());
}
pGameA->add_socket(iSocket);
pBattleMsg1->set_rolename(A.RoleName);
pBattleMsg1->set_hp(A.HP);
pBattleMsg1->set_atk(A.ATK);
pBattleMsg1->set_def(A.DEF);
pGameB->set_message_data(pBattleMsg1->SerializeAsString());
CMsgMgr::Instance().InsertResponseMsg(pGameB);
pBattleMsg2->set_rolename(B.RoleName);
pBattleMsg2->set_hp(B.HP);
pBattleMsg2->set_atk(B.ATK);
pBattleMsg2->set_def(B.DEF);
pGameA->set_message_data(pBattleMsg2->SerializeAsString());
CMsgMgr::Instance().InsertResponseMsg(pGameA);
}
if (A.HP<0)
{
std::shared_ptr<nd::SelfDescribingMessage> pGameOverA(NEW_ND nd::SelfDescribingMessage());
std::shared_ptr<nd::SelfDescribingMessage> pGameOverB(NEW_ND nd::SelfDescribingMessage());
std::shared_ptr<nd::pvp::GameOver>pGameOverMsg(NEW_ND nd::pvp::GameOver());
pGameOverA->set_type_name(pGameOverMsg->GetTypeName());
pGameOverB->set_type_name(pGameOverMsg->GetTypeName());
for each (auto player in PVPReqMap)
{
pGameOverA->add_socket((player.second)->socket());
}
pGameOverA->add_socket(iSocket);
pGameOverMsg->set_winner(B.RoleName);
pGameOverMsg->set_exp((A.Lv * 10));
pGameOverA->set_message_data(pGameOverMsg->SerializeAsString());
pGameOverB->set_message_data(pGameOverMsg->SerializeAsString());
CMsgMgr::Instance().InsertResponseMsg(pGameOverA);
CMsgMgr::Instance().InsertResponseMsg(pGameOverB);
return;
}
else if (B.HP<0)
{
std::shared_ptr<nd::SelfDescribingMessage> pGameOverA(NEW_ND nd::SelfDescribingMessage());
std::shared_ptr<nd::SelfDescribingMessage> pGameOverB(NEW_ND nd::SelfDescribingMessage());
std::shared_ptr<nd::pvp::GameOver>pGameOverMsg(NEW_ND nd::pvp::GameOver());
pGameOverA->set_type_name(pGameOverMsg->GetTypeName());
pGameOverB->set_type_name(pGameOverMsg->GetTypeName());
for each (auto player in PVPReqMap)
{
pGameOverA->add_socket((player.second)->socket());
}
pGameOverA->add_socket(iSocket);
pGameOverMsg->set_winner(A.RoleName);
pGameOverMsg->set_exp((B.Lv * 10));
pGameOverA->set_message_data(pGameOverMsg->SerializeAsString());
pGameOverB->set_message_data(pGameOverMsg->SerializeAsString());
CMsgMgr::Instance().InsertResponseMsg(pGameOverA);
CMsgMgr::Instance().InsertResponseMsg(pGameOverB);
return;
}
return;
}
#pragma once
#include <string>
#include "msg/pvp.pb.h"
namespace nd
{
typedef std::shared_ptr<nd::pvp::PVPReq> PVPReq_PTR;
typedef std::shared_ptr<nd::pvp::PVPResp>PVPResp_PTR;
typedef std::shared_ptr<nd::pvp::GameStart>GS_PTR;
typedef std::shared_ptr<nd::pvp::BattleMsg>BM_PTR;
typedef std::shared_ptr<nd::pvp::BattleAction>BA_PTR;
typedef std::shared_ptr<nd::pvp::GameOver>OVER_PTR;
class CPvpDao
{
public:
static CPvpDao& Instance()
{
static CPvpDao instance;
return instance;
}
bool IsONLINE(const ::std::string& account);
BM_PTR BattleMsg(const ::std::string& RoleName);
private:
CPvpDao() {};
~CPvpDao() {};
CPvpDao(const CPvpDao&) {};
CPvpDao& operator=(const CPvpDao&) {};
};
}
#include "PvpDao.h"
#include "../../basic//GameLog.h"
#include "../../basic/basic.h"
#include "../../db/ConnectionPool.h"
#include "msg/pvp.pb.h"
#include<stdio.h>
//mysql driver
#include <mysql_connection.h>
//mysql execute
#include <cppconn/statement.h>
#include <cppconn/prepared_statement.h>
#include <cppconn/resultset.h>
#include <exception>
#include<string>
#include<iostream>
using namespace std;
bool nd::CPvpDao::IsONLINE(const::std::string & account)
{
sql::SQLString strSql("select status from t_player where account=?");
//获得一个连接
std::shared_ptr<Connection> pCon = CConnectionPool::Instance().GetConnect();
try
{
std::shared_ptr<PreparedStatement> pStmt(pCon->prepareStatement(strSql));
pStmt->setString(1, SQLString(account));
std::shared_ptr<ResultSet> pResult(pStmt->executeQuery());
CConnectionPool::Instance().ReturnConnect(pCon);
if (pResult->next()) {
//logger_debug("query result: account {} ", account);
return true;
}
}
catch (sql::SQLException& e)
{
CConnectionPool::Instance().HandleException(pCon, e);
}
return false;
}
nd::BM_PTR nd::CPvpDao::BattleMsg(const::std::string & RoleName)
{
sql::SQLString strSql("select * from t_role where RoleName=?");
BM_PTR BM(NEW_ND nd::pvp::BattleMsg());
//获得一个连接
std::shared_ptr<Connection> pCon = CConnectionPool::Instance().GetConnect();
try
{
std::shared_ptr<PreparedStatement> pStmt(pCon->prepareStatement(strSql));
pStmt->setString(1, SQLString(RoleName));
std::shared_ptr<ResultSet> pResult(pStmt->executeQuery());
CConnectionPool::Instance().ReturnConnect(pCon);
if (pResult->next()) {
//logger_debug("query result: RoleName {} ", pResult->getString("RoleName"));
BM->set_rolename(pResult->getString("RoleName"));
BM->set_lv(pResult->getInt("Lv"));
BM->set_atk(pResult->getInt("ATK"));
BM->set_hp(pResult->getInt("HP"));
BM->set_def(pResult->getInt("DEF"));
BM->set_mp(pResult->getInt("MP"));
}
}
catch (sql::SQLException& e)
{
CConnectionPool::Instance().HandleException(pCon, e);
}
return BM;
}