Skip to content

Commit

Permalink
fix: try fix Tpa
Browse files Browse the repository at this point in the history
  • Loading branch information
engsr6982 committed Oct 8, 2024
1 parent ccbc483 commit e666666
Show file tree
Hide file tree
Showing 13 changed files with 167 additions and 278 deletions.
61 changes: 27 additions & 34 deletions src/command/CommandTpa.cc
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ void registerCommandWithTpa(const string& _commandName) {

} else if (senders.size() == 1) { // 只有一个请求
auto req = pool->getRequest(receiver.getRealName(), senders[0]);
param.option == TpOption::accept ? req->accept() : req->deny();
param.option == TpOption::accept ? req->_accept() : req->_deny();
return;

} else {
Expand All @@ -68,7 +68,7 @@ void registerCommandWithTpa(const string& _commandName) {
fm.appendButton(sender, [sender, pool, param](Player& receiver2) {
auto req = pool->getRequest(receiver2.getRealName(), sender);
if (req->getAvailable() == tpa::Available::Available) {
param.option == TpOption::accept ? req->accept() : req->deny();
param.option == TpOption::accept ? req->_accept() : req->_deny();
}
});
}
Expand All @@ -78,44 +78,37 @@ void registerCommandWithTpa(const string& _commandName) {
);

// tps tpa <here|to> <Player>
cmd.overload<ParamTp>().text("tpa").required("type").required("target").execute([](CommandOrigin const& origin,
CommandOutput& output,
const ParamTp& param) {
CHECK_COMMAND_TYPE(output, origin, CommandOriginType::Player);
auto& sender = *static_cast<Player*>(origin.getEntity());
if (!Config::checkOpeningDimensions(Config::cfg.Tpa.OpenDimensions, sender.getDimensionId())) {
sendText<MsgLevel::Error>(output, "当前维度不允许使用此功能!"_tr());
return;
}
cmd.overload<ParamTp>().text("tpa").required("type").required("target").execute(
[](CommandOrigin const& origin, CommandOutput& output, const ParamTp& param) {
CHECK_COMMAND_TYPE(output, origin, CommandOriginType::Player);
auto& sender = *static_cast<Player*>(origin.getEntity());
if (!Config::checkOpeningDimensions(Config::cfg.Tpa.OpenDimensions, sender.getDimensionId())) {
sendText<MsgLevel::Error>(output, "当前维度不允许使用此功能!"_tr());
return;
}


auto li = param.target.results(origin);
if (li.empty()) {
sendText<MsgLevel::Error>(output, "请至少选择一位玩家!"_tr());
return;
} else if (li.size() > 1) {
sendText<MsgLevel::Error>(output, "仅支持对一位玩家发起TPA!"_tr());
return;
}
auto li = param.target.results(origin);
if (li.empty()) {
sendText<MsgLevel::Error>(output, "请至少选择一位玩家!"_tr());
return;
} else if (li.size() > 1) {
sendText<MsgLevel::Error>(output, "仅支持对一位玩家发起TPA!"_tr());
return;
}

auto request =
std::make_shared<tpa::TpaRequest>(sender, *(*li.data)[0], param.type, Config::cfg.Tpa.CacheExpirationTime);
auto request = tpa::TpaRequestPool::getInstance().makeRequest(sender, *(*li.data)[0], param.type);

tpa::Available avail = request->ask(); // 发送请求
tpa::Available avail = request->sendAskForm(); // 发送请求

if (avail != tpa::Available::Available) {
sendText<MsgLevel::Error>(sender, "{}"_tr(tpa::TpaRequest::getAvailableDescription(avail)));
}
if (avail != tpa::Available::Available) {
sendText<MsgLevel::Error>(sender, "{}"_tr(tpa::TpaRequest::getAvailableDescription(avail)));
}

// Tpa 请求发送事件
ll::event::EventBus::getInstance().publish(event::TpaRequestSendEvent(
request->sender,
request->receiver,
*request->time,
request->type,
request->lifespan
));
});
// Tpa 请求发送事件
ll::event::EventBus::getInstance().publish(event::TpaRequestSendEvent(request));
}
);
}

} // namespace tps::command
16 changes: 12 additions & 4 deletions src/event/EventManager.cc
Original file line number Diff line number Diff line change
Expand Up @@ -49,20 +49,28 @@ void registerEvent() {
// 发送tpa请求事件
if (Config::cfg.Tpa.Enable) {
mTpaRequestSendListener = eventBus.emplaceListener<TpaRequestSendEvent>([](TpaRequestSendEvent& ev) {
auto sender = ll::service::getLevel()->getPlayer(ev.getSender()); // 获取发送者
auto receiver = ll::service::getLevel()->getPlayer(ev.getReciever()); // 获取接收者
auto req = ev.getRequest();

auto sender = ll::service::getLevel()->getPlayer(req->getSender()); // 获取发送者
auto receiver = ll::service::getLevel()->getPlayer(req->getReceiver()); // 获取接收者

if (sender) {
utils::mc::sendText(
sender,
"已向 {} 发起 {} 请求."_tr(receiver->getRealName(), tpa::TpaRequest::tpaTypeToString(ev.getType()))
"已向 {} 发起 {} 请求."_tr(
receiver->getRealName(),
tpa::TpaRequest::tpaTypeToString(req->getType())
)
);
}

if (receiver) {
utils::mc::sendText(
receiver,
"收到来自 {} 的 {} 请求."_tr(sender->getRealName(), tpa::TpaRequest::tpaTypeToString(ev.getType()))
"收到来自 {} 的 {} 请求."_tr(
sender->getRealName(),
tpa::TpaRequest::tpaTypeToString(req->getType())
)
);
}
});
Expand Down
8 changes: 1 addition & 7 deletions src/event/TpaRequestSendEvent.cc
Original file line number Diff line number Diff line change
@@ -1,14 +1,8 @@
#include "TpaRequestSendEvent.h"
#include "utils/Date.h"


namespace tps::event {

string const& TpaRequestSendEvent::getSender() { return mSender; }
string const& TpaRequestSendEvent::getReciever() { return mReciever; }
tpa::TpaType TpaRequestSendEvent::getType() { return mType; }
int TpaRequestSendEvent::getLifeSpan() { return mLifeSpan; }
utils::Date const& TpaRequestSendEvent::getTime() { return mTime; }

tpa::TpaRequest* TpaRequestSendEvent::getRequest() const { return mRequest; }

} // namespace tps::event
31 changes: 3 additions & 28 deletions src/event/TpaRequestSendEvent.h
Original file line number Diff line number Diff line change
@@ -1,41 +1,16 @@
#include "ll/api/event/Event.h"
#include "tpa/core/TpaRequest.h"
#include "utils/Date.h"
#include <string>


using string = std::string;

namespace tps::event {


class TpaRequestSendEvent final : public ll::event::Event {
private:
string const& mSender;
string const& mReciever;
utils::Date const& mTime;
tpa::TpaType mType;
int mLifeSpan;
tpa::TpaRequest* mRequest;

public:
constexpr explicit TpaRequestSendEvent(
string const& sender,
string const& reciever,
utils::Date const& time,
tpa::TpaType type,
int lifespan
)
: mSender(sender),
mReciever(reciever),
mTime(time),
mType(type),
mLifeSpan(lifespan) {}
constexpr explicit TpaRequestSendEvent(tpa::TpaRequest* req) : mRequest(req) {}

string const& getSender();
string const& getReciever();
utils::Date const& getTime();
tpa::TpaType getType();
int getLifeSpan();
tpa::TpaRequest* getRequest() const;
};


Expand Down
126 changes: 70 additions & 56 deletions src/tpa/core/TpaRequest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -8,46 +8,57 @@
#include "mc/world/level/Level.h"
#include "modules/Moneys.h"
#include "rule/RuleManager.h"
#include "tpa/gui/TpaAskForm.h"
#include "utils/Date.h"
#include "utils/Mc.h"
#include <cstdint>
#include <memory>
#include <stdexcept>
#include <unordered_map>


namespace tps::tpa {


using ll::i18n_literals::operator""_tr;
TpaRequest::TpaRequest(Player& sender, Player& receiver, TpaType type) {
this->mSender = sender.getRealName();
this->mReceiver = receiver.getRealName();
this->mType = type;
this->mTime = Date();
this->mLifespan = Config::cfg.Tpa.CacheExpirationTime;


// 构造表单
string tpaDescription;
if (mType == TpaType::Tpa) {
tpaDescription = "{0} 希望传送到您这里"_tr(mSender);
} else if (mType == TpaType::TpaHere) {
tpaDescription = "{0} 希望将您传送至他那里"_tr(mSender);
} else {
tpaDescription = "未知请求类型"_tr();
}

std::unordered_map<uint64_t, std::unique_ptr<TpaAskForm>> mAskList;
static uint64_t NextRequestId = 0;
mAskForm.setTitle("TPA Request"_tr());
mAskForm.setContent(tpaDescription);

TpaRequest::TpaRequest(Player& sender, Player& receiver, TpaType type, int lifespan) : mRequestId(NextRequestId++) {
this->sender = sender.getRealName();
this->receiver = receiver.getRealName();
this->type = type;
this->time = std::make_unique<Date>();
this->lifespan = lifespan;
}
TpaRequest::~TpaRequest() {
auto iter = mAskList.find(this->mRequestId);
if (iter != mAskList.end()) {
mAskList.erase(iter);
}
mAskForm.appendButton("接受"_tr(), "textures/ui/realms_green_check", "path", [this](Player&) { this->_accept(); });

mAskForm.appendButton("拒绝"_tr(), "textures/ui/realms_red_x", "path", [this](Player&) { this->_deny(); });

mAskForm.appendButton("暂时忽略\n(有效期至: {0})"_tr(mTime.toString()), "textures/ui/backup_replace", "path");
}

string const& TpaRequest::getSender() const { return mSender; }
string const& TpaRequest::getReceiver() const { return mReceiver; }
TpaType TpaRequest::getType() const { return mType; }
Date const& TpaRequest::getTime() const { return mTime; }
int TpaRequest::getLifespan() const { return mLifespan; }

void TpaRequest::destoryThisRequestFromPool() {
void TpaRequest::destroy() const {
auto& pool = TpaRequestPool::getInstance();
if (pool.hasRequest(receiver, sender)) {
pool.deleteRequest(receiver, sender);
if (pool.hasRequest(mReceiver, mSender)) {
pool.deleteRequest(mReceiver, mSender);
}
}

bool TpaRequest::isOutdated() {
if (Date{}.getTime() - this->time->getTime() >= this->lifespan) {
bool TpaRequest::isAvailable() const { return getAvailable() == Available::Available; }
bool TpaRequest::isOutdated() const {
if (Date{}.getTime() - this->mTime.getTime() >= this->mLifespan) {
return true;
}
return false;
Expand All @@ -56,92 +67,95 @@ bool TpaRequest::isOutdated() {

using namespace ll::service;
using namespace tps::utils::mc;
void TpaRequest::accept() {
void TpaRequest::_accept() const {
Available avail = getAvailable();
if (avail != Available::Available) {
if (avail != Available::SenderOffline) {
sendText<MsgLevel::Error>(sender, "{}", getAvailableDescription(avail));
sendText<MsgLevel::Error>(mSender, "{}", getAvailableDescription(avail));
}
return;
}

auto level = ll::service::getLevel();
auto receiverPlayer = level->getPlayer(this->receiver);
auto senderPlayer = level->getPlayer(this->sender);
auto receiverPlayer = level->getPlayer(this->mReceiver);
auto senderPlayer = level->getPlayer(this->mSender);
if (!receiverPlayer || !senderPlayer) {
destoryThisRequestFromPool(); // 销毁请求
destroy(); // 销毁请求
return;
}

if (type == TpaType::Tpa) {
if (mType == TpaType::Tpa) {
senderPlayer
->teleport(receiverPlayer->getPosition(), receiverPlayer->getDimensionId(), senderPlayer->getRotation());
} else if (type == TpaType::TpaHere) {
} else if (mType == TpaType::TpaHere) {
receiverPlayer
->teleport(senderPlayer->getPosition(), senderPlayer->getDimensionId(), receiverPlayer->getRotation());
}

// 扣除经济
tps::modules::Moneys::getInstance().reduceMoney(senderPlayer, Config::cfg.Tpa.Money);

sendText<MsgLevel::Success>(senderPlayer, "'{0}' 接受了您的 '{1}' 请求。"_tr(receiver, tpaTypeToString(type)));
sendText<MsgLevel::Success>(receiverPlayer, "您接受了来自 '{0}' 的 '{1}' 请求。"_tr(sender, tpaTypeToString(type)));
sendText<MsgLevel::Success>(senderPlayer, "'{0}' 接受了您的 '{1}' 请求。"_tr(mReceiver, tpaTypeToString(mType)));
sendText<MsgLevel::Success>(
receiverPlayer,
"您接受了来自 '{0}' 的 '{1}' 请求。"_tr(mSender, tpaTypeToString(mType))
);

destoryThisRequestFromPool(); // 销毁请求
destroy(); // 销毁请求
}

void TpaRequest::deny() {
sendText<MsgLevel::Error>(sender, "'{0}' 拒绝了您的 '{1}' 请求。"_tr(receiver, tpaTypeToString(type)));
sendText<MsgLevel::Error>(receiver, "您拒绝了来自 '{0}' 的 '{1}' 请求。"_tr(sender, tpaTypeToString(type)));
void TpaRequest::_deny() const {
sendText<MsgLevel::Error>(mSender, "'{0}' 拒绝了您的 '{1}' 请求。"_tr(mReceiver, tpaTypeToString(mType)));
sendText<MsgLevel::Error>(mReceiver, "您拒绝了来自 '{0}' 的 '{1}' 请求。"_tr(mSender, tpaTypeToString(mType)));

destoryThisRequestFromPool(); // 销毁请求
destroy(); // 销毁请求
}


Available TpaRequest::ask() {
Available TpaRequest::sendAskForm() {
Available avail = getAvailable();
if (avail != Available::Available) {
if (avail != Available::SenderOffline) {
sendText<MsgLevel::Error>(sender, "{}", getAvailableDescription(avail));
sendText<MsgLevel::Error>(mSender, "{}", getAvailableDescription(avail));
}
return avail;
}

// 创建询问表单
auto ptr = std::make_unique<TpaAskForm>(TpaRequestPtr(shared_from_this()));
// 移交表单所有权
mAskList[this->mRequestId] = std::move(ptr);

// 检查玩家是否接受弹窗, 接受则发送弹窗,否则缓存到请求池
if (rule::RuleManager::getInstance().getPlayerRule(receiver).tpaPopup) {
ptr->sendTo(*ll::service::getLevel()->getPlayer(receiver)); // 发送弹窗给接收者
} else {
ptr->cacheRequest(); // 缓存到请求池
// 检查玩家是否接受弹窗, 接受则发送弹窗,否则
if (rule::RuleManager::getInstance().getPlayerRule(mReceiver).tpaPopup) {
mAskForm.sendTo(*ll::service::getLevel()->getPlayer(mReceiver), [](Player&, int, ll::form::FormCancelReason) {
});
}

return avail;
}


Available TpaRequest::getAvailable() {
Available TpaRequest::getAvailable() const {
if (isOutdated()) {
return Available::Expired;
}
if (getLevel()->getPlayer(sender) == nullptr) {
if (getLevel()->getPlayer(mSender) == nullptr) {
return Available::SenderOffline;
}
if (getLevel()->getPlayer(receiver) == nullptr) {
if (getLevel()->getPlayer(mReceiver) == nullptr) {
return Available::RecieverOffline;
}
if (modules::Moneys::getInstance().getMoney(sender) < Config::cfg.Tpa.Money && Config::cfg.Tpa.Money != 0) {
if (modules::Moneys::getInstance().getMoney(mSender) < Config::cfg.Tpa.Money && Config::cfg.Tpa.Money != 0) {
return Available::Unaffordable;
}
// 检查对方是否禁止发送tpa请求
if (!rule::RuleManager::getInstance().getPlayerRule(receiver).allowTpa) {
if (!rule::RuleManager::getInstance().getPlayerRule(mReceiver).allowTpa) {
return Available::ProhibitTpaRequest;
}
return Available::Available;
}

// TpaRequest::operator bool() const { return isAvailable(); }
bool TpaRequest::operator!=(const TpaRequest& other) const { return !(*this == other); }
bool TpaRequest::operator==(const TpaRequest& other) const {
return mSender == other.mSender && mReceiver == other.mReceiver && mType == other.mType;
}

// static
string TpaRequest::getAvailableDescription(Available avail) {
Expand Down
Loading

0 comments on commit e666666

Please sign in to comment.