Skip to content

Commit

Permalink
feat(PC): CardTemp js script
Browse files Browse the repository at this point in the history
角色卡模板支持全局js脚本
修复.game master无法正确添加gm的bug
  • Loading branch information
mystringEmpty committed Feb 5, 2024
1 parent a80dfc2 commit 17c88b4
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 39 deletions.
45 changes: 37 additions & 8 deletions Dice/CharacterCard.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
*/
#include "CharacterCard.h"
#include "DDAPI.h"
#include "quickjs.h"
#include "DiceJS.h"
#include "DiceMod.h"

Expand All @@ -29,9 +30,13 @@ AttrShape::AttrShape(const tinyxml2::XMLElement* node, bool isUTF8) {
defVal = AttrVar::parse(s);
}
}
AttrVar AttrShape::init(CharaCard* pc) {
AttrVar AttrShape::init(ptr<CardTemp> temp, CharaCard* pc) {
if (textType == TextType::JavaScript) {
return js_context_eval(defVal, pc->shared_from_this());
if (auto ret = temp->js_ctx->evalStringLocal(defVal, temp->type, pc->shared_from_this());
!JS_IsException(ret)) {
return temp->js_ctx->getValue(ret);
}
else console.log("生成<" + temp->type + ">属性时执行js失败!\n" + temp->js_ctx->getException(), 0b10);
}
else if (textType == TextType::Dicexp && !defVal.is_null()) {
if (auto exp{ fmt->format(defVal, pc->shared_from_this()) }; exp.is_text()) {
Expand Down Expand Up @@ -149,6 +154,9 @@ int loadCardTemp(const std::filesystem::path& fpPath, dict_ci<CardTemp>& m) {
if (auto opt{ kid->Attribute("name") })tp.presets[Text2GBK(opt)] = CardPreset(kid, isUTF8);
}
}
else if (tag == "script") {
tp.script = Text2GBK(elem->GetText());
}
}
return 1;
}
Expand All @@ -164,11 +172,21 @@ int loadCardTemp(const std::filesystem::path& fpPath, dict_ci<CardTemp>& m) {
CardTemp& CardTemp::merge(const CardTemp& other) {
if (type.empty())type = other.type;
map_merge(AttrShapes, other.AttrShapes);
if (!other.script.empty())script += "\n" + other.script;
for (auto& [opt, preset] : other.presets) {
map_merge(presets[opt].shapes, preset.shapes);
}
return *this;
}
void CardTemp::init() {
js_ctx = std::make_shared<js_context>();
if (!script.empty()) {
if (auto ret{ js_ctx->evalString(script, "model.init") };
JS_IsException(ret)) {
console.log("初始化<" + type + ">js脚本失败!\n" + js_ctx->getException(), 0b10);
}
}
}
string CardTemp::show() {
ResList res;
if (!AttrShapes.empty()) {
Expand Down Expand Up @@ -203,7 +221,7 @@ void CharaCard::setType(const string& strType) {
AttrVar CharaCard::get(const string& key, const AttrVar& val)const{
if (dict.count(key))return dict.at(key);
if (auto temp{ getTemplet() }; temp->canGet(key)) {
return temp->AttrShapes.at(key).init(const_cast<CharaCard*>(this));
return temp->AttrShapes.at(key).init(temp, const_cast<CharaCard*>(this));
}
return {};
}
Expand All @@ -226,7 +244,7 @@ int CharaCard::set(string key, const AttrVar& val) {
string CharaCard::print(const string& key){
if (dict.count(key))return dict.at(key).print();
if (auto temp{ getTemplet() }; temp->canGet(key)) {
return temp->AttrShapes.at(key).init(this).print();
return temp->AttrShapes.at(key).init(temp, this).print();
}
return {};
}
Expand All @@ -252,8 +270,8 @@ string CharaCard::getExp(string& key, std::unordered_set<string> sRef){
auto val = dict.find("&" + key);
if (val != dict.end())return escape(val->second.to_str(), sRef);
else if ((val = dict.find(key)) != dict.end())return escape(val->second.to_str(), sRef);
else if (auto exp = temp->AttrShapes.find("&" + key); exp != temp->AttrShapes.end())return escape(exp->second.init(this).to_str(), sRef);
else if (auto exp = temp->AttrShapes.find(key); exp != temp->AttrShapes.end())return escape(exp->second.init(this).to_str(), sRef);
else if (auto exp = temp->AttrShapes.find("&" + key); exp != temp->AttrShapes.end())return escape(exp->second.init(temp, this).to_str(), sRef);
else if (auto exp = temp->AttrShapes.find(key); exp != temp->AttrShapes.end())return escape(exp->second.init(temp, this).to_str(), sRef);
return "0";
}
bool CharaCard::countExp(const string& key)const {
Expand All @@ -280,6 +298,17 @@ std::optional<int> CharaCard::cal(string exp){
return std::nullopt;
}

void CharaCard::build(const string& para)
{
auto tmp{ getTemplet() };
if (const auto it = tmp->presets.find(para);
it != tmp->presets.end()) {
auto& preset = it->second;
for (auto& [attr, shape] : preset.shapes) {
if (!dict.count(attr) || dict.at(attr).is_null())set(attr, shape.init(tmp, this));
}
}
}
void CharaCard::buildv(string para)
{
std::stack<string> vOption;
Expand Down Expand Up @@ -554,12 +583,12 @@ int Player::newCard(string& s, long long group, string type)
vOption.pop();
card->build(para);
if (card->getName().empty() && temp->presets.count(para) && temp->presets[para].shapes.count("__Name")) {
if (!mNameIndex.count(s = temp->presets[para].shapes["__Name"].init(card.get())))card->setName(s);
if (!mNameIndex.count(s = temp->presets[para].shapes["__Name"].init(temp, card.get())))card->setName(s);
}
}
if (card->getName().empty()){
if (temp->presets.count("pc") && temp->presets["pc"].shapes.count("__Name")) {
if (!mNameIndex.count(s = temp->presets["pc"].shapes["__Name"].init(card.get())))card->setName(s);
if (!mNameIndex.count(s = temp->presets["pc"].shapes["__Name"].init(temp, card.get())))card->setName(s);
}
if (card->getName().empty())card->setName(to_string(indexMax + 1));
}
Expand Down
32 changes: 13 additions & 19 deletions Dice/CharacterCard.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,9 @@
* program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <fstream>
#include <utility>
#include <vector>
#include <stack>
#include <mutex>
#include <mutex>
#include "CQTools.h"
#include "RDConstant.h"
#include "RD.h"
Expand All @@ -38,14 +35,15 @@
#include "MsgFormat.h"
#include "CardDeck.h"
#include "DiceEvent.h"
#include "DiceAttrVar.h"
#include "DiceJS.h"

using std::string;
using std::to_string;
using std::vector;
using std::map;
using xml = tinyxml2::XMLDocument;
class CharaCard;
class CardTemp;

inline unordered_map<string, short> mCardTag = {
{"Name", 1},
Expand All @@ -69,11 +67,11 @@ class AttrShape {
AttrShape(const string& s):defVal(s){}
AttrShape(const string& s, TextType tt) :defVal(s), textType(tt){}
DataType type{ DataType::Any };
string title;
//string title;
vector<string> alias;
TextType textType{ TextType::Plain };
AttrVar defVal;
AttrVar init(CharaCard*);
AttrVar init(ptr<CardTemp>, CharaCard*);
int check(AttrVar& val);
bool equalDefault(const AttrVar& val)const { return TextType::Plain == textType && val == defVal; }
};
Expand All @@ -99,17 +97,21 @@ class CardTemp
//作成时生成
vector<vector<string>> vBasicList = {};
//元表
fifo_dict_ci<AttrShape> AttrShapes;
dict_ci<AttrShape> AttrShapes;
//生成参数
dict_ci<CardPreset> presets = {};
//
string script;
ptr<js_context> js_ctx;
CardTemp() = default;

CardTemp(const string& type, const dict_ci<>& replace, vector<vector<string>> basic,
const dict_ci<>& dynamic, const dict_ci<>& exps,
const dict_ci<int>& def_skill, const dict_ci<CardPreset>& option = {}) : type(type),
const dict_ci<int>& def_skill, const dict_ci<CardPreset>& option = {},
const string& s = {}) : type(type),
replaceName(replace),
vBasicList(basic),
presets(option)
presets(option),script(s)
{
for (auto& [attr, exp] : dynamic) {
AttrShapes[attr] = AttrShape(exp, AttrShape::TextType::Dicexp);
Expand All @@ -122,6 +124,7 @@ class CardTemp
}
}
CardTemp& merge(const CardTemp& other);
void init();
bool equalDefault(const string& attr, const AttrVar& val)const { return AttrShapes.count(attr) && AttrShapes.at(attr).equalDefault(val); }

//CardTemp(const xml* d) { }
Expand Down Expand Up @@ -220,16 +223,7 @@ class CharaCard: public AnysTable
//计算表达式
std::optional<int> cal(string exp);

void build(const string& para)
{
if (const auto it = getTemplet()->presets.find(para);
it != getTemplet()->presets.end()) {
auto& preset = it->second;
for (auto& [attr, shape] : preset.shapes) {
if (!dict.count(attr) || dict.at(attr).is_null())set(attr, shape.init(this));
}
}
}
void build(const string& para);

//解析生成参数
void buildv(string para = "");
Expand Down
19 changes: 9 additions & 10 deletions Dice/Dice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,15 @@ EVE_Enable(eventEnable){
参考文档参看.help链接)";
DD::debugMsg(msgInit);
}
DD::debugLog("DiceConsole.load");
try {
js_global_init();
#ifdef DICE_PYTHON
if (console["EnablePython"])py = make_unique<PyGlobal>();
#endif //DICE_PYTHON
}
catch (const std::exception& e) {
console.log(string("初始化js/python环境失败!") + e.what(), 1, printSTNow());
}
fmt = make_unique<DiceModManager>();
try {
std::unique_lock lock(GlobalMsgMutex);
Expand All @@ -294,15 +302,6 @@ EVE_Enable(eventEnable){
catch (const std::exception& e) {
console.log(string("读取/conf/CustomMsg.json失败!") + e.what(), 1, printSTNow());
}
try {
js_global_init();
#ifdef DICE_PYTHON
if (console["EnablePython"])py = make_unique<PyGlobal>();
#endif //DICE_PYTHON
}
catch (const std::exception& e) {
console.log(string("初始化js/python环境失败!") + e.what(), 1, printSTNow());
}
loadData();
//初始化黑名单
blacklist = make_unique<DDBlackManager>();
Expand Down
4 changes: 2 additions & 2 deletions Dice/DiceEvent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1661,9 +1661,9 @@ int DiceEvent::BasicOrder()
}
else if (action == "master") {
auto gms{ game->get_gm() };
if (game->is_gm(fromChat.uid)) {
if (!gms->count(fromChat.uid)) {
if (gms->empty() ? canRoomHost() : DD::isGroupAdmin(fromChat.gid, fromChat.uid, false)) {
auto game{ thisGame() }; game->add_gm(fromChat.uid);
game->add_gm(fromChat.uid);
replyMsg("strGameMastered");
}
else {
Expand Down
3 changes: 3 additions & 0 deletions Dice/DiceMod.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1274,6 +1274,9 @@ void DiceModManager::build() {
if (rules_new->build())resLog << "注册规则集 " + to_string(rules_new->rules.size()) + "";
ruleset.swap(rules_new);
if (cntModel)resLog << "注册角色卡模板 " + to_string(rules_new->rules.size()) + "";
for (auto& [name, model] : models) {
model->init();
}
if (cntModel || CardModels.size() > 2)CardModels.swap(models);
if (cntSpeech += map_merge(global_speech, EditedMsg))
resLog << "注册speech " + to_string(cntSpeech) + "";
Expand Down

0 comments on commit 17c88b4

Please sign in to comment.