LiteLoaderBDS-1.16.40/LiteLoader/Kernel/FormPacketHelper.cpp
2022-09-21 19:47:03 +08:00

173 lines
6.1 KiB
C++

#include <Global.h>
#include <FormUI.h>
#include <LLAPI.h>
#include <I18nAPI.h>
#include <Impl/FormPacketHelper.h>
#include <Nlohmann/fifo_json.hpp>
#include <Utils/DbgHelper.h>
#include <Main/LiteLoader.h>
#include <MC/ServerNetworkHandler.hpp>
#include <MC/NetworkIdentifier.hpp>
#include <MC/Player.hpp>
#include <MC/ServerPlayer.hpp>
using namespace std;
//////////////////////////////// Data ////////////////////////////////
enum class FormType {
SimpleFormBuilder,
ModalFormBuilder,
CustomFormBuilder,
SimpleFormPacket,
ModalFormPacket,
CustomFormPacket
};
unordered_map<unsigned, FormType> formTypes;
unordered_map<unsigned, std::function<void(Player*, int)>> simpleFormPacketCallbacks;
unordered_map<unsigned, std::function<void(Player*, bool)>> modalFormPacketCallbacks;
unordered_map<unsigned, std::function<void(Player*, string)>> customFormPacketCallbacks;
unordered_map<unsigned, std::shared_ptr<Form::SimpleForm>> simpleFormBuilders;
unordered_map<unsigned, std::shared_ptr<Form::ModalForm>> modalFormBuilders;
unordered_map<unsigned, std::shared_ptr<Form::CustomForm>> customFormBuilders;
//////////////////////////////// Functions ////////////////////////////////
#define RAND_FORM_ID() (unsigned)((rand() << 16) + rand())
unsigned NewFormId() {
unsigned formId;
do {
formId = RAND_FORM_ID();
} while (formTypes.find(formId) != formTypes.end());
return formId;
}
void SetSimpleFormPacketCallback(unsigned formId, std::function<void(Player*, int)> callback) {
formTypes[formId] = FormType::SimpleFormPacket;
simpleFormPacketCallbacks[formId] = callback;
}
void SetModalFormPacketCallback(unsigned formId, std::function<void(Player*, bool)> callback) {
formTypes[formId] = FormType::ModalFormPacket;
modalFormPacketCallbacks[formId] = callback;
}
void SetCustomFormPacketCallback(unsigned formId, std::function<void(Player*, string)> callback) {
formTypes[formId] = FormType::CustomFormPacket;
customFormPacketCallbacks[formId] = callback;
}
void SetSimpleFormBuilderData(unsigned formId, std::shared_ptr<Form::SimpleForm> data) {
formTypes[formId] = FormType::SimpleFormBuilder;
simpleFormBuilders[formId] = data;
}
void SetModalFormBuilderData(unsigned formId, std::shared_ptr<Form::ModalForm> data) {
formTypes[formId] = FormType::ModalFormBuilder;
modalFormBuilders[formId] = data;
}
void SetCustomFormBuilderData(unsigned formId, std::shared_ptr<Form::CustomForm> data) {
formTypes[formId] = FormType::CustomFormBuilder;
customFormBuilders[formId] = data;
}
void HandleFormPacket(Player* player, unsigned formId, const string& data) {
if (formTypes.find(formId) == formTypes.end())
return;
if (formTypes[formId] == FormType::SimpleFormBuilder) {
int chosen = data != "null" ? stoi(data) : -1;
// Simple Form Builder
auto form = simpleFormBuilders[formId];
if (form->callback)
form->callback(player, chosen);
// Button Callback
if (chosen >= 0) {
auto button = dynamic_pointer_cast<Form::Button>(form->elements[chosen]);
if (button->callback)
button->callback(player);
}
simpleFormBuilders.erase(formId);
} else if (formTypes[formId] == FormType::ModalFormBuilder) {
int chosen = data == "true" ? 1 : 0;
// Modal Form Builder
auto form = modalFormBuilders[formId];
if (form->callback)
form->callback(player, chosen);
modalFormBuilders.erase(formId);
} else if (formTypes[formId] == FormType::CustomFormBuilder) {
// Custom Form Builder
auto form = customFormBuilders[formId];
if (data == "null") {
customFormBuilders.erase(formId);
if (form->callback)
form->callback(player, {});
return;
}
fifo_json res = fifo_json::parse(data);
int nowIndex = 0;
for (fifo_json& j : res) {
switch (form->getType(nowIndex)) {
case Form::CustomFormElement::Type::Label: // label's data is null
break;
case Form::CustomFormElement::Type::Input:
form->setValue(nowIndex, j.get<string>());
break;
case Form::CustomFormElement::Type::Toggle:
form->setValue(nowIndex, j.get<bool>());
break;
case Form::CustomFormElement::Type::Slider:
form->setValue(nowIndex, j.get<double>());
break;
case Form::CustomFormElement::Type::Dropdown: {
auto& options = dynamic_pointer_cast<Form::Dropdown>(form->elements[nowIndex].second)->options;
form->setValue(nowIndex, options[j.get<int>()]);
break;
}
case Form::CustomFormElement::Type::StepSlider: {
auto& options = dynamic_pointer_cast<Form::StepSlider>(form->elements[nowIndex].second)->options;
form->setValue(nowIndex, options[j.get<int>()]);
break;
}
default:
break;
}
++nowIndex;
}
if (form->callback) {
std::map<string, std::shared_ptr<Form::CustomFormElement>> callbackData;
for (auto& [k, v] : form->elements)
callbackData[k] = v;
form->callback(player, callbackData);
}
customFormBuilders.erase(formId);
} else if (formTypes[formId] == FormType::SimpleFormPacket) {
int chosen = data != "null" ? stoi(data) : -1;
simpleFormPacketCallbacks[formId](player, chosen);
simpleFormPacketCallbacks.erase(formId);
} else if (formTypes[formId] == FormType::CustomFormPacket) {
customFormPacketCallbacks[formId](player, data);
customFormPacketCallbacks.erase(formId);
} else if (formTypes[formId] == FormType::ModalFormPacket) {
int chosen = data == "true" ? 1 : 0;
modalFormPacketCallbacks[formId](player, chosen);
modalFormPacketCallbacks.erase(formId);
}
formTypes.erase(formId);
}