diff --git a/Dice/BlackListManager.cpp b/Dice/BlackListManager.cpp index 631e0448..7008809e 100644 --- a/Dice/BlackListManager.cpp +++ b/Dice/BlackListManager.cpp @@ -1,7 +1,7 @@ /** * 黑名单明细 * 更数据库式的管理 - * Copyright (C) 2019-2023 String.Empty + * Copyright (C) 2019-2024 String.Empty */ #include #include @@ -23,7 +23,7 @@ using Manager = DDBlackManager; using Factory = DDBlackMarkFactory; //判断信任 -int isReliable(long long uid) +static int isReliable(long long uid) { if (!uid)return 0; if (uid == console)return 255; @@ -46,14 +46,14 @@ void checkGroupWithBlackQQ(const DDBlackMark& mark, long long llQQ) for (auto& [id, grp] : ChatList) { int authSelf; - if (!grp.getLst() || grp.isset("忽略") || !grp.isGroup + if (!grp->getLst() || grp->is("忽略") || !(authSelf = DD::getGroupAuth(id, console.DiceMaid, 0)))continue; - if (DD::isGroupMember(grp.ID, llQQ, false)) { + if (DD::isGroupMember(grp->ID, llQQ, false)) { strNotice = printGroup(id); - if (grp.isset("协议无效")) { + if (grp->is("协议无效")) { strNotice += "群协议无效"; } - else if (grp.isset("免黑")) { + else if (grp->is("免黑")) { if (mark.isSource(console.DiceMaid) && !mark.isType("local"))DD::sendGroupMsg(id, mark.warning()); strNotice += "群免黑"; } @@ -68,11 +68,11 @@ void checkGroupWithBlackQQ(const DDBlackMark& mark, long long llQQ) else if (authSelf > authBlack) { DD::sendGroupMsg(id, mark.warning()); - grp.leave("发现新增黑名单管理员" + printUser(llQQ) + "\n" + getMsg("strSelfName") + "将预防性退群"); + grp->leave("发现新增黑名单管理员" + printUser(llQQ) + "\n" + getMsg("strSelfName") + "将预防性退群"); strNotice += "对方群权限较高,已退群"; this_thread::sleep_for(1s); } - else if (grp.isset("免清")) + else if (grp->is("免清")) { if (mark.isSource(console.DiceMaid) && !mark.isType("local"))AddMsgToQueue( mark.warning(), { 0, id }); @@ -81,7 +81,7 @@ void checkGroupWithBlackQQ(const DDBlackMark& mark, long long llQQ) else if (console["LeaveBlackQQ"]) { DD::sendGroupMsg(id, mark.warning()); - grp.leave("发现新增黑名单成员" + printUser(llQQ) + "(同等群权限)\n" + getMsg("strSelfName") + "将预防性退群"); + grp->leave("发现新增黑名单成员" + printUser(llQQ) + "(同等群权限)\n" + getMsg("strSelfName") + "将预防性退群"); strNotice += "已退群"; this_thread::sleep_for(1s); } @@ -846,7 +846,7 @@ void DDBlackManager::reset_qq_danger(long long llqq) if (Enabled) { if (!isLoadingExtern)console.log("已消除" + printUser(llqq) + "的危险等级", 0b10, printSTNow()); - if (UserList.count(llqq))AddMsgToQueue(getMsg("strBlackQQDelNotice", AttrVars{ {"uid",llqq}, {"user_nick", getName(llqq)}}), llqq); + if (UserList.count(llqq))AddMsgToQueue(getMsg("strBlackQQDelNotice", std::make_shared(AttrVars{ {"uid",llqq}, {"user_nick", getName(llqq)}})), llqq); } } } @@ -885,10 +885,10 @@ bool DDBlackManager::up_qq_danger(long long llqq, DDBlackMark& mark) { if (!mQQDanger.count(llqq) && UserList.count(llqq) && mark.danger == 2) mark.note.empty() - ? AddMsgToQueue(getMsg("strBlackQQAddNotice", AttrVars{ {"uid",llqq}, {"user_nick", getName(llqq)}}), llqq) - : AddMsgToQueue(getMsg("strBlackQQAddNoticeReason", AttrVars{ + ? AddMsgToQueue(getMsg("strBlackQQAddNotice", std::make_shared(AttrVars{ {"uid",llqq}, {"user_nick", getName(llqq)}})), llqq) + : AddMsgToQueue(getMsg("strBlackQQAddNoticeReason", std::make_shared(AttrVars{ {"uid",llqq}, {"reason", mark.note}, {"user_nick", getName(llqq)} - }), llqq); + })), llqq); if (!isLoadingExtern) { console.log(getMsg("strSelfName") + "已将" + printUser(llqq) + "危险等级提升至" + to_string(mark.danger), 0b10, printSTNow()); diff --git a/Dice/CharacterCard.cpp b/Dice/CharacterCard.cpp index cba98df1..e93c4c54 100644 --- a/Dice/CharacterCard.cpp +++ b/Dice/CharacterCard.cpp @@ -29,12 +29,12 @@ AttrShape::AttrShape(const tinyxml2::XMLElement* node, bool isUTF8) { defVal = AttrVar::parse(s); } } -AttrVar AttrShape::init(const CharaCard* pc) { +AttrVar AttrShape::init(CharaCard* pc) { if (textType == TextType::JavaScript) { - return js_context_eval(defVal, *pc); + return js_context_eval(defVal, pc->shared_from_this()); } else if (textType == TextType::Dicexp && !defVal.is_null()) { - if (auto exp{ fmt->format(defVal,*pc) }; exp.is_text()) { + if (auto exp{ fmt->format(defVal, pc->shared_from_this()) }; exp.is_text()) { return pc->cal(exp); } else return exp; @@ -192,16 +192,16 @@ ptr CharaCard::getTemplet()const{ } void CharaCard::update() { - (*dict)["__Update"] = (long long)time(nullptr); + dict["__Update"] = (long long)time(nullptr); } void CharaCard::setName(const string& strName) { - Attr["__Name"] = Name = strName; + dict["__Name"] = Name = strName; } void CharaCard::setType(const string& strType) { - Attr["__Type"] = strType; + dict["__Type"] = strType; } -AttrVar CharaCard::get(const string& key)const { - if (dict->count(key))return at(key); +AttrVar CharaCard::get(const string& key){ + if (dict.count(key))return dict.at(key); if (auto temp{ getTemplet() }; temp->canGet(key)) { return temp->AttrShapes.at(key).init(this); } @@ -213,24 +213,24 @@ int CharaCard::set(string key, const AttrVar& val) { if (val.is_text() && val.text.length() > 256)return -11; key = standard(key); if (getTemplet()->equalDefault(key, val)){ - if (has(key)) dict->erase(key); + if (has(key)) dict.erase(key); else return -1; } else { - Attr[key] = val; + dict[key] = val; } update(); return 0; } -string CharaCard::print(const string& key)const { - if (dict->count(key))return dict->at(key).print(); +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 {}; } -std::optional CharaCard::show(string key) const { +std::optional CharaCard::show(string key) { if (has(key) || has(key = standard(key))) { if (auto res{ get(key) }; !res.is_null())return res.print(); } @@ -238,7 +238,7 @@ std::optional CharaCard::show(string key) const { } bool CharaCard::has(const string& key)const { - return (dict->count(key) && !dict->at(key).is_null()) + return (dict.count(key) && !dict.at(key).is_null()) || getTemplet()->canGet(key); } @@ -246,9 +246,9 @@ bool CharaCard::has(const string& key)const { string CharaCard::getExp(string& key, std::unordered_set sRef){ sRef.insert(key = standard(key)); auto temp{ getTemplet() }; - 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); + 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); return "0"; @@ -257,7 +257,7 @@ bool CharaCard::countExp(const string& key)const { return key[0] == '&' ? (has(key) || getTemplet()->canGet(key)) : (has("&" + key) || getTemplet()->canGet("&" + key)); } -std::optional CharaCard::cal(string exp)const { +std::optional CharaCard::cal(string exp){ if (exp[0] == '&'){ if (auto res{ get(exp.substr(1)) };res.is_numberic()) { return res.to_int(); @@ -298,9 +298,9 @@ void CharaCard::buildv(string para) } void CharaCard::clear() { - dict = std::make_shared(AttrVars{{"__Type",Attr["__Type"]},{"__Name",Attr["__Name"]}} ); + dict = AttrVars{{"__Type",dict["__Type"]},{"__Name",dict["__Name"]}}; } -[[nodiscard]] string CharaCard::show(bool isWhole) const { +[[nodiscard]] string CharaCard::show(bool isWhole){ std::set sDefault; ResList Res; for (const auto& list : getTemplet()->vBasicList) { @@ -315,7 +315,7 @@ void CharaCard::clear() { Res << subList.show(); } string strAttrRest; - for (const auto& [key,val] : *dict) { + for (const auto& [key,val] : dict) { if (sDefault.count(key) || key[0] == '_' || (isWhole && val.type == AttrVar::Type::Number))continue; strAttrRest += key + ":" + val.print() + (val.type == AttrVar::Type::Number @@ -350,7 +350,7 @@ void CharaCard::writeb(std::ofstream& fout) const { fwrite(fout, string("Name")); fwrite(fout, Name); fwrite(fout, string("Attrs")); - AttrObject::writeb(fout); + AnysTable::writeb(fout); if (!locks.empty()) { fwrite(fout, string("Lock")); fwrite(fout, locks); @@ -365,17 +365,16 @@ void CharaCard::readb(std::ifstream& fin) { setName(fread(fin)); break; case 2: - Attr["__Type"] = fread(fin); + dict["__Type"] = fread(fin); break; case 3: - AttrObject::readb(fin); + AnysTable::readb(fin); break; case 11: { std::unordered_mapTempAttr; fread(fin, TempAttr); - TempAttr.erase(""); for (auto& [key, val] : TempAttr) { - AttrObject::set(key, val); + AnysTable::set(key, val); } } break; @@ -383,7 +382,7 @@ void CharaCard::readb(std::ifstream& fin) { std::unordered_mapTempExp; fread(fin, TempExp); for (auto& [key, val] : TempExp) { - AttrObject::set("&" + key, val); + AnysTable::set("&" + key, val); } } break; @@ -394,12 +393,12 @@ void CharaCard::readb(std::ifstream& fin) { std::unordered_mapTempInfo; fread(fin, TempInfo); for (auto& [key, val] : TempInfo) { - AttrObject::set(key, val); + AnysTable::set(key, val); } } break; case 101: - Attr["note"] = fread(fin); + dict["note"] = fread(fin); break; default: break; @@ -430,7 +429,7 @@ void CharaCard::cntRcStat(int die, int rate) { if (die <= 5)inc("__StatRcCnt5"); //统计出1-5 if (die >= 96)inc("__StatRcCnt96"); //统计出96-100 if (die == 100)inc("__StatRcCnt100"); //统计出100 - Attr["__StatRcSumRate"] = get_int("__StatRcSumRate") + rate; //总成功率 + dict["__StatRcSumRate"] = get_int("__StatRcSumRate") + rate; //总成功率 update(); } unordered_map PList; @@ -620,12 +619,12 @@ void Player::readb(std::ifstream& fin) fread(fin, mGroupIndex); } -AttrVar idx_pc(AttrObject& eve){ - if (eve.has("pc"))return eve["pc"]; - if (!eve.has("uid"))return {}; - long long uid{ eve.get_ll("uid") }; - long long gid{ eve.get_ll("gid") }; +AttrVar idx_pc(const AttrObject& eve){ + if (eve->has("pc"))return eve->at("pc"); + if (!eve->has("uid"))return {}; + long long uid{ eve->get_ll("uid") }; + long long gid{ eve->get_ll("gid") }; if (PList.count(uid) && PList[uid][gid]->getName() != "角色卡") - return eve["pc"] = PList[uid][gid]->getName(); + return eve->at("pc") = PList[uid][gid]->getName(); return idx_nick(eve); } diff --git a/Dice/CharacterCard.h b/Dice/CharacterCard.h index 973a9e31..d95f9f42 100644 --- a/Dice/CharacterCard.h +++ b/Dice/CharacterCard.h @@ -55,7 +55,7 @@ class AttrShape { vector alias; TextType textType{ TextType::Plain }; AttrVar defVal; - AttrVar init(const CharaCard*); + AttrVar init(CharaCard*); int check(AttrVar& val); bool equalDefault(const AttrVar& val)const { return TextType::Plain == textType && val == defVal; } }; @@ -129,7 +129,7 @@ int loadCardTemp(const std::filesystem::path& fpPath, dict_ci& m); extern unordered_map PlayerErrors; struct lua_State; -class CharaCard: public AttrObject +class CharaCard: public AnysTable { private: string Name = "角色卡"; @@ -154,19 +154,18 @@ class CharaCard: public AttrObject void setName(const string&); void setType(const string&); void update(); -#define Attr (*dict) CharaCard(){ - (*dict)["__Type"] = "COC7"; - (*dict)["__Update"] = (long long)time(nullptr); + dict["__Type"] = "COC7"; + dict["__Update"] = (long long)time(nullptr); } CharaCard(const CharaCard& pc){ Name = pc.Name; - dict = std::make_shared(*pc.dict); + dict = pc.dict; } CharaCard(const string& name, const string& type = "COC7") : Name(name) { - (*dict)["__Name"] = name; + dict["__Name"] = name; setType(type); } @@ -199,7 +198,7 @@ class CharaCard: public AttrObject bool countExp(const string& key)const; //计算表达式 - std::optional cal(string exp)const; + std::optional cal(string exp); void build(const string& para) { @@ -207,7 +206,7 @@ class CharaCard: public AttrObject 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)); + if (!dict.count(attr) || dict.at(attr).is_null())set(attr, shape.init(this)); } } } @@ -221,17 +220,17 @@ class CharaCard: public AttrObject return key; } - AttrVar get(const string& key)const; + AttrVar get(const string& key); int set(string key, const AttrVar& val); bool erase(string& key); void clear(); - std::optional show(string key) const; - string print(const string& key)const; + std::optional show(string key); + string print(const string& key); - [[nodiscard]] string show(bool isWhole) const; + [[nodiscard]] string show(bool isWhole); bool has(const string& key)const; //can get attr by card or temp @@ -247,8 +246,8 @@ class CharaCard: public AttrObject void cntRcStat(int die, int rate); void operator<<(const CharaCard& card){ - dict = std::make_shared(*card.dict); - AttrObject::set("__Name", Name); + dict = card.dict; + dict["__Name"] = Name; } void writeb(std::ofstream& fout) const; @@ -362,4 +361,4 @@ extern unordered_map PList; Player& getPlayer(long long qq); -AttrVar idx_pc(AttrObject&); +AttrVar idx_pc(const AttrObject&); diff --git a/Dice/Dice.cpp b/Dice/Dice.cpp index 0a41580a..f02e9bda 100644 --- a/Dice/Dice.cpp +++ b/Dice/Dice.cpp @@ -64,9 +64,9 @@ using namespace std; -unordered_map UserList{}; +unordered_map> UserList{}; unordered_map TinyList{}; -unordered_map ChatList; +unordered_map> ChatList; ThreadFactory threads; std::filesystem::path fpFileLoc; std::unique_ptr ManagerServer; @@ -143,11 +143,10 @@ void readUserData(){ } else { cnt = loadBFile(dir / "UserConf.RDconf", UserList); - loadFile(dir / "UserList.txt", UserList); if (cnt > 0)log << "迁移用户记录" + to_string(cnt) + "条"; } //for QQ Channel - if (User& self{ getUser(console.DiceMaid) }; !self.confs.get_ll("tinyID")) { + if (User& self{ getUser(console.DiceMaid) }; !self.get_ll("tinyID")) { if (long long tiny{ DD::getTinyID() }) { DD::debugMsg("获取分身ID:" + to_string(tiny)); self.setConf("tinyID", tiny); @@ -190,7 +189,6 @@ void readUserData(){ } else { cnt = loadBFile(dir / "ChatConf.RDconf", ChatList); - loadFile(dir / "ChatList.txt", ChatList); if (cnt > 0)log << "迁移群聊记录" + to_string(cnt) + "条"; } } @@ -324,8 +322,8 @@ EVE_Enable(eventEnable){ today = make_unique(); set grps{ DD::getGroupIDList() }; for (auto gid : grps){ - if (auto grp{ chat(gid).group().reset("未进").reset("已退").set("已入群") }; - !grp.isset("lastMsg"))grp.setLst(-1); + if (auto grp{ chat(gid).reset("未进").reset("已退").set("已入群") }; + !grp.is("lastMsg"))grp.setLst(-1); } // 确保线程执行结束 while (msgSendThreadRunning)this_thread::sleep_for(10ms); @@ -440,14 +438,14 @@ EVE_Enable(eventEnable){ getDiceList(); getExceptGroup(); isIniting.clear(); - fmt->call_hook_event(AttrVars{ {{"Event","StartUp"}} }); + fmt->call_hook_event(AnysTable{ AttrVars {{"Event","StartUp"}} }); } mutex GroupAddMutex; bool eve_GroupAdd(Chat& grp) { { unique_lock lock_queue(GroupAddMutex); - if (!grp.isset("已入群"))grp.set("已入群").reset("未进").reset("已退"); + if (!grp.is("已入群"))grp.set("已入群").reset("未进").reset("已退"); else return false; if (ChatList.size() == 1 && !console)DD::sendGroupMsg(grp.ID, msgInit); } @@ -455,16 +453,16 @@ bool eve_GroupAdd(Chat& grp) { if (grp.Name.empty()) grp.set("Name", grp.Name = DD::getGroupName(fromGID)); GroupSize_t gsize(DD::getGroupSize(fromGID)); - if (console["GroupInvalidSize"] > 0 && grp.confs.empty() && gsize.currSize > (size_t)console["GroupInvalidSize"]) { + if (console["GroupInvalidSize"] > 0 && grp.empty() && gsize.currSize > (size_t)console["GroupInvalidSize"]) { grp.set("协议无效"); } - if (!console["ListenGroupAdd"] || grp.isset("忽略"))return 0; + if (!console["ListenGroupAdd"] || grp.is("忽略"))return 0; string strNow = printSTNow(); string strMsg(getMsg("strSelfName")); - AttrObject eve{ { + AttrObject eve{ AnysTable{{ {"Event","GroupAdd"}, {"gid",fromGID}, - } }; + }} }; try { strMsg += "新加入:" + DD::printGroupInfo(grp.ID); @@ -475,8 +473,8 @@ bool eve_GroupAdd(Chat& grp) { console.log(strMsg, 0b10, printSTNow()); return true; } - if (grp.isset("许可使用"))strMsg += "(已获使用许可)"; - else if(grp.isset("协议无效"))strMsg += "(已标记协议无效)"; + if (grp.is("许可使用"))strMsg += "(已获使用许可)"; + else if(grp.is("协议无效"))strMsg += "(已标记协议无效)"; if (grp.inviter) { strMsg += ",邀请者" + printUser(grp.inviter); } @@ -506,7 +504,7 @@ bool eve_GroupAdd(Chat& grp) { if (blacklist->get_user_danger(each) > 1) { strMsg += ",发现黑名单管理员" + printUser(each); - if (grp.isset("免黑")) { + if (grp.is("免黑")) { strMsg += "(群免黑)"; } else @@ -568,7 +566,7 @@ bool eve_GroupAdd(Chat& grp) { console.log(strMsg, 1, strNow); return 0; } - if (console["Private"] && !grp.isset("许可使用")) + if (console["Private"] && !grp.is("许可使用")) { //避免小群绕过邀请没加上白名单 if (max_trust > 1 || ave_trust > 0.5) @@ -576,7 +574,7 @@ bool eve_GroupAdd(Chat& grp) { grp.set("许可使用"); strMsg += "\n已自动追加使用许可"; } - else if(!grp.isset("协议无效")) + else if(!grp.is("协议无效")) { strMsg += "\n无许可使用,已退群"; console.log(strMsg, 1, strNow); @@ -592,13 +590,13 @@ bool eve_GroupAdd(Chat& grp) { console.log(strMsg + "\n群" + to_string(fromGID) + "信息获取失败!", 0b1, printSTNow()); return true; } - if (grp.isset("协议无效"))return 0; - if (string selfIntro{ getMsg("strAddGroup", AttrVars{{"gid",fromGID}}) }; + if (grp.is("协议无效"))return 0; + if (string selfIntro{ getMsg("strAddGroup", AnysTable{{"gid",fromGID}}) }; !selfIntro.empty()) { this_thread::sleep_for(2s); AddMsgToQueue(selfIntro, { 0,fromGID, 0 }); } - if (console["CheckGroupLicense"] && !grp.isset("许可使用")) { + if (console["CheckGroupLicense"] && !grp.is("许可使用")) { grp.set("未审核"); this_thread::sleep_for(2s); AddMsgToQueue(getMsg("strGroupLicenseDeny"), { 0,fromGID, 0 }); @@ -627,10 +625,10 @@ EVE_PrivateMsg(eventPrivateMsg) EVE_GroupMsg(eventGroupMsg) { if (!Enabled)return 0; - Chat& grp = chat(fromGID).group(); + Chat& grp = chat(fromGID); if (fromUID == console.DiceMaid && !console["ListenGroupEcho"])return 0; - if (!grp.isset("已入群") && grp.getLst())eve_GroupAdd(grp); - if (!grp.isset("忽略")) { + if (!grp.is("已入群") && grp.getLst())eve_GroupAdd(grp); + if (!grp.is("忽略")) { shared_ptr Msg(make_shared( AttrVars({ { "Event", "Message" }, { "fromMsg", message }, @@ -641,14 +639,14 @@ EVE_GroupMsg(eventGroupMsg) }), chatInfo{ fromUID,fromGID,0 })); return Msg->DiceFilter(); } - return grp.setLst(time(nullptr)).isset("拦截消息"); + return grp.setLst(time(nullptr)).is("拦截消息"); } EVE_ChannelMsg(eventChannelMsg) { if (!Enabled)return 0; - Chat& grp = chat(fromGID).channel(); + Chat& grp = chat(fromGID); if (fromUID == console.DiceMaid && !console["ListenChannelEcho"])return 0; - //if (!grp.isset("忽略")) + //if (!grp.is("忽略")) { shared_ptr Msg(make_shared( AttrVars({ { "Event","Message"}, @@ -661,7 +659,7 @@ EVE_ChannelMsg(eventChannelMsg) }), chatInfo{ fromUID,fromGID,fromChID })); return Msg->DiceFilter(); } - //return grp.isset("拦截消息"); + //return grp.is("拦截消息"); return false; } @@ -690,21 +688,22 @@ EVE_DiscussMsg(eventDiscussMsg) { "uid", fromUID }, { "gid", fromDiscuss } }), chatInfo{ fromUID,fromDiscuss,0 })); - return Msg->DiceFilter() || grp.isset("拦截消息"); + return Msg->DiceFilter() || grp.is("拦截消息"); } EVE_GroupMemberIncrease(eventGroupMemberAdd) { if (!Enabled)return 0; Chat& grp = chat(fromGID); - if (grp.isset("忽略"))return 0; + if (grp.is("忽略"))return 0; if (fromUID != console.DiceMaid){ - if (chat(fromGID).confs.has("入群欢迎")){ - AttrObject eve{ {{ "Event","GroupWelcome"}, + if (chat(fromGID).has("入群欢迎")){ + AttrObject eve{ AnysTable{{ + { "Event","GroupWelcome"}, {"gid",fromGID}, {"uid",fromUID}, - } }; - AddMsgToQueue(strip(fmt->format(grp.update().confs.get_str("入群欢迎"), eve, false)), + }} }; + AddMsgToQueue(strip(fmt->format(grp.update().get_str("入群欢迎"), eve, false)), { 0,fromGID }); } if (blacklist->get_user_danger(fromUID)) @@ -713,9 +712,9 @@ EVE_GroupMemberIncrease(eventGroupMemberAdd) string strNote = printGroup(fromGID) + "发现" + getMsg("strSelfName") + "的黑名单用户" + printUser( fromUID) + "入群"; AddMsgToQueue(blacklist->list_self_qq_warning(fromUID), { 0,fromGID }); - if (grp.isset("免清"))strNote += "(群免清)"; - else if (grp.isset("免黑"))strNote += "(群免黑)"; - else if (grp.isset("协议无效"))strNote += "(群协议无效)"; + if (grp.is("免清"))strNote += "(群免清)"; + else if (grp.is("免黑"))strNote += "(群免黑)"; + else if (grp.is("协议无效"))strNote += "(群协议无效)"; else if (DD::isGroupAdmin(fromGID, console.DiceMaid, false))strNote += "(群内有权限)"; else if (console["LeaveBlackQQ"]) { @@ -729,7 +728,7 @@ EVE_GroupMemberIncrease(eventGroupMemberAdd) if (!grp.inviter)grp.inviter = operatorQQ; { unique_lock lock_queue(GroupAddMutex); - if (grp.isset("已入群"))return 0; + if (grp.is("已入群"))return 0; } return eve_GroupAdd(grp); } @@ -741,16 +740,16 @@ EVE_GroupMemberKicked(eventGroupMemberKicked){ Chat& grp = chat(fromGID); if (beingOperateQQ == console.DiceMaid){ grp.reset("已入群").rmLst(); - if (!console || grp.isset("忽略"))return 0; + if (!console || grp.is("忽略"))return 0; string strNow = printSTime(stNow); string strNote = printUser(fromUID) + "将" + printUser(beingOperateQQ) + "移出了" + printChat(grp); console.log(strNote, 0b1000, strNow); - if (!console["ListenGroupKick"] || trustedQQ(fromUID) > 1 || grp.isset("免黑") || grp.isset("协议无效") || ExceptGroups.count(fromGID)) return 0; - AttrObject eve{ { + if (!console["ListenGroupKick"] || trustedQQ(fromUID) > 1 || grp.is("免黑") || grp.is("协议无效") || ExceptGroups.count(fromGID)) return 0; + AttrObject eve{ AnysTable{{ {"Event","GroupKicked"}, {"uid",fromUID}, {"gid",fromGID}, - } }; + }} }; if (fmt->call_hook_event(eve))return 1; DDBlackMarkFactory mark{fromUID, fromGID}; mark.sign().type("kick").time(strNow).note(strNow + " " + strNote).comment(getMsg("strSelfCall") + "原生记录"); @@ -764,11 +763,11 @@ EVE_GroupMemberKicked(eventGroupMemberKicked){ } else if (mDiceList.count(beingOperateQQ) && console["ListenGroupKick"]) { - if (!console || grp.isset("忽略"))return 0; + if (!console || grp.is("忽略"))return 0; string strNow = printSTime(stNow); string strNote = printUser(fromUID) + "将" + printUser(beingOperateQQ) + "移出了" + printChat(grp); console.log(strNote, 0b1000, strNow); - if (trustedQQ(fromUID) > 1 || grp.isset("免黑") || grp.isset("协议无效") || ExceptGroups.count(fromGID)) return 0; + if (trustedQQ(fromUID) > 1 || grp.is("免黑") || grp.is("协议无效") || ExceptGroups.count(fromGID)) return 0; DDBlackMarkFactory mark{fromUID, fromGID}; mark.type("kick").time(strNow).note(strNow + " " + strNote).DiceMaid(beingOperateQQ).master(mDiceList[beingOperateQQ]).comment(strNow + " " + printUser(console.DiceMaid) + "目击"); grp.reset("许可使用").reset("免清"); @@ -781,7 +780,7 @@ EVE_GroupBan(eventGroupBan) { if (!Enabled) return 0; Chat& grp = chat(fromGID); - if (grp.isset("忽略") || (beingOperateQQ != console.DiceMaid && !mDiceList.count(beingOperateQQ)) || !console["ListenGroupBan"])return 0; + if (grp.is("忽略") || (beingOperateQQ != console.DiceMaid && !mDiceList.count(beingOperateQQ)) || !console["ListenGroupBan"])return 0; if (!duration || !duration[0]) { if (beingOperateQQ == console.DiceMaid) @@ -795,17 +794,17 @@ EVE_GroupBan(eventGroupBan) string strNow = printSTNow(); long long llOwner = 0; string strNote = "在" + printGroup(fromGID) + "中," + printUser(beingOperateQQ) + "被" + printUser(operatorQQ) + "禁言" + duration; - if (!console["ListenGroupBan"] || trustedQQ(operatorQQ) > 1 || grp.isset("免黑") || grp.isset("协议无效") || ExceptGroups.count(fromGID)) + if (!console["ListenGroupBan"] || trustedQQ(operatorQQ) > 1 || grp.is("免黑") || grp.is("协议无效") || ExceptGroups.count(fromGID)) { console.log(strNote, 0b10, strNow); return 1; } - AttrObject eve{ { + AttrObject eve{ AnysTable{{ {"Event","GroupBanned"}, {"uid",operatorQQ}, {"gid",fromGID}, {"duration",duration}, - } }; + }} }; if (fmt->call_hook_event(eve))return 1; DDBlackMarkFactory mark{operatorQQ, fromGID}; mark.type("ban").time(strNow).note(strNow + " " + strNote); @@ -854,14 +853,14 @@ EVE_GroupInvited(eventGroupInvited) if (groupset(fromGID, "忽略") < 1) { this_thread::sleep_for(3s); - AttrObject eve{ { + AttrObject eve{ AnysTable{ { {"Event","GroupRequest"}, {"uid",fromUID}, {"gid",fromGID}, - } }; + }} }; bool isBlocked{ fmt->call_hook_event(eve) }; - if (eve.has("approval")) { - if (eve.is("approval")) { + if (eve->has("approval")) { + if (eve->is("approval")) { chat(fromGID).inviter = fromUID; DD::answerFriendRequest(fromUID, 1); } @@ -886,7 +885,7 @@ EVE_GroupInvited(eventGroupInvited) console.log(strMsg, 0b10, strNow); DD::answerGroupInvited(fromGID, 2); } - else if (Chat& grp = chat(fromGID).group(); grp.isset("许可使用")) { + else if (Chat& grp = chat(fromGID); grp.is("许可使用")) { grp.setLst(0); grp.inviter = fromUID; strMsg += "\n已同意(已许可使用)"; @@ -901,7 +900,7 @@ EVE_GroupInvited(eventGroupInvited) console.log(strMsg, 1, strNow); DD::answerGroupInvited(fromGID, 1); } - else if (grp.isset("协议无效")) { + else if (grp.is("协议无效")) { strMsg += "\n已忽略(协议无效)"; console.log(strMsg, 0b10, strNow); DD::answerGroupInvited(fromGID, 3); @@ -934,15 +933,15 @@ EVE_FriendRequest(eventFriendRequest) { if (!Enabled) return 0; if (!console["ListenFriendRequest"])return 0; this_thread::sleep_for(3s); - AttrObject eve{{ + AttrObject eve{ AnysTable{{ {"Event","FriendRequest"}, {"fromMsg",message}, {"uid",fromUID}, - } }; + }} }; bool isBlocked{ fmt->call_hook_event(eve) }; - if (eve.has("approval")) { - DD::answerFriendRequest(fromUID, eve.is("approval") ? 1 : 2, - fmt->format(eve.get_str("msg_reply"), eve)); + if (eve->has("approval")) { + DD::answerFriendRequest(fromUID, eve->is("approval") ? 1 : 2, + fmt->format(eve->get_str("msg_reply"), eve)); } if (isBlocked)return 1; string strMsg = "好友添加请求,来自 " + printUser(fromUID) + ":" + message; @@ -977,10 +976,10 @@ EVE_FriendAdded(eventFriendAdd) { if (!Enabled) return 0; if (!console["ListenFriendAdd"])return 0; this_thread::sleep_for(3s); - AttrObject eve{ { + AttrObject eve{ AnysTable{{ {"Event","FriendAdd"}, {"uid",fromUID}, - } }; + }} }; if(fmt->call_hook_event(eve))return 1; (trustedQQ(fromUID) > 0 && !getMsg("strAddFriendWhiteQQ", eve).empty()) ? AddMsgToQueue(getMsg("strAddFriendWhiteQQ", eve), fromUID) @@ -990,7 +989,7 @@ EVE_FriendAdded(eventFriendAdd) { EVE_Extra(eventExtra) { if (!Enabled) return 0; try { - AttrObject eve{ AttrObject(fifo_json::parse(jsonData)) }; + AttrObject eve{ AnysTable(fifo_json::parse(jsonData)) }; if (fmt->call_hook_event(eve))return 1; } catch (std::exception& e) { diff --git a/Dice/DiceAttrVar.cpp b/Dice/DiceAttrVar.cpp index 3b394d86..4da31a10 100644 --- a/Dice/DiceAttrVar.cpp +++ b/Dice/DiceAttrVar.cpp @@ -30,37 +30,54 @@ ByteS::ByteS(std::ifstream& fin) { bytes = new char[len + 1]; fin.read(bytes, len); } -bool AttrObject::is(const string& key)const { - return dict->count(key) ? bool(dict->at(key)) : false; +bool AnysTable::is(const string& key)const { + return dict.count(key) ? bool(dict.at(key)) : false; } -bool AttrObject::is_empty(const string& key)const { - auto it{ dict->find(key) }; - return (it == dict->end()) +bool AnysTable::is_empty(const string& key)const { + auto it{ dict.find(key) }; + return (it == dict.end()) || (it->second.type == AttrVar::Type::Text && it->second.text.empty()) - || (it->second.type == AttrVar::Type::Table && it->second.table.empty()); + || (it->second.type == AttrVar::Type::Table && it->second.table->empty()); } -bool AttrObject::is_table(const string& key)const { - return dict->count(key) && dict->at(key).is_table(); +bool AnysTable::is_table(const string& key)const { + return dict.count(key) && dict.at(key).is_table(); } -bool AttrObject::empty()const { - return dict->empty() && (!list || list->empty()); +bool AnysTable::empty()const { + return dict.empty() && (!list || list->empty()); } -bool AttrObject::has(const string& key)const { - return dict->count(key) && !dict->at(key).is_null(); +bool AnysTable::has(const string& key)const { + return dict.count(key) && !dict.at(key).is_null(); } -void AttrObject::set(const string& key, const AttrVar& val)const { - if (key.empty())return; - if (val.is_null())dict->erase(key); - else (*dict)[key] = val; +void AnysTable::set(const string& key, const AttrVar& val){ + if (!key.empty()) { + if (val.is_null())dict.erase(key); + else dict[key] = val; + } } -void AttrObject::set(const string& key)const { - if (key.empty())return; - (*dict)[key] = true; +void AnysTable::set(const string& key){ + if (!key.empty())dict[key] = true; +} +void AnysTable::set(int i, const AttrVar& val) { + if (list) { + if (list->size() == i) { + list->emplace_back(val); + return; + } + else if (list->size() > i) { + list->at(i) = val; + return; + } + } + else if (i == 0) { + list = std::make_shared(VarArray{ val }); + return; + } + set(to_string(i), val); } -void AttrObject::reset(const string& key)const { - dict->erase(key); +void AnysTable::reset(const string& key){ + dict.erase(key); } -vector AttrObject::to_deck()const { +vector AnysTable::to_deck()const { vector deck; if (list) { for (auto& it : *list) { @@ -69,71 +86,74 @@ vector AttrObject::to_deck()const { } return deck; } -AttrVar& AttrObject::at(const string& key)const { - return (*dict)[key]; +AttrVar& AnysTable::at(const string& key){ + return dict[key]; } -AttrVar& AttrObject::operator[](const char* key)const { - return (*dict)[key]; +const AttrVar& AnysTable::at(const string& key)const { + return dict.at(key); } -AttrVar AttrObject::get(const string& key, ptr val)const { - return dict->count(key) ? dict->at(key) +AttrVar& AnysTable::operator[](const char* key){ + return dict[key]; +} +AttrVar AnysTable::get(const string& key, ptr val)const { + return dict.count(key) ? dict.at(key) : val ? *val : AttrVar(); } -string AttrObject::get_str(const string& key)const { - return dict->count(key) ? dict->at(key).to_str() : ""; +string AnysTable::get_str(const string& key)const { + return dict.count(key) ? dict.at(key).to_str() : ""; } -string AttrObject::get_str(const string& key, const string& val)const { - return dict->count(key) ? dict->at(key).to_str() : val; +string AnysTable::get_str(const string& key, const string& val)const { + return dict.count(key) ? dict.at(key).to_str() : val; } -string AttrObject::print(const string& key)const { - return dict->count(key) ? dict->at(key).print() : ""; +string AnysTable::print(const string& key)const { + return dict.count(key) ? dict.at(key).print() : ""; } -int AttrObject::get_int(const string& key)const { - return dict->count(key) ? dict->at(key).to_int() : 0; +int AnysTable::get_int(const string& key)const { + return dict.count(key) ? dict.at(key).to_int() : 0; } -long long AttrObject::get_ll(const string& key)const { - return dict->count(key) ? dict->at(key).to_ll() : 0; +long long AnysTable::get_ll(const string& key)const { + return dict.count(key) ? dict.at(key).to_ll() : 0; } -double AttrObject::get_num(const string& key)const { - return dict->count(key) ? dict->at(key).to_num() : 0; +double AnysTable::get_num(const string& key)const { + return dict.count(key) ? dict.at(key).to_num() : 0; } -AttrObject AttrObject::get_obj(const string& key)const { - return dict->count(key) ? dict->at(key).to_obj() : AttrObject(); +AttrObject AnysTable::get_obj(const string& key)const { + return dict.count(key) ? dict.at(key).to_obj() : ptr(); } -ptr AttrObject::get_dict(const string& key)const { - return dict->count(key) ? dict->at(key).to_dict() : ptr(); +std::optional AnysTable::get_dict(const string& key)const { + return dict.count(key) ? dict.at(key).to_dict() : std::nullopt; } -ptr AttrObject::get_list(const string& key)const { - return dict->count(key) ? dict->at(key).to_list() : ptr(); +ptr AnysTable::get_list(const string& key)const { + return dict.count(key) ? dict.at(key).to_list() : ptr(); } -AttrSet AttrObject::get_set(const string& key)const { - return dict->count(key) ? dict->at(key).to_set() : AttrSet(); +AttrSet AnysTable::get_set(const string& key)const { + return dict.count(key) ? dict.at(key).to_set() : AttrSet(); } -int AttrObject::inc(const string& key)const { +int AnysTable::inc(const string& key){ if (key.empty())return 0; - if (dict->count(key))return (++dict->at(key)).to_int(); - else dict->emplace(key, 1); + if (dict.count(key))return (++dict.at(key)).to_int(); + else dict.emplace(key, 1); return 1; } -int AttrObject::inc(const string& key, int i)const { +int AnysTable::inc(const string& key, int i){ if (key.empty())return 0; - if (dict->count(key))return (dict->at(key) += i).to_int(); - else dict->emplace(key, i); + if (dict.count(key))return (dict.at(key) += i).to_int(); + else dict.emplace(key, i); return 1; } -void AttrObject::add(const string& key, const AttrVar& val)const { +void AnysTable::add(const string& key, const AttrVar& val){ if (key.empty())return; - (*dict)[key] = (*dict)[key] + val; + dict[key] = dict[key] + val; } -AttrObject& AttrObject::merge(const AttrVars& other) { +AnysTable& AnysTable::merge(const AttrVars& other) { for (const auto& [key, val] : other) { - (*dict)[key] = val; + dict[key] = val; } return *this; } -void AttrObject::writeb(std::ofstream& fout) const { - AttrVars vars{ *dict }; +void AnysTable::writeb(std::ofstream& fout) const { + AttrVars vars{ dict }; if (list) { int idx{ 0 }; for (auto& val : *list) { @@ -143,25 +163,25 @@ void AttrObject::writeb(std::ofstream& fout) const { } fwrite(fout, vars); } -void AttrObject::readb(std::ifstream& fs) { +void AnysTable::readb(std::ifstream& fs) { short len = fread(fs); if (len < 0)return; if (!fs.peek()) { fs.ignore(2); } while (len--) { - (*dict)[fread(fs)].readb(fs); + dict[fread(fs)].readb(fs); } - if (string strI{ "0" }; dict->count(strI) || dict->count(strI = "1")) { + if (string strI{ "0" }; dict.count(strI) || dict.count(strI = "1")) { list = std::make_shared(); int idx{ strI == "0" ? 0 : 1 }; do { - list->push_back(dict->at(strI)); - dict->erase(strI); - } while (dict->count(strI = to_string(++idx))); + list->push_back(dict.at(strI)); + dict.erase(strI); + } while (dict.count(strI = to_string(++idx))); } } -bool AttrObject::operator<(const AttrObject other)const { return dict < other.dict; } +bool AnysTable::operator<(const AnysTable other)const { return dict < other.dict; } AttrVar::AttrVar(const AttrVar& other) :type(other.type) { switch (type) { @@ -540,7 +560,7 @@ size_t AttrVar::len()const { return text.length(); break; case Type::Table: - table.size(); + table->size(); break; case Type::Set: return flags->size(); @@ -552,17 +572,17 @@ bool AttrVar::str_empty()const{ return type == Type::Text && text.empty(); } AttrObject AttrVar::to_obj()const { - if (type != Type::Table)return {}; - return table; + if (type != Type::Table)return table; + return {}; } -ptr AttrVar::to_dict()const { +std::optional AttrVar::to_dict()const { if (type != Type::Table)return {}; - return table.to_dict(); + return &table->as_dict(); } ptr AttrVar::to_list()const { if (type != Type::Table)return {}; - return table.to_list(); + return table->to_list(); } AttrSet AttrVar::to_set()const { if (type != Type::Set)return {}; @@ -641,28 +661,28 @@ AttrVar::AttrVar(const fifo_json& j) { break; case fifo_json::value_t::object: type = Type::Table; { - new(&table)AttrObject(); + new(&table)AnysTable(); unordered_set idxs; if (string strI{ "0" }; j.count(strI)) { - table.list = std::make_shared(); + table->list = std::make_shared(); int idx{ 0 }; do { - table.list->push_back(j[strI]); + table->list->push_back(j[strI]); idxs.insert(strI); } while (j.count(strI = to_string(++idx))); } for (auto& it : j.items()) { if (idxs.count(it.key()))continue; - if (!it.value().is_null())table.dict->emplace(UTF8toGBK(it.key()), it.value()); + if (!it.value().is_null())table->dict.emplace(UTF8toGBK(it.key()), it.value()); } } break; case fifo_json::value_t::array: type = Type::Table; { - new(&table)AttrObject(); - table.list = std::make_shared(); + new(&table)AnysTable(); + table->list = std::make_shared(); for (auto& it : j) { - table.list->push_back(it); + table->list->push_back(it); } } break; @@ -715,7 +735,7 @@ fifo_json AttrVar::to_json()const { return id; break; case Type::Table: - return table.to_json(); + return table->to_json(); break; case Type::Set: return ::to_json(*flags); @@ -724,8 +744,8 @@ fifo_json AttrVar::to_json()const { } return {}; } -fifo_json AttrObject::to_json()const { - if (dict->empty() && list) { +fifo_json AnysTable::to_json()const { + if (dict.empty() && list) { fifo_json j = fifo_json::array(); for (auto& val : *list) { j.push_back(val ? val.to_json() : fifo_json()); @@ -734,7 +754,7 @@ fifo_json AttrObject::to_json()const { } else { fifo_json j = fifo_json::object(); - for (auto& [key, val] : *dict) { + for (auto& [key, val] : dict) { if (val)j[GBKtoUTF8(key)] = val.to_json(); } if (list) { @@ -754,29 +774,29 @@ AttrVar::AttrVar(const toml::node& t) { break; case toml::node_type::table: type = Type::Table; { - new(&table)AttrObject(); + new(&table)AnysTable(); auto tab{ t.as_table() }; unordered_set idxs; if (string strI{ "0" }; tab->contains(strI)) { - table.list = std::make_shared(); + table->list = std::make_shared(); int idx{ 0 }; do { - table.list->push_back(AttrVar(*(*tab)[strI].node())); + table->list->push_back(AttrVar(*(*tab)[strI].node())); idxs.insert(strI); } while (tab->contains(strI = to_string(++idx))); } for (auto& [key,val] : *tab) { if (idxs.count(string(key.str())))continue; - table.dict->emplace(UTF8toGBK(string(key.str())), val); + table->dict.emplace(UTF8toGBK(string(key.str())), val); } } break; case toml::node_type::array: type = Type::Table; { - new(&table)AttrObject(); - table.list = std::make_shared(); + new(&table)AnysTable(); + table->list = std::make_shared(); for (auto& it : *t.as_array()) { - table.list->push_back(it); + table->list->push_back(it); } } break; @@ -809,9 +829,9 @@ AttrVar::AttrVar(const toml::node& t) { break; //Todo:parse time } } -toml::table AttrObject::to_toml()const { +toml::table AnysTable::to_toml()const { toml::table tab; - for (auto& [key, val] : *dict) { + for (auto& [key, val] : dict) { if (val)switch (val.type) { case AttrVar::Type::Boolean: tab.insert(GBKtoUTF8(key), val.bit); @@ -829,7 +849,7 @@ toml::table AttrObject::to_toml()const { tab.insert(GBKtoUTF8(key), val.id); break; case AttrVar::Type::Table: - tab.insert(GBKtoUTF8(key), val.table.to_toml()); + tab.insert(GBKtoUTF8(key), val.table->to_toml()); break; case AttrVar::Type::Set: tab.insert(GBKtoUTF8(key), ::to_toml(*val.flags)); @@ -868,20 +888,20 @@ AttrVar::AttrVar(const YAML::Node& y) { } else if (y.IsMap()) { type = Type::Table; { - new(&table)AttrObject(); + new(&table)AnysTable(); unordered_set idxs; string strIdx{ "0" }; if (y[strIdx] || y[strIdx = "1"]) { - table.list = std::make_shared(); + table->list = std::make_shared(); int idx{ 1 }; do { - table.list->push_back(y[strIdx]); + table->list->push_back(y[strIdx]); idxs.insert(strIdx); } while (y[strIdx = to_string(++idx)]); } for (auto& it : y) { if (idxs.count(it.first.Scalar()))continue; - table.dict->emplace(UTF8toGBK(it.first.Scalar()), it.second); + table->dict.emplace(UTF8toGBK(it.first.Scalar()), it.second); } } } @@ -891,7 +911,7 @@ AttrVar::AttrVar(const YAML::Node& y) { for (YAML::Node it : y) { list.push_back(it); } - new(&table)AttrObject(list); + new(&table)AnysTable(list); } } YAML::Node AttrVar::to_yaml()const { @@ -913,12 +933,12 @@ YAML::Node AttrVar::to_yaml()const { yaml = id; break; case Type::Table: - for (auto& [k, v] : *table.to_dict()) { + for (auto& [k, v] : table->as_dict()) { yaml[GBKtoUTF8(k)] = v.to_yaml(); } - if (auto li{ table.to_list() }) { + if (auto li{ table->to_list() }) { int i = 0; - if (table.to_dict()->empty()) { + if (!yaml.IsMap()) { for (auto& v : *li) { yaml[i++] = v.to_yaml(); } @@ -1017,7 +1037,7 @@ void AttrVar::writeb(std::ofstream& fout) const { break; case Type::Table: fwrite(fout, (char)5); - table.writeb(fout); + table->writeb(fout); break; case Type::Function: fwrite(fout, (char)6); @@ -1059,8 +1079,8 @@ void AttrVar::readb(std::ifstream& fin) { break; case 5: type = Type::Table; - new(&table) AttrObject(); - table.readb(fin); + new(&table) AnysTable(); + table->readb(fin); break; case 6: type = Type::Function; @@ -1118,14 +1138,14 @@ string showAttrCMPR(AttrVar::CMPR cmpr) { return {}; } -AttrVar AttrObject::index(const string& key)const { - if (dict->count(key))return dict->at(key); +AttrVar AnysTable::index(const string& key)const { + if (dict.count(key))return dict.at(key); AttrVar var; size_t dot{ 0 }; while ((dot = key.find('.', ++dot)) != string::npos) { string sub{ key.substr(0,dot) }; - if (dict->count(sub) && dict->at(sub).is_table() - && (var = dict->at(sub).table.index(key.substr(dot + 1)))) { + if (dict.count(sub) && dict.at(sub).is_table() + && (var = dict.at(sub).table->index(key.substr(dot + 1)))) { break; } } diff --git a/Dice/DiceAttrVar.h b/Dice/DiceAttrVar.h index 14d6999f..af717b70 100644 --- a/Dice/DiceAttrVar.h +++ b/Dice/DiceAttrVar.h @@ -83,65 +83,19 @@ struct std::equal_to { } }; -class AttrObject { -protected: - ptrdict; - ptrlist; - friend class AttrVar; - friend AttrVar lua_to_attr(lua_State*, int); - friend void lua_push_attr(lua_State*, const AttrVar&); -public: - AttrObject() :dict(std::make_shared()) {} - AttrObject(const AttrVars& vars) :dict(std::make_shared(vars)) {} - explicit AttrObject(const VarArray& vars) :dict(std::make_shared()), list(std::make_shared(vars)) {} - template - AttrObject(const std::vector& vars) :dict(std::make_shared()), list(std::make_shared()) { - for (auto& it : vars)list->emplace_back(it); +class AnysTable; +struct AttrObject { + ptr p; + AttrObject(const ptr& ptr = {}) :p(ptr) {} + AttrObject(const AnysTable& vars) :p(std::make_shared(vars)) {} + AnysTable* const operator->()const { + return p.get(); } - AttrObject(const AttrObject& other) :dict(other.dict), list(other.list) {} - const ptr& to_dict()const { return dict; } - const ptr& to_list()const { return list; } - std::vector to_deck()const; - const ptr& new_list() { return list = std::make_shared(); } - AttrVars* operator->()const { - return dict.get(); + AnysTable& operator*()const { + return *p.get(); } - AttrVar& at(const string& key)const; - AttrVar& operator[](const char* key)const; - bool operator<(const AttrObject other)const; - //bool operator<(const AttrObject& other)const { return dict < other.dict; } - bool empty()const; - bool has(const string& key)const; - void set(const string& key, const AttrVar& val)const; - void set(const string& key)const; - void reset(const string& key)const; - bool is(const string& key)const; - bool is_empty(const string& key)const; - bool is_table(const string& key)const; - size_t size()const { return dict->size(); } - size_t length()const { return list?list->size() : dict->size(); } - AttrVar index(const string& key)const; - AttrVar get(const string& key, ptr val = {})const; - string get_str(const string& key)const; - string get_str(const string& key, const string& val)const; - string print(const string& key)const; - int get_int(const string& key)const; - long long get_ll(const string& key)const; - double get_num(const string& key)const; - AttrObject get_obj(const string& key)const; - ptr get_dict(const string& key)const; - ptr get_list(const string& key)const; - AttrSet get_set(const string& key)const; - int inc(const string& key)const; - int inc(const string& key, int i)const; - void add(const string& key, const AttrVar&)const; - AttrObject& merge(const AttrVars& other); - fifo_json to_json()const; - toml::table to_toml()const; - void writeb(std::ofstream&)const; - void readb(std::ifstream&); + operator bool()const { return bool(p); } }; - class AttrVar { public: enum class Type { Nil, Boolean, Integer, Number, Text, Table, Function, ID, Set }; @@ -176,8 +130,9 @@ class AttrVar { AttrVar(const fifo_json&); AttrVar(const toml::node&); AttrVar(const YAML::Node&); + AttrVar(const AnysTable& vars) :type(Type::Table), table(vars) {} AttrVar(const AttrObject& vars) :type(Type::Table), table(vars) {} - explicit AttrVar(const AttrVars& vars) :type(Type::Table), table(vars) {} + explicit AttrVar(const AttrVars& vars) :type(Type::Table), table(std::make_shared(vars)) {} void des() { if (type == Type::Text)text.~string(); else if (type == Type::Table)table.~AttrObject(); @@ -216,7 +171,7 @@ class AttrVar { size_t len()const; bool str_empty()const; AttrObject to_obj()const; - ptr to_dict()const; + std::optional to_dict()const; ptr to_list()const; AttrSet to_set()const; fifo_json to_json()const; @@ -252,6 +207,66 @@ fifo_json to_json(const AttrVars& vars); void from_json(const fifo_json& j, AttrVars&); string showAttrCMPR(AttrVar::CMPR); -using AttrObjects = std::unordered_map; -using AttrGetter = AttrVar(*)(AttrObject&); +class AnysTable: public std::enable_shared_from_this { +protected: + AttrVars dict; + ptrlist; + friend class AttrVar; + friend AttrVar lua_to_attr(lua_State*, int); + friend void lua_push_attr(lua_State*, const AttrVar&); +public: + AnysTable() {} + AnysTable(const AttrVars& vars) :dict(vars) {} + explicit AnysTable(const VarArray& vars) :list(std::make_shared(vars)) {} + template + AnysTable(const std::vector& vars) : list(std::make_shared()) { + for (auto& it : vars)list->emplace_back(it); + } + AnysTable(const AnysTable& other) :dict(other.dict), list(other.list) {} + AttrVars& as_dict() { return dict; } + const ptr& to_list()const { return list; } + std::vector to_deck()const; + const ptr& new_list() { return list = std::make_shared(); } + AttrVars* operator->() { + return &dict; + } + AttrVar& at(const string& key); + const AttrVar& at(const string& key)const; + AttrVar& operator[](const char* key); + bool operator<(const AnysTable other)const; + //bool operator<(const AnysTable& other)const { return dict < other.dict; } + bool empty()const; + bool has(const string& key)const; + void set(const string& key, const AttrVar& val); + void set(const string& key); + void set(int i, const AttrVar& val); + void reset(const string& key); + [[nodiscard]] bool is(const string& key)const; + bool is_empty(const string& key)const; + bool is_table(const string& key)const; + size_t size()const { return dict.size(); } + size_t length()const { return list ? list->size() : dict.size(); } + AttrVar index(const string& key)const; + AttrVar get(const string& key, ptr val = {})const; + string get_str(const string& key)const; + string get_str(const string& key, const string& val)const; + string print(const string& key)const; + int get_int(const string& key)const; + long long get_ll(const string& key)const; + double get_num(const string& key)const; + AttrObject get_obj(const string& key)const; + std::optional get_dict(const string& key)const; + ptr get_list(const string& key)const; + AttrSet get_set(const string& key)const; + int inc(const string& key); + int inc(const string& key, int i); + void add(const string& key, const AttrVar&); + AnysTable& merge(const AttrVars& other); + fifo_json to_json()const; + toml::table to_toml()const; + void writeb(std::ofstream&)const; + void readb(std::ifstream&); +}; +//using AnysTables = std::unordered_map; +using AttrGetter = AttrVar(*)(const AttrObject&); using AttrGetters = std::unordered_map; \ No newline at end of file diff --git a/Dice/DiceConsole.cpp b/Dice/DiceConsole.cpp index c39c9a88..f8f8f121 100644 --- a/Dice/DiceConsole.cpp +++ b/Dice/DiceConsole.cpp @@ -437,7 +437,7 @@ std::string printSTime(const tm st) string printGroup(long long llgroup) { if (!llgroup)return "私聊"; - if (ChatList.count(llgroup))return printChat(ChatList[llgroup]); + if (ChatList.count(llgroup))return ChatList[llgroup]->print(); if (string name{ DD::getGroupName(llgroup) };!name.empty())return "[" + name + "](" + to_string(llgroup) + ")"; return "群(" + to_string(llgroup) + ")"; } diff --git a/Dice/DiceEvent.cpp b/Dice/DiceEvent.cpp index b1949e0e..526416ba 100644 --- a/Dice/DiceEvent.cpp +++ b/Dice/DiceEvent.cpp @@ -18,17 +18,17 @@ using namespace std; static bool is_digit(char c) { return c >= '0' && c <= '9'; } -AttrVar idx_at(AttrObject& eve) { - if (eve.has("at"))return eve["at"]; - if (!eve.has("uid"))return {}; - return eve["at"] = eve.has("gid") - ? AttrVar("[CQ:at,qq=" + eve.get_str("uid") + "]") +AttrVar idx_at(const AttrObject& eve) { + if (eve->has("at"))return eve->at("at"); + if (!eve->has("uid"))return {}; + return eve->at("at") = eve->has("gid") + ? AttrVar("[CQ:at,qq=" + eve->get_str("uid") + "]") : idx_nick(eve); } -AttrVar idx_gAuth(AttrObject& eve) { - if (!eve.has("uid")|| !eve.has("gid"))return {}; - if (int auth{ DD::getGroupAuth(eve.get_ll("gid"),eve.get_ll("uid"),0) }) - return eve["grpAuth"] = auth; +AttrVar idx_gAuth(const AttrObject& eve) { + if (!eve->has("uid")|| !eve->has("gid"))return {}; + if (int auth{ DD::getGroupAuth(eve->get_ll("gid"),eve->get_ll("uid"),0) }) + return eve->at("grpAuth") = auth; return {}; } @@ -37,30 +37,30 @@ AttrGetters MsgIndexs{ {"pc", idx_pc}, {"at", idx_at}, {"@", idx_at}, - {"gender", [](AttrObject& vars) { - return vars.has("uid") ? vars["gender"] = getUserItem(vars.get_ll("uid"),"gender") : AttrVar(); + {"gender", [](const AttrObject& vars) { + return vars->has("uid") ? vars->at("gender") = getUserItem(vars->get_ll("uid"),"gender") : AttrVar(); }}, {"grpAuth", idx_gAuth}, - {"fromUser", [](AttrObject& vars) { - return vars.has("uid") ? vars["fromUser"] = vars.get_str("uid") : ""; + {"fromUser", [](const AttrObject& vars) { + return vars->has("uid") ? vars->at("fromUser") = vars->get_str("uid") : ""; }}, - {"fromQQ", [](AttrObject& vars) { - return vars.has("uid") ? vars["fromQQ"] = vars.get_str("uid") : ""; + {"fromQQ", [](const AttrObject& vars) { + return vars->has("uid") ? vars->at("fromQQ") = vars->get_str("uid") : ""; }}, - {"fromGroup", [](AttrObject& vars) { - return vars.has("gid") ? vars["fromGroup"] = vars.get_str("gid") : ""; + {"fromGroup", [](const AttrObject& vars) { + return vars->has("gid") ? vars->at("fromGroup") = vars->get_str("gid") : ""; }}, }; DiceEvent::DiceEvent(const AttrVars& var, const chatInfo& ct) - :AttrObject(var), strMsg(at("fromMsg").text), fromChat(ct) { + :AnysTable(var), strMsg(at("fromMsg").text), fromChat(ct) { if (fromChat.gid) { pGrp = &chat(fromChat.gid); } thisGame = sessions.get_if(fromChat); } -DiceEvent::DiceEvent(const AttrObject& var) - :AttrObject(var), strMsg(at("fromMsg").text) { +DiceEvent::DiceEvent(const AnysTable& var) + :AnysTable(var), strMsg(at("fromMsg").text) { fromChat = { get_ll("uid") ,get_ll("gid") ,get_ll("chid") }; if (fromChat.gid) { pGrp = &chat(fromChat.gid); @@ -159,7 +159,7 @@ void DiceEvent::replyHidden() { << GBKtoUTF8(filter_CQcode(strReply, fromChat.gid)) << endl << endl; } strReply = "在" + printChat(fromChat) + "中 " + forward_filter(strReply); - if (!pGrp || !pGrp->isset("Rh盲骰")) { + if (!pGrp || !pGrp->is("Rh盲骰")) { AddMsgToQueue(strReply, fromChat.uid); } if (thisGame) { @@ -695,12 +695,12 @@ int DiceEvent::AdminEvent(const string& strOption){ for (auto& [id, grp] : ChatList) { string strGroup; - if (grp.isset("许可使用") || grp.isset("免清") || grp.isset("免黑")) + if (grp->is("许可使用") || grp->is("免清") || grp->is("免黑")) { - strGroup = printChat(grp); - if (grp.isset("许可使用"))strGroup += "-许可使用"; - if (grp.isset("免清"))strGroup += "-免清"; - if (grp.isset("免黑"))strGroup += "-免黑"; + strGroup = grp->print(); + if (grp->is("许可使用"))strGroup += "-许可使用"; + if (grp->is("免清"))strGroup += "-免清"; + if (grp->is("免黑"))strGroup += "-免黑"; res << strGroup; } } @@ -795,7 +795,7 @@ int DiceEvent::AdminEvent(const string& strOption){ strReply = "当前白名单用户列表:"; for (auto& [uid, user] : UserList) { - if (user.nTrust)strReply += "\n" + printUser(uid) + ":" + to_string(user.nTrust); + if (user->nTrust)strReply += "\n" + printUser(uid) + ":" + to_string(user->nTrust); } reply(); return 1; @@ -960,7 +960,7 @@ int DiceEvent::MasterSet() ResList list; for (const auto& [uid, user] : UserList) { - if (user.nTrust > 3)list << printUser(uid); + if (user->nTrust > 3)list << printUser(uid); } reply(getMsg("strSelfName") + "的管理权限拥有者共" + to_string(list.size()) + "位:" + list.show()); return 1; @@ -993,7 +993,7 @@ int DiceEvent::BasicOrder() return 1; } } - if (pGrp->isset("许可使用") && !pGrp->isset("未审核") && !pGrp->isset("协议无效"))return 0; + if (pGrp->is("许可使用") && !pGrp->is("未审核") && !pGrp->is("协议无效"))return 0; string strInfo = readRest(); if (fmt->call_hook_event(merge({ {"hook","GroupAuthorize"}, @@ -1060,14 +1060,14 @@ int DiceEvent::BasicOrder() pGrp->leave(getMsg("strAdminDismiss", *this)); return 1; } - if (pGrp->isset("协议无效") && !isTarget)return 0; + if (pGrp->is("协议无效") && !isTarget)return 0; if (canRoomHost()) { pGrp->leave(getMsg("strDismiss")); } else { - if (!isCalled && (pGrp->isset("停用指令") || DD::getGroupSize(fromChat.gid).currSize > 200))AddMsgToQueue(getMsg("strPermissionDeniedErr", *this), fromChat.uid); + if (!isCalled && (pGrp->is("停用指令") || DD::getGroupSize(fromChat.gid).currSize > 200))AddMsgToQueue(getMsg("strPermissionDeniedErr", *this), fromChat.uid); else replyMsg("strPermissionDeniedErr"); } return 1; @@ -1107,7 +1107,7 @@ int DiceEvent::BasicOrder() } return 1; } - else if (!isPrivate() && pGrp->isset("协议无效")){ + else if (!isPrivate() && pGrp->is("协议无效")){ set("ignored"); return 0; } @@ -1124,7 +1124,7 @@ int DiceEvent::BasicOrder() { if (Command == "on" && !isPrivate()) { - if ((console["CheckGroupLicense"] && pGrp->isset("未审核")) || (console["CheckGroupLicense"] == 2 && !pGrp->isset("许可使用"))) + if ((console["CheckGroupLicense"] && pGrp->is("未审核")) || (console["CheckGroupLicense"] == 2 && !pGrp->is("许可使用"))) replyMsg("strGroupLicenseDeny"); else { if (canRoomHost()) @@ -1153,7 +1153,7 @@ int DiceEvent::BasicOrder() { if (groupset(fromChat.gid, "停用指令")) { - if (!isCalled && QQNum.empty() && pGrp->isGroup && DD::getGroupSize(fromChat.gid).currSize > 200)AddMsgToQueue(getMsg("strBotOffAlready", *this), fromChat.uid); + if (!isCalled && QQNum.empty() && DD::getGroupSize(fromChat.gid).currSize > 200)AddMsgToQueue(getMsg("strBotOffAlready", *this), fromChat.uid); else replyMsg("strBotOffAlready"); } else @@ -1168,11 +1168,11 @@ int DiceEvent::BasicOrder() else replyMsg("strPermissionDeniedErr"); } } - else if (!Command.empty() && !isCalled && pGrp->isset("停用指令")) + else if (!Command.empty() && !isCalled && pGrp->is("停用指令")) { return 0; } - else if (!isPrivate() && pGrp->isset("停用指令") && DD::getGroupSize(fromChat.gid).currSize > 500 && !isCalled) + else if (!isPrivate() && pGrp->is("停用指令") && DD::getGroupSize(fromChat.gid).currSize > 500 && !isCalled) { AddMsgToQueue(getMsg("strBotHeader") + Dice_Full_Ver_On + getMsg("strBotMsg"), fromChat.uid); } @@ -1194,7 +1194,7 @@ int DiceEvent::BasicOrder() string action{ readPara() }; if (action == "on" && fromChat.gid) { const string& option{ (at("option") = "禁用回复").text }; - if (!chat(fromChat.gid).isset(option)) { + if (!chat(fromChat.gid).is(option)) { replyMsg("strGroupSetOffAlready"); } else if (trusted > 0 || canRoomHost()) { @@ -1208,7 +1208,7 @@ int DiceEvent::BasicOrder() } else if (action == "off" && fromChat.gid) { const string& option{ (at("option") = "禁用回复").text }; - if (chat(fromChat.gid).isset(option)) { + if (chat(fromChat.gid).is(option)) { replyMsg("strGroupSetOnAlready"); } else if (trusted > 0 || canRoomHost()) { @@ -1288,7 +1288,7 @@ int DiceEvent::BasicOrder() while (intMsgCnt < strMsg.length()) { deck.push_back(readItem()); } - trigger->answer = AttrObject(deck); + trigger->answer = AnysTable(deck); } else { if (trigger->echo == DiceMsgReply::Echo::Lua) { @@ -1590,7 +1590,7 @@ int DiceEvent::BasicOrder() set("set_item", strItem); if (!strVal.empty()) { AttrVar& val{ at("set_val") = AttrVar::parse(strVal) }; - thisGame->setAttr(strItem, val); + thisGame->set(strItem, val); replyMsg("strGameItemSet"); } else { @@ -1744,7 +1744,7 @@ int DiceEvent::InnerOrder() { if (canRoomHost()) { string strWelcomeMsg = strMsg.substr(intMsgCnt); if (strWelcomeMsg == "clr") { - if (chat(fromChat.gid).isset("入群欢迎")) { + if (chat(fromChat.gid).is("入群欢迎")) { chat(fromChat.gid).reset("入群欢迎"); replyMsg("strWelcomeMsgClearNotice"); } @@ -1753,7 +1753,7 @@ int DiceEvent::InnerOrder() { } } else if (strWelcomeMsg == "show") { - string strWelcome{ chat(fromChat.gid).confs.get_str("入群欢迎") }; + string strWelcome{ chat(fromChat.gid).get_str("入群欢迎") }; if (strWelcome.empty())replyMsg("strWelcomeMsgEmpty"); else reply(strWelcome, false); //转义有注入风险 } @@ -1801,15 +1801,15 @@ int DiceEvent::InnerOrder() { string action{ readPara() }; if (action == "show") { if ((thisGame || (thisGame = sessions.get_if(fromChat))) - && thisGame->attrs.has("rr_rc")) { + && thisGame->has("rr_rc")) { set("rule", thisGame->getAttr("rr_rc")); } else if (isPrivate()) { - if (User& user{ getUser(fromChat.uid) }; user.isset("rc房规")) - set("rule", user.confs["rc房规"]); + if (User& user{ getUser(fromChat.uid) }; user.is("rc房规")) + set("rule", user.get("rc房规")); } - else if (pGrp->isset("rc房规")) { - set("rule", pGrp->confs["rc房规"]); + else if (pGrp->is("rc房规")) { + set("rule", pGrp->get("rc房规")); } if (has("rule")) { replyMsg("strDefaultCOCShow"); @@ -1822,8 +1822,8 @@ int DiceEvent::InnerOrder() { } else if (action == "clr") { if (thisGame - && thisGame->attrs.has("rr_rc")) { - thisGame->rmAttr("rr_rc"); + && thisGame->has("rr_rc")) { + thisGame->reset("rr_rc"); } else if (isPrivate())getUser(fromChat.uid).rmConf("rc房规"); else chat(fromChat.gid).reset("rc房规"); @@ -2040,8 +2040,8 @@ int DiceEvent::InnerOrder() { int Cnt = 0; if (isSet) { for (auto& [id, grp] : ChatList) { - if (grp.isset(strOption))continue; - grp.set(strOption); + if (grp->is(strOption))continue; + grp->set(strOption); Cnt++; } set("cnt", Cnt); @@ -2049,8 +2049,8 @@ int DiceEvent::InnerOrder() { } else { for (auto& [id, grp] : ChatList) { - if (!grp.isset(strOption))continue; - grp.reset(strOption); + if (!grp->is(strOption))continue; + grp->reset(strOption); Cnt++; } set("cnt", Cnt); @@ -2100,7 +2100,7 @@ int DiceEvent::InnerOrder() { replyMsg("strGroupSetOnAlready"); } } - else if (grp.isset(get_str("option"))) { + else if (grp.is(get_str("option"))) { ++cntSet; chat(llGroup).reset(get_str("option")); } @@ -2135,11 +2135,11 @@ int DiceEvent::InnerOrder() { res << "记录创建:" + printDate(grp.tCreated); res << "最后记录:" + printDate(grp.updated()); if (grp.inviter)res << "邀请者:" + printUser(grp.inviter); - res << string("入群欢迎:") + (grp.isset("入群欢迎") ? "已设置" : "无"); + res << string("入群欢迎:") + (grp.is("入群欢迎") ? "已设置" : "无"); reply(getMsg("strSelfName") + res.show()); return 1; } - if (!grp.isGroup || (fromChat.gid == llGroup && isPrivate())) { + if (fromChat.gid == llGroup && isPrivate()) { replyMsg("strGroupNot"); return 1; } @@ -2153,7 +2153,7 @@ int DiceEvent::InnerOrder() { return 1; } if (ChatList.count(llGroup)) { - reply(UTF8toGBK(chat(llGroup).confs.to_json().dump()), false); + reply(UTF8toGBK(chat(llGroup).to_json().dump()), false); } else { reply("{self}无" + printGroup(llGroup) + "的群聊记录×"); @@ -2412,8 +2412,8 @@ int DiceEvent::InnerOrder() { if (auto rule{ getGameRule() }; GetRule::get(*rule, strSearch, strReply)) { reply(); } - else if (getUser(fromChat.uid).isset("默认规则") && strSearch.find(':') == string::npos && - GetRule::get(getUser(fromChat.uid).confs.get_str("默认规则"), strSearch, strReply)) { + else if (getUser(fromChat.uid).is("默认规则") && strSearch.find(':') == string::npos && + GetRule::get(getUser(fromChat.uid).get_str("默认规则"), strSearch, strReply)) { reply(); } else if (GetRule::analyze(strSearch, strReply)) { @@ -2575,7 +2575,7 @@ int DiceEvent::InnerOrder() { if (strCmd.empty()|| isPrivate()) { replyHelp("init"); } - else if (!thisGame || !thisGame->table_count("先攻")) { + else if (!thisGame || !thisGame->has("先攻")) { replyMsg("strGMTableNotExist"); } else if (strCmd == "show" || strCmd == "list") { @@ -2718,7 +2718,7 @@ int DiceEvent::InnerOrder() { } else { AddMsgToQueue(fmt->format(strFwd, ct.gid ? - AttrVars{ {"gid",ct.gid}} : AttrVars{ {"uid",ct.uid} }), ct); + AnysTable{ {"gid",ct.gid}} : AnysTable{ {"uid",ct.uid} }), ct); replyMsg("strSendMsg"); } return 1; @@ -2824,7 +2824,7 @@ int DiceEvent::InnerOrder() { long long target{ readID() }; if (!target)target = fromChat.uid; if(UserList.count(target)){ - reply(UTF8toGBK(getUser(target).confs.to_json().dump()), false); + reply(UTF8toGBK(getUser(target).to_json().dump()), false); } else { reply("{self}无" + printUser(target) + "的用户记录×"); @@ -3088,7 +3088,7 @@ int DiceEvent::InnerOrder() { s->get_deck().erase("__Ank"); if (string strTitle{ strMsg.substr(intMsgCnt,strMsg.find('+') - intMsgCnt) }; !strTitle.empty()) { intMsgCnt += strTitle.length(); - s->setAttr("AkFork", at("fork") = strTitle); + s->set("AkFork", at("fork") = strTitle); } if (intMsgCnt == strMsg.length()) { replyMsg("strAkForkNew"); @@ -3104,7 +3104,7 @@ int DiceEvent::InnerOrder() { replyMsg("strAkAddEmpty"); return 1; } - set("fork",s->attrs["AkFork"]); + set("fork",s->at("AkFork")); ResList list; list.order(); for (auto& val : deck) { @@ -3123,7 +3123,7 @@ int DiceEvent::InnerOrder() { return 1; } deck.erase(deck.begin() + nNo - 1); - set("fork",s->attrs["AkFork"]); + set("fork",s->get("AkFork")); ResList list; list.order(); for (auto& val : deck) { @@ -3135,8 +3135,8 @@ int DiceEvent::InnerOrder() { } else if (sign == '=' || action == "get") { if (DeckInfo& deck{ s->get_deck("__Ank") }; !deck.meta.empty()) { - set("fork",s->attrs["AkFork"]); - s->rmAttr("AkFork"); + set("fork",s->at("AkFork")); + s->reset("AkFork"); size_t res{ (size_t)RandomGenerator::Randint(0,deck.meta.size() - 1) }; set("get",to_string(res + 1) + ". " + deck.meta[res]); ResList list; @@ -3155,7 +3155,7 @@ int DiceEvent::InnerOrder() { } else if (action == "show") { std::vector& deck{ s->get_deck("__Ank").meta }; - set("fork",s->attrs["AkFork"]); + set("fork",s->at("AkFork")); ResList list; list.order(); for (auto& val : deck) { @@ -3166,8 +3166,8 @@ int DiceEvent::InnerOrder() { } else if (action == "clr") { s->get_deck().erase("__Ank"); - set("fork",s->attrs["AkFork"]); - s->rmAttr("AkFork"); + set("fork",s->at("AkFork")); + s->reset("AkFork"); replyMsg("strAkClr"); s->update(); } @@ -4498,7 +4498,7 @@ bool DiceEvent::DiceFilter() { isCalled = isSummoned = true; } - else if (User& self{ getUser(console.DiceMaid) }; self.isset("tinyID") && self.confs["tinyID"] == strTarget) + else if (User& self{ getUser(console.DiceMaid) }; self.has("tinyID") && self.get_str("tinyID") == strTarget) { isCalled = isSummoned = true; } @@ -4526,7 +4526,7 @@ bool DiceEvent::DiceFilter() if (int chon{ (isChannel() && pGrp) ? pGrp->getChConf(fromChat.chid,"order",0) : 0 }) { set("order_off",chon < 0); } - else if (pGrp && pGrp->isset("停用指令")) { + else if (pGrp && pGrp->is("停用指令")) { set("order_off"); } } @@ -4535,8 +4535,8 @@ bool DiceEvent::DiceFilter() } else if (is("ignored"))return 0; if (isCalled)set("called"); - if (!isPrivate() && ((console["CheckGroupLicense"] > 0 && pGrp->isset("未审核")) - || (console["CheckGroupLicense"] == 2 && !pGrp->isset("许可使用")) + if (!isPrivate() && ((console["CheckGroupLicense"] > 0 && pGrp->is("未审核")) + || (console["CheckGroupLicense"] == 2 && !pGrp->is("许可使用")) || blacklist->get_group_danger(fromChat.gid))) { isDisabled = true; } @@ -4547,7 +4547,7 @@ bool DiceEvent::DiceFilter() if (auto ruleName{ getGameRule() }; ruleName && (thisGame->is_part(fromChat.uid)) && ruleset->has_rule(*ruleName) - && ((thisGame->attrs.has("tape") && ruleset->get_rule(*ruleName)->listen_cassette(thisGame->attrs.get_str("tape"), this)) + && ((thisGame->has("tape") && ruleset->get_rule(*ruleName)->listen_cassette(thisGame->get_str("tape"), this)) || ruleset->get_rule(*ruleName)->listen_order(this))) { return monitorFrq(); } @@ -4609,8 +4609,8 @@ void DiceEvent::virtualCall() { DiceFilter(); } std::optional DiceEvent::getGameRule() { - if (thisGame && thisGame->attrs.has("rule")) { - return thisGame->attrs.get_str("rule"); + if (thisGame && thisGame->has("rule")) { + return thisGame->get_str("rule"); } return std::nullopt; } @@ -4797,10 +4797,10 @@ void reply(AttrObject& msg, string strReply, bool isFormat) { while (isspace(static_cast(strReply[0]))) strReply.erase(strReply.begin()); if(isFormat)strReply = fmt->format(strReply, msg); - if (console["ReferMsgReply"] && msg.get_int("msgid"))strReply = "[CQ:reply,id=" + msg.get_str("msgid") + "]" + strReply; - long long uid{ msg.get_ll("uid") }; - long long gid{ msg.get_ll("gid") }; - long long chid{ msg.get_ll("chid") }; + if (console["ReferMsgReply"] && msg->get_int("msgid"))strReply = "[CQ:reply,id=" + msg->get_str("msgid") + "]" + strReply; + long long uid{ msg->get_ll("uid") }; + long long gid{ msg->get_ll("gid") }; + long long chid{ msg->get_ll("chid") }; if (uid || gid || chid) AddMsgToQueue(strReply, chatInfo{ uid,gid,chid }); } @@ -4808,10 +4808,10 @@ void MsgNote(AttrObject& msg, string strReply, int note_lv) { while (isspace(static_cast(strReply[0]))) strReply.erase(strReply.begin()); strReply = fmt->format(strReply, msg); - if (console["ReferMsgReply"] && msg.get_int("msgid"))strReply = "[CQ:reply,id=" + msg.get_str("msgid") + "]" + strReply; - long long uid{ msg.get_ll("uid") }; - long long gid{ msg.get_ll("gid") }; - long long chid{ msg.get_ll("chid") }; + if (console["ReferMsgReply"] && msg->get_int("msgid"))strReply = "[CQ:reply,id=" + msg->get_str("msgid") + "]" + strReply; + long long uid{ msg->get_ll("uid") }; + long long gid{ msg->get_ll("gid") }; + long long chid{ msg->get_ll("chid") }; if (uid || gid || chid) AddMsgToQueue(strReply, chatInfo{ uid,gid,chid }); strReply = getName(uid) + strReply; diff --git a/Dice/DiceEvent.h b/Dice/DiceEvent.h index 1d818b23..6a1cc7f6 100644 --- a/Dice/DiceEvent.h +++ b/Dice/DiceEvent.h @@ -20,7 +20,7 @@ class RD; class DiceSession; //打包待处理消息 -class DiceEvent : public AttrObject { +class DiceEvent : public AnysTable { public: chatInfo fromChat; string strLowerMessage; @@ -30,10 +30,7 @@ class DiceEvent : public AttrObject { string strReply; std::wsmatch msgMatch; DiceEvent(const AttrVars& var, const chatInfo& ct); - DiceEvent(const AttrObject& var); - AttrVar& operator[](const char* key) { - return (*dict)[key]; - } + DiceEvent(const AnysTable& var); bool isPrivate()const; bool isChannel()const; diff --git a/Dice/DiceFile.cpp b/Dice/DiceFile.cpp index ccfc9cd7..06761133 100644 --- a/Dice/DiceFile.cpp +++ b/Dice/DiceFile.cpp @@ -150,11 +150,6 @@ ifstream& operator>>(ifstream& fin, User& user) { return fin; } -ifstream& operator>>(ifstream& fin, Chat& grp) { - fin >> grp.ID >> grp.isGroup >> grp.inviter >> grp.tCreated >> tUpdated; - return fin; -} - template int _listDir(const std::filesystem::path& dir, vector& files) { diff --git a/Dice/DiceFile.hpp b/Dice/DiceFile.hpp index 27ae5834..a54052e2 100644 --- a/Dice/DiceFile.hpp +++ b/Dice/DiceFile.hpp @@ -318,22 +318,27 @@ int loadFile(const std::filesystem::path& fpPath, nlohmann::fifo_map& ma } template -int loadBFile(const std::filesystem::path& fpPath, std::map& m) +int loadBFile(const std::filesystem::path& fpPath, std::unordered_map>& m) { std::ifstream fin(fpPath, std::ios::in | std::ios::binary); if (!fin)return -1; - const int len = fread(fin); int Cnt = 0; - T key; - while (fin.peek() != EOF && len > Cnt++) - { - key = fread(fin); - m[key] = fread(fin); + try { + const int len = fread(fin); + T key; + while (fin.peek() != EOF && len > Cnt++) + { + key = fread(fin); + m.emplace(key, std::make_shared(key)); + ((*m[key]).*U)(fin); + } + } + catch (...) { + } fin.close(); return Cnt; } - template int loadBFile(const std::filesystem::path& fpPath, std::unordered_map& m) { @@ -657,7 +662,7 @@ void saveBFile(const std::filesystem::path& fpPath, std::unordered_map& m) } template -void saveBFile(const std::filesystem::path& fpPath, std::unordered_map& m) +void saveBFile(const std::filesystem::path& fpPath, std::unordered_map>& m) { if (clrEmpty(fpPath, m))return; std::ofstream fout(fpPath, ios::out | ios::trunc | ios::binary); @@ -666,7 +671,7 @@ void saveBFile(const std::filesystem::path& fpPath, std::unordered_map& m) for (auto& [key, val] : m) { fwrite(fout, key); - fwrite(fout, val); + val->writeb(fout); } fout.close(); } diff --git a/Dice/DiceGUI.cpp b/Dice/DiceGUI.cpp index 73bb1dd8..3c14c7cd 100644 --- a/Dice/DiceGUI.cpp +++ b/Dice/DiceGUI.cpp @@ -732,7 +732,7 @@ LRESULT DiceGUI::HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam) MessageBox(m_hwnd, TEXT("信任等级无效!"), TEXT("Dice! GUI"), MB_OK | MB_ICONWARNING); return 0; } - UserList[uid].trust(trustlevel); + UserList[uid]->trust(trustlevel); if (ret == -1) { @@ -942,7 +942,7 @@ LRESULT DiceGUI::CreateMasterPage() for (const auto& item : UserList) { const string qq = to_string(item.first); - const string trust = to_string(item.second.nTrust); + const string trust = to_string(item.second->nTrust); const string nick = nicknameMp[item.first]; ListViewUserTrust.AddTextRow({qq, nick, trust}, index); index++; @@ -1149,7 +1149,7 @@ int WINAPI GUIMain() time_t tLimit{ time(NULL) - (time_t)86400 * 7 }; for (const auto& item : UserList) { - if (LoadActiveUser && item.second.updated() < tLimit)continue; + if (LoadActiveUser && item.second->updated() < tLimit)continue; if (FriendMp.count(item.first) || LoadStranger) { nicknameMp[item.first] = DD::getQQNick(item.first); } diff --git a/Dice/DiceJS.cpp b/Dice/DiceJS.cpp index ee189ba9..f5951876 100644 --- a/Dice/DiceJS.cpp +++ b/Dice/DiceJS.cpp @@ -150,7 +150,7 @@ AttrVar js_toAttr(JSContext* ctx, JSValue val) { auto len = (uint32_t)JS_VALUE_GET_INT(JS_GetPropertyStr(ctx, val, "length")); for (uint32_t i = 0; i < len; i++) ary.emplace_back(js_toAttr(ctx, JS_GetPropertyUint32(ctx,val,i))); - return AttrObject(ary); + return AnysTable(ary); } else { AttrObject obj; @@ -158,7 +158,7 @@ AttrVar js_toAttr(JSContext* ctx, JSValue val) { uint32_t len = 0; if (!JS_GetOwnPropertyNames(ctx, &tab, &len, val, JS_GPN_ENUM_ONLY | JS_GPN_STRING_MASK)) { for (uint32_t i = 0; i < len; ++i) { - obj.set(js_AtomtoGBK(ctx, tab[i].atom), js_toAttr(ctx, JS_GetProperty(ctx, val, tab[i].atom))); + obj->set(js_AtomtoGBK(ctx, tab[i].atom), js_toAttr(ctx, JS_GetProperty(ctx, val, tab[i].atom))); } js_free_prop_enum(ctx, tab, len); } @@ -191,23 +191,23 @@ JSValue js_newAttr(JSContext* ctx, const AttrVar& var) { return JS_NewString(ctx, GBKtoUTF8(var.text).c_str()); break; case AttrVar::Type::Table: - if (!var.table.to_dict()->empty()) { + if (!var.table->as_dict().empty()) { auto dict = JS_NewObject(ctx); - if (var.table.to_list()) { + if (var.table->to_list()) { uint32_t idx{ 0 }; - for (auto& val : *var.table.to_list()) { + for (auto& val : *var.table->to_list()) { JS_SetPropertyUint32(ctx, dict, idx++, js_newAttr(ctx, val)); } } - for (auto& [key, val] : *var.table.to_dict()) { + for (auto& [key, val] : var.table->as_dict()) { JS_SetPropertyStr(ctx, dict, GBKtoUTF8(key).c_str(), js_newAttr(ctx, val)); } return dict; } - else if (var.table.to_list()) { + else if (var.table->to_list()) { auto ary = JS_NewArray(ctx); uint32_t idx{ 0 }; - for (auto& val : *var.table.to_list()) { + for (auto& val : *var.table->to_list()) { JS_SetPropertyUint32(ctx, ary, idx++, js_newAttr(ctx, val)); } return ary; @@ -465,11 +465,11 @@ QJSDEF(eventMsg) { long long gid{ JS_IsUndefined(argv[1]) ? 0 : js_toLongLong(ctx, argv[1]) }, uid{ JS_IsUndefined(argv[2]) ? 0 : js_toLongLong(ctx, argv[2]) }; eve = gid - ? AttrVars{ {"fromMsg",fromMsg},{"gid",gid}, {"uid", uid} } - : AttrVars{ {"fromMsg",fromMsg}, {"uid", uid} }; + ? AnysTable{ {{"fromMsg",fromMsg},{"gid",gid}, {"uid", uid}} } + : AnysTable{ {{"fromMsg",fromMsg}, {"uid", uid}} }; } std::thread th([=]() { - DiceEvent(eve).virtualCall(); + DiceEvent(*eve.p).virtualCall(); }); th.detach(); return JS_TRUE; @@ -478,8 +478,8 @@ QJSDEF(sendMsg) { AttrObject chat; if (JS_IsObject(argv[0])) { chat = js_toAttr(ctx, argv[0]).to_obj(); - AddMsgToQueue(fmt->format(chat.get_str("fwdMsg"), chat), - chatInfo{ chat.get_ll("uid") ,chat.get_ll("gid") ,chat.get_ll("chid") }); + AddMsgToQueue(fmt->format(chat->get_str("fwdMsg"), chat), + chatInfo{ chat->get_ll("uid") ,chat->get_ll("gid") ,chat->get_ll("chid") }); } else { long long gid{ JS_IsUndefined(argv[1]) ? 0 : js_toLongLong(ctx, argv[1]) }, @@ -489,8 +489,8 @@ QJSDEF(sendMsg) { return JS_EXCEPTION; } string msg{ js_toGBK(ctx, argv[0]) }; - if (uid)chat.set("uid", uid); - if (gid)chat.set("gid", gid); + if (uid)chat->set("uid", uid); + if (gid)chat->set("gid", gid); AddMsgToQueue(fmt->format(msg, chat), { uid,gid,0 }); } return JS_TRUE; @@ -505,12 +505,12 @@ QJSDEF(getGroupAttr) { } auto items{ JS_NewArray(ctx) }; for (auto& [gid, data] : ChatList) { - if (data.confs.has(item))JS_SetPropertyInt64(ctx, items, (int64_t)gid, js_newAttr(ctx, data.confs.get(item))); + if (data->has(item))JS_SetPropertyInt64(ctx, items, (int64_t)gid, js_newAttr(ctx, data->get(item))); } return items; } if (long long gid{ js_toLongLong(ctx,argv[0]) }) { - if (item.empty()) return js_newDiceContext(ctx, chat(gid).confs); + if (item.empty()) return js_newDiceContext(ctx, chat(gid).shared_from_this()); else if (item == "members") { auto items{ JS_NewArray(ctx) }; uint32_t i = 0; @@ -597,12 +597,12 @@ QJSDEF(getUserAttr) { } auto items{ JS_NewArray(ctx) }; for (auto& [id, data] : UserList) { - if (data.confs.has(item))JS_SetPropertyInt64(ctx, items, (int64_t)id, js_newAttr(ctx, data.confs.get(item))); + if (data->has(item))JS_SetPropertyInt64(ctx, items, (int64_t)id, js_newAttr(ctx, data->get(item))); } return items; } if (long long uid{ js_toLongLong(ctx,argv[0]) }) { - if (item.empty()) return js_newDiceContext(ctx, getUser(uid).confs); + if (item.empty()) return js_newDiceContext(ctx, getUser(uid).shared_from_this()); if (auto val{ getUserItem(uid,item) }; !val.is_null())return js_newAttr(ctx, val); else return argv[2]; } @@ -656,7 +656,7 @@ QJSDEF(getUserToday) { } auto items{ JS_NewArray(ctx) }; for (auto& [uid, data] : today->getUserInfo()) { - if (data.has(item))JS_SetPropertyInt64(ctx, items, (int64_t)uid, js_newAttr(ctx, data.get(item))); + if (data->has(item))JS_SetPropertyInt64(ctx, items, (int64_t)uid, js_newAttr(ctx, data->get(item))); } return items; } @@ -717,17 +717,17 @@ int js_dice_context_get_own(JSContext* ctx, JSPropertyDescriptor* desc, JSValueC JS2OBJ(this_val); if (desc) { string key{ js_AtomtoGBK(ctx, prop) }; - if (key == "user" && obj.has("uid")) { - desc->value = js_newDiceContext(ctx, getUser(obj.get_ll("uid")).confs); + if (key == "user" && obj->has("uid")) { + desc->value = js_newDiceContext(ctx, getUser(obj->get_ll("uid")).shared_from_this()); } - else if ((key == "grp" || key == "group") && obj.has("gid")) { - desc->value = js_newDiceContext(ctx, chat(obj.get_ll("gid")).confs); + else if ((key == "grp" || key == "group") && obj->has("gid")) { + desc->value = js_newDiceContext(ctx, chat(obj->get_ll("gid")).shared_from_this()); } - else if (key == "pc" && obj.has("uid")) { - desc->value = js_newActor(ctx, getPlayer(obj.get_ll("uid"))[obj.get_ll("gid")]); + else if (key == "pc" && obj->has("uid")) { + desc->value = js_newActor(ctx, getPlayer(obj->get_ll("uid"))[obj->get_ll("gid")]); } else if (key == "game") { - if (auto game = sessions.get_if(obj)) { + if (auto game = sessions.get_if(*obj)) { desc->value = js_newGameTable(ctx, game); } else return FALSE; @@ -748,7 +748,7 @@ int js_dice_context_get_keys(JSContext* ctx, JSPropertyEnum** ptab, uint32_t* pl if ((*plen = obj->size()) > 0) { JSPropertyEnum* tab = (JSPropertyEnum*)js_malloc(ctx, sizeof(JSPropertyEnum) * (*plen)); int i = 0; - for (const auto& [key, val] : *obj.to_dict()) { + for (const auto& [key, val] : obj->as_dict()) { if (auto atom = JS_NewAtom(ctx, GBKtoUTF8(key).c_str()); atom != JS_ATOM_NULL) { DD::debugLog("newAtom:" + js_AtomtoGBK(ctx, atom) + "#" + to_string(atom)); @@ -767,13 +767,13 @@ int js_dice_context_get_keys(JSContext* ctx, JSPropertyEnum** ptab, uint32_t* pl } int js_dice_context_delete(JSContext* ctx, JSValue this_val, JSAtom atom) { JS2OBJ(this_val); - obj.reset(js_AtomtoGBK(ctx, atom)); + obj->reset(js_AtomtoGBK(ctx, atom)); return TRUE; } int js_dice_context_define(JSContext* ctx, JSValueConst this_obj, JSAtom prop, JSValueConst val, JSValueConst getter, JSValueConst setter, int flags) { JS2OBJ(this_obj); auto str = js_AtomtoGBK(ctx, prop); - obj.set(str, js_toAttr(ctx, val)); + obj->set(str, js_toAttr(ctx, val)); return TRUE; } QJSDEF(context_get) { @@ -816,9 +816,9 @@ QJSDEF(context_inc) { JS2OBJ(this_val); if (argc > 0) { string key{ js_toGBK(ctx, argv[0]) }; - return obj.inc(key) ? js_newAttr(ctx, obj.get(key)) + return obj->inc(key) ? js_newAttr(ctx, obj->get(key)) : (argc > 1 ? argv[1] : JS_UNDEFINED); - return argc > 1 ? obj.inc(key, js_toInt(ctx, argv[1])) : obj.inc(key); + return argc > 1 ? obj->inc(key, js_toInt(ctx, argv[1])) : obj->inc(key); } else { JS_ThrowTypeError(ctx, "undefined field"); @@ -851,9 +851,9 @@ int js_dice_selfdata_get_own(JSContext* ctx, JSPropertyDescriptor* desc, JSValue JS2DATA(this_val); if (data && desc) { string key{ js_AtomtoGBK(ctx, prop) }; - if (data->data.to_dict()->count(key)) { + if (data->data.to_obj()->has(key)) { desc->flags = JS_PROP_C_W_E; - desc->value = js_newAttr(ctx, data->data.to_obj().get(key)); + desc->value = js_newAttr(ctx, data->data.to_obj()->get(key)); desc->getter = JS_UNDEFINED; desc->setter = JS_UNDEFINED; return TRUE; @@ -865,7 +865,7 @@ int js_dice_selfdata_delete(JSContext* ctx, JSValue this_val, JSAtom atom) { JS2DATA(this_val); if (data) { auto str = js_AtomtoGBK(ctx, atom); - data->data.to_obj().reset(str); + data->data.to_obj()->reset(str); data->save(); return TRUE; } @@ -878,7 +878,7 @@ int js_dice_selfdata_define(JSContext* ctx, JSValueConst this_obj, JS2DATA(this_obj); if (data) { auto str = js_AtomtoGBK(ctx, prop); - data->data.to_obj().set(str, js_toAttr(ctx, val)); + data->data.to_obj()->set(str, js_toAttr(ctx, val)); data->save(); return TRUE; } @@ -888,7 +888,7 @@ int js_dice_selfdata_set(JSContext* ctx, JSValueConst obj, JSAtom atom, JSValueC JS2DATA(obj); if (data) { auto str = js_AtomtoGBK(ctx, atom); - data->data.to_obj().set(str, js_toAttr(ctx, value)); + data->data.to_obj()->set(str, js_toAttr(ctx, value)); data->save(); return TRUE; } @@ -931,8 +931,8 @@ int js_dice_GameTable_get_own(JSContext* ctx, JSPropertyDescriptor* desc, JSValu desc->setter = JS_UNDEFINED; return TRUE; } - else if (game->attrs.has(key)) { - desc->value = js_newAttr(ctx, game->attrs.get(key)); + else if (game->has(key)) { + desc->value = js_newAttr(ctx, game->get(key)); } else return FALSE; } @@ -946,7 +946,7 @@ int js_dice_GameTable_delete(JSContext* ctx, JSValue obj, JSAtom atom) { JS2GAME(obj); if (game) { auto str = js_AtomtoGBK(ctx, atom); - game->rmAttr(str); + game->reset(str); return TRUE; } return FALSE; @@ -955,7 +955,7 @@ int js_dice_GameTable_define(JSContext* ctx, JSValueConst this_obj, JSAtom prop, JS2GAME(this_obj); if (game) { auto str = js_AtomtoGBK(ctx, prop); - game->setAttr(str, js_toAttr(ctx, val)); + game->set(str, js_toAttr(ctx, val)); return TRUE; } return FALSE; @@ -995,7 +995,7 @@ int js_dice_actor_get_keys(JSContext* ctx, JSPropertyEnum** ptab, uint32_t* plen if ((*plen = pc->size() - 3) > 0) { JSPropertyEnum* tab = (JSPropertyEnum*)js_malloc(ctx, sizeof(JSPropertyEnum) * (*plen)); int i = 0; - for (const auto& [key, val] : *pc->to_dict()) { + for (const auto& [key, val] : pc->as_dict()) { if (prop_desc.count(key)) { continue; } @@ -1096,8 +1096,8 @@ AttrVar js_context_eval(const std::string& s, const AttrObject& context) { return {}; } -bool js_call_event(AttrObject eve, const AttrVar& action) { - string title{ eve.has("hook") ? eve.get_str("hook") : eve.get_str("Event") }; +bool js_call_event(const AttrObject& eve, const AttrVar& action) { + string title{ eve->has("hook") ? eve->get_str("hook") : eve->get_str("Event") }; string script{ action.to_str() }; bool isFile{ action.is_character() && fmt->has_js(script) }; if (auto ret = isFile ? js_event_pool[title].evalFileLocal(fmt->js_path(script), eve) diff --git a/Dice/DiceJS.h b/Dice/DiceJS.h index 4c420f15..e357afd0 100644 --- a/Dice/DiceJS.h +++ b/Dice/DiceJS.h @@ -8,7 +8,7 @@ * * Dice! QQ Dice Robot for TRPG * CoJSright (C) 2018-2021 w4123溯洄 - * CoJSright (C) 2019-2023 String.Empty + * CoJSright (C) 2019-2024 String.Empty * * This program is free software: you can redistribute it and/or modify it under the terms * of the GNU Affero General Public License as published by the Free Software Foundation, @@ -44,7 +44,7 @@ class js_context { JSValue js_newAttr(JSContext*, const AttrVar& var); void js_global_init(); void js_global_end(); -bool js_call_event(AttrObject, const AttrVar&); +bool js_call_event(const AttrObject&, const AttrVar&); void js_msg_call(DiceEvent*, const AttrVar&); AttrVar js_simple_eval(const std::string&); AttrVar js_context_eval(const std::string&, const AttrObject& context); \ No newline at end of file diff --git a/Dice/DiceJob.cpp b/Dice/DiceJob.cpp index 06ed648c..78353dde 100644 --- a/Dice/DiceJob.cpp +++ b/Dice/DiceJob.cpp @@ -53,7 +53,7 @@ inline PROCESSENTRY32 getProcess(int pid) { void frame_restart(AttrObject& job) { #ifdef _WIN32 - if (!job.get_ll("uid")) { + if (!job->get_ll("uid")) { if (console["AutoFrameRemake"] <= 0) { sch.add_job_for(60 * 60, job); return; @@ -153,7 +153,7 @@ void auto_save(AttrObject& job) { //被引用的图片列表 void clear_image(AttrObject& job) { return; - if (!job.has("uid")) { + if (!job->has("uid")) { if (sch.is_job_cold("clrimage"))return; if (console["AutoClearImage"] <= 0) { sch.add_job_for(60 * 60, job); @@ -173,16 +173,16 @@ void clear_group(AttrObject& job) { ResList res; vector GrpDelete; time_t grpline{ console["InactiveGroupLine"] > 0 ? (tNow - console["InactiveGroupLine"] * (time_t)86400) : 0 }; - if (string mode{ job.get_str("clear_mode") };mode == "unpower") { + if (string mode{ job->get_str("clear_mode") };mode == "unpower") { for (auto& [id, grp] : ChatList) { - if (grp.isset("忽略") || !grp.getLst() || grp.isset("免清") || grp.isset("协议无效"))continue; - if (grp.isGroup && !DD::isGroupAdmin(id, console.DiceMaid, true)) { + if (grp->is("忽略") || !grp->getLst() || grp->is("免清") || grp->is("协议无效"))continue; + if (!DD::isGroupAdmin(id, console.DiceMaid, true)) { res << printGroup(id); - time_t tLast{ grp.updated() }; + time_t tLast{ grp->updated() }; if (auto s{ sessions.get_if({ 0,id }) }) tLast = s->tUpdate > tLast ? s->tUpdate : tLast; if (tLast < grpline)GrpDelete.push_back(id); - grp.leave(getMsg("strLeaveNoPower")); + grp->leave(getMsg("strLeaveNoPower")); intCnt++; if (console["GroupClearLimit"] > 0 && intCnt >= console["GroupClearLimit"])break; this_thread::sleep_for(3s); @@ -191,23 +191,23 @@ void clear_group(AttrObject& job) { MsgNote(job, "筛除{strSelfName}非群管群聊" + to_string(intCnt) + "个:" + res.show(), 0b10); } else if (!mode.empty() && isdigit(static_cast(mode[0]))) { - int intDayLim{ job.get_int("clear_mode") }; + int intDayLim{ job->get_int("clear_mode") }; time_t tNow{ time(nullptr) }; for (auto& [id, grp] : ChatList) { - if (grp.isset("忽略") || grp.isset("免清") || grp.isset("协议无效"))continue; - time_t tLast{ grp.getLst() }; + if (grp->is("忽略") || grp->is("免清") || grp->is("协议无效"))continue; + time_t tLast{ grp->getLst() }; if (auto s{ sessions.get_if({ 0,id }) };s && s->tUpdate > tLast) tLast = s->tUpdate; if (tNow - 86400LL * intDayLim < tLast)continue; if (long long tLMT{ DD::getGroupLastMsg(id, console.DiceMaid) }; - tLMT > tLast)grp.setLst(tLast = tLMT); + tLMT > tLast)grp->setLst(tLast = tLMT); if (tLast <= 0)continue; - if (tLast < grpline && !grp.isset("免黑"))GrpDelete.push_back(id); + if (tLast < grpline && !grp->is("免黑"))GrpDelete.push_back(id); int intDay{ int((tNow - tLast) / 86400) }; if (intDay > intDayLim) { - job["day"] = to_string(intDay); + job->at("day") = to_string(intDay); res << printGroup(id) + ":" + to_string(intDay) + "天\n"; - grp.leave(getMsg("strLeaveUnused", job)); + grp->leave(getMsg("strLeaveUnused", job)); intCnt++; if (console["GroupClearLimit"] > 0 && intCnt >= console["GroupClearLimit"])break; this_thread::sleep_for(3s); @@ -219,8 +219,8 @@ void clear_group(AttrObject& job) { try { set grps{ DD::getGroupIDList() }; for (auto id : grps) { - Chat& grp = chat(id).group().name(DD::getGroupName(id)); - if (grp.isset("忽略") || grp.isset("免清") || grp.isset("免黑") || grp.isset("协议无效"))continue; + Chat& grp = chat(id).name(DD::getGroupName(id)); + if (grp.is("忽略") || grp.is("免清") || grp.is("免黑") || grp.is("协议无效"))continue; if (blacklist->get_group_danger(id)) { time_t tLast{ grp.updated() }; if (auto s{ sessions.get_if({ 0,id }) }) @@ -264,23 +264,23 @@ void clear_group(AttrObject& job) { if (intCnt) { MsgNote(job, "已按{strSelfName}黑名单清查群聊" + to_string(intCnt) + "个:" + res.show(), 0b10); } - else if (job.has("uid")) { + else if (job->has("uid")) { reply(job, getMsg("strSelfName") + "按黑名单未发现待清查群聊"); } } else if (mode == "preserve") { for (auto& [id, grp] : ChatList) { - if (grp.isset("忽略") || !grp.getLst() || grp.isset("许可使用") || grp.isset("免清") || grp.isset("协议无效"))continue; - if (grp.isGroup && DD::isGroupAdmin(id, console, false)) { - grp.set("许可使用"); + if (grp->is("忽略") || !grp->getLst() || grp->is("许可使用") || grp->is("免清") || grp->is("协议无效"))continue; + if (DD::isGroupAdmin(id, console, false)) { + grp->set("许可使用"); continue; } - time_t tLast{ grp.updated() }; + time_t tLast{ grp->updated() }; if (auto s{ sessions.get_if({ 0,id }) }) tLast = s->tUpdate > tLast ? s->tUpdate : tLast; if (tLast < grpline)GrpDelete.push_back(id); - res << printChat(grp); - grp.leave(getMsg("strPreserve")); + res << printChat(*grp); + grp->leave(getMsg("strPreserve")); intCnt++; if (console["GroupClearLimit"] > 0 && intCnt >= console["GroupClearLimit"])break; this_thread::sleep_for(3s); @@ -299,15 +299,15 @@ void clear_group(AttrObject& job) { } void list_group(AttrObject& job) { console.log("遍历群列表", 0, printSTNow()); - string mode{ job.get_str("list_mode") }; + string mode{ job->get_str("list_mode") }; if (mode.empty()) { reply(job, fmt->get_help("groups_list")); } if (mChatConf.count(mode)) { ResList res; for (auto& [id, grp] : ChatList) { - if (grp.isset(mode)) { - res << printChat(grp); + if (grp->is(mode)) { + res << printChat(*grp); } } reply(job, "{self}含词条" + mode + "群记录" + to_string(res.size()) + "条" + res.head(":").show()); @@ -316,13 +316,11 @@ void list_group(AttrObject& job) { std::priority_queue> qDiver; time_t tNow = time(NULL); for (auto& [id, grp] : ChatList) { - //if (grp.isGroup && !grps.empty() && !grps.count(id))grp.rmLst(); - if (!grp.getLst())continue; - time_t tLast{ grp.updated() }; - if (grp.isGroup) { - if (long long tLMT{ DD::getGroupLastMsg(grp.ID, console.DiceMaid) }; - tLMT > 0 && tLMT > tLast)tLast = tLMT; - } + //if (grp->isGroup && !grps.empty() && !grps.count(id))grp->rmLst(); + if (!grp->getLst())continue; + time_t tLast{ grp->updated() }; + if (long long tLMT{ DD::getGroupLastMsg(grp->ID, console.DiceMaid) }; + tLMT > 0 && tLMT > tLast)tLast = tLMT; if (!tLast)continue; int intDay{ int((tNow - tLast) / 86400) }; qDiver.emplace(intDay, printGroup(id)); @@ -340,11 +338,11 @@ void list_group(AttrObject& job) { } reply(job, "{self}所在闲置群列表:" + res.show(1)); } - else if (job["list_mode"] == "size") { + else if (job->at("list_mode") == "size") { std::priority_queue> qSize; time_t tNow = time(NULL); for (auto& [id, grp] : ChatList) { - if (!grp.getLst() || !grp.isGroup)continue; + if (!grp->getLst())continue; GroupSize_t size(DD::getGroupSize(id)); if (!size.currSize)continue; qSize.emplace(size.currSize, DD::printGroupInfo(id)); @@ -394,7 +392,7 @@ void dice_update(AttrObject& job) { reply(job, "{self}获取版本信息时出错: \n" + ret); return; } - string ver{ job.get_str("ver")}; + string ver{ job->get_str("ver")}; if (ver.empty())ver = isDev ? "dev" : "release"; try { fifo_json jInfo(fifo_json::parse(ret)); @@ -420,7 +418,7 @@ void dice_update(AttrObject& job) { reply(job, "{self}未发现更新{ver}版本"); } } catch (std::exception& e) { - job.set("err", e.what()); + job->set("err", e.what()); reply(job, "{self}获取更新失败!{err}"); } } @@ -452,7 +450,7 @@ void dice_cloudblack(AttrObject& job) { break; } if (isSuccess) { - if (job["uid"])MsgNote(job, "同步云不良记录成功," + getMsg("self") + "开始读取", 1); + if (job->has("uid"))MsgNote(job, "同步云不良记录成功," + getMsg("self") + "开始读取", 1); blacklist->loadJson(DiceDir / "conf" / "CloudBlackList.json", true); } if (console["CloudBlackShare"]) @@ -460,15 +458,15 @@ void dice_cloudblack(AttrObject& job) { } void log_put(AttrObject& job) { - int cntExec{ job.get_int("retry") }; + int cntExec{ job->get_int("retry") }; if (!cntExec) { - DD::debugLog("发送log文件:" + job.get_str("log_path")); - if ((!job.get_ll("gid") || !DD::uploadGroupFile(job.get_ll("gid"), job.get_str("log_path"))) - && job.get_ll("uid")) { - DD::sendFriendFile(job.get_ll("uid"), job.get_str("log_path")); + DD::debugLog("发送log文件:" + job->get_str("log_path")); + if ((!job->get_ll("gid") || !DD::uploadGroupFile(job->get_ll("gid"), job->get_str("log_path"))) + && job->get_ll("uid")) { + DD::sendFriendFile(job->get_ll("uid"), job->get_str("log_path")); } } - string nameLog{ Base64urlEncode(job.get_str("log_file")) }; + string nameLog{ Base64urlEncode(job->get_str("log_file")) }; #ifndef _WIN32 auto curl = curl_easy_init(); curl_slist* headers = NULL; @@ -481,7 +479,7 @@ void log_put(AttrObject& job) { CURLFORM_END); curl_formadd(&pFormPost, &pLastElem, CURLFORM_COPYNAME, "file", - CURLFORM_FILE, job.get_str("log_path").c_str(), + CURLFORM_FILE, job->get_str("log_path").c_str(), CURLFORM_FILENAME, nameLog.c_str(), CURLFORM_END); curl_easy_setopt(curl, CURLOPT_URL, "http://dicelogger.s3.ap-southeast-1.amazonaws.com"); @@ -490,26 +488,26 @@ void log_put(AttrObject& job) { curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, Network::curlWriteToString); curl_easy_setopt(curl, CURLOPT_WRITEDATA, &ret); auto res = curl_easy_perform(curl); - if (res != CURLE_OK)job.set("ret", curl_easy_strerror(res)); + if (res != CURLE_OK)job->set("ret", curl_easy_strerror(res)); curl_formfree(pFormPost); curl_easy_cleanup(curl); if (res == CURLE_OK) { #else - job["ret"] = put_s3_object("dicelogger", + job->at("ret") = put_s3_object("dicelogger", nameLog.c_str(), - GBKtoLocal(job.get_str("log_path")).c_str(), + GBKtoLocal(job->get_str("log_path")).c_str(), "ap-southeast-1"); - if (job["ret"] == "SUCCESS") { + if (job->at("ret") == "SUCCESS") { #endif //_Win32 - job["log_file"] = nameLog; - job["log_url"] = "https://logpainter.kokona.tech/?s3=" + nameLog; + job->at("log_file") = nameLog; + job->at("log_url") = "https://logpainter.kokona.tech/?s3=" + nameLog; reply(job, "{strLogUpSuccess}"); } else if (++cntExec > 2) { reply(job, "{strLogUpFailureEnd}"); } else { - job.inc("retry"); + job->inc("retry"); reply(job, "{strLogUpFailure}"); console.log(getMsg("strLogUpFailure", job), 1); sch.add_job_for(2 * 60, job); diff --git a/Dice/DiceLua.cpp b/Dice/DiceLua.cpp index fa40bc10..6332f9c9 100644 --- a/Dice/DiceLua.cpp +++ b/Dice/DiceLua.cpp @@ -90,11 +90,12 @@ AttrIndex lua_to_index(lua_State* L, int idx){ return lua_to_gbstring(L, idx); } -void lua_push_Context(lua_State* L, AttrObject& vars) { +void lua_push_Context(lua_State* L, const AttrObject& obj) { AttrObject** p{ (AttrObject**)lua_newuserdata(L, sizeof(AttrObject*)) }; - *p = &vars; + new(p) AttrObject(obj); luaL_setmetatable(L, "Context"); } +#define LUA2OBJ(idx) AttrObject& obj{*(AttrObject*)luaL_checkudata(L, idx, "Context")} void lua_push_GameTable(lua_State* L, const ptr& p) { ptr* u{ (ptr*)lua_newuserdata(L, sizeof(ptr)) }; new(u) ptr(p); @@ -166,16 +167,16 @@ void lua_push_attr(lua_State* L, const AttrVar& attr) { break; case AttrVar::Type::Table: lua_newtable(L); - if (unordered_set idxs; !attr.table.dict->empty() || attr.table.list) { - if (attr.table.list) { + if (unordered_set idxs; !attr.table->dict.empty() || attr.table->list) { + if (attr.table->list) { int idx{ 0 }; - for (auto& val : *attr.table.list) { + for (auto& val : *attr.table->list) { lua_push_attr(L, val); lua_seti(L, -2, ++idx); idxs.insert(to_string(idx)); } } - for (auto& [key, val] : *attr.table.dict) { + for (auto& [key, val] : attr.table->dict) { if (idxs.count(key))continue; val ? lua_push_attr(L, val) : lua_pushnil(L); lua_set_field(L, -2, key.c_str()); @@ -217,15 +218,15 @@ AttrVar lua_to_attr(lua_State* L, int idx = -1) { lua_pushnil(L); while (lua_next(L, idx)) { if (lua_type(L, -2) == LUA_TNUMBER) { - if (!tab.list)tab.list = std::make_shared(); + if (!tab->list)tab->list = std::make_shared(); size_t idx{ (size_t)lua_tointeger(L,-2) }; - while (idx > tab.list->size() + 1) { - tab.list->push_back({}); + while (idx > tab->list->size() + 1) { + tab->list->push_back({}); } - tab.list->push_back(lua_to_attr(L, -1)); + tab->list->push_back(lua_to_attr(L, -1)); } else { - tab.dict->emplace(lua_to_gbstring(L, -2), lua_to_attr(L, -1)); + tab->dict.emplace(lua_to_gbstring(L, -2), lua_to_attr(L, -1)); } lua_pop(L, 1); } @@ -241,22 +242,35 @@ AttrVar lua_to_attr(lua_State* L, int idx = -1) { return {}; } -AttrVars lua_to_dict(lua_State* L, int idx = -1) { - AttrVars tab; +AnysTable lua_to_table(lua_State* L, int idx = -1) { + AnysTable tab; if (idx < 0)idx = lua_gettop(L) + idx + 1; lua_pushnil(L); while (lua_next(L, idx)) { if (lua_isstring(L, -2) && !lua_isnil(L, -1)) { - tab[lua_to_gbstring(L, -2)] = lua_to_attr(L, -1); + tab.set(lua_to_gbstring(L, -2),lua_to_attr(L, -1)); + } + else { + tab.set(lua_to_int(L, -2) - 1, lua_to_attr(L, -1)); } lua_pop(L, 1); } return tab; } +AttrVars lua_to_dict(lua_State* L, int idx = -1) { + AttrVars tab; + if (idx < 0)idx = lua_gettop(L) + idx + 1; + lua_pushnil(L); + while (lua_next(L, idx)) { + tab[lua_to_gbstring(L, -2)] = lua_to_attr(L, -1); + lua_pop(L, 1); + } + return tab; +} //为msg直接调用lua语句 bool lua_msg_call(DiceEvent* msg, const AttrVar& lua) { - string luaFile{ lua.is_table() ? lua.to_obj().get_str("file") : "" }; + string luaFile{ lua.is_table() ? lua.to_obj()->get_str("file") : "" }; AttrVar luaFunc; if (luaFile.empty() && lua.is_character() && fmt->has_lua(lua)) { luaFile = fmt->lua_path(lua); @@ -264,7 +278,7 @@ bool lua_msg_call(DiceEvent* msg, const AttrVar& lua) { else luaFunc = lua.is_table() ? lua.to_obj()["func"] : lua; LuaState L{ luaFile }; if (!L)return false; - lua_push_Context(L, *msg); + lua_push_Context(L, msg->shared_from_this()); lua_setglobal(L, "msg"); if (!luaFile.empty()) { #ifdef _WIN32 @@ -293,7 +307,7 @@ bool lua_msg_call(DiceEvent* msg, const AttrVar& lua) { } else { lua_getglobal(L, luaFunc.to_str().c_str()); - lua_push_Context(L, *msg); + lua_push_Context(L, msg->shared_from_this()); if (lua_pcall(L, 1, 2, 0)) { string pErrorMsg = lua_to_gbstring_from_native(L, -1); console.log(getMsg("strSelfName") + "调用" + fileGBK + "函数" + luaFunc.to_str() + "失败!\n" + pErrorMsg, 0b10); @@ -308,7 +322,7 @@ bool lua_msg_call(DiceEvent* msg, const AttrVar& lua) { ByteS bytes{ lua.to_bytes() }; if (bytes.isUTF8)UTF8Luas.insert(L); if (lua_load(L, lua_reader, &bytes, msg->get_str("reply_title").c_str(), "bt") - || (lua_push_Context(L, *msg), lua_pcall(L, 1, 2, 0))) { + || (lua_push_Context(L, msg->shared_from_this()), lua_pcall(L, 1, 2, 0))) { string pErrorMsg = lua_to_gbstring_from_native(L, -1); console.log(getMsg("strSelfName") + "运行Lua字节码" + msg->get_str("reply_title") + "失败!\n" + pErrorMsg, 0b10); msg->set("lang", "Lua"); @@ -369,7 +383,7 @@ bool lua_call_event(AttrObject eve, const AttrVar& lua) { else if (lua.is_function()) { ByteS bytes{ lua.to_bytes() }; if (bytes.isUTF8)UTF8Luas.insert(L); - if (lua_load(L, lua_reader, (void*)&bytes, eve.get_str("Type").c_str(), "bt") + if (lua_load(L, lua_reader, (void*)&bytes, eve->get_str("Type").c_str(), "bt") || lua_pcall(L, 0, 2, 0)) { string pErrorMsg = lua_to_gbstring_from_native(L, -1); console.log(getMsg("strSelfName") + "调用事件lua失败!\n" + pErrorMsg, 0b10); @@ -507,8 +521,8 @@ int selfData_get(lua_State* L) { } else if(file.data.is_table()){ string key{ lua_to_gbstring(L, 2) }; - if (file.data.table.has(key)) { - lua_push_attr(L, file.data.table.get(key)); + if (file.data.table->has(key)) { + lua_push_attr(L, file.data.table->get(key)); return 1; } else if (lua_gettop(L) > 2) { @@ -527,9 +541,9 @@ int selfData_set(lua_State* L) { else if (std::lock_guard lock(file.exWrite); lua_isstring(L, 2) && file.data.is_table()) { string key{ lua_to_gbstring(L, 2) }; if (lua_isnoneornil(L, 3)) { - file.data.table.reset(key); + file.data.table->reset(key); } - else file.data.table.set(key, lua_to_attr(L, 3)); + else file.data.table->set(key, lua_to_attr(L, 3)); } else return 0; file.save(); @@ -545,8 +559,8 @@ int SelfData_index(lua_State* L) { else if (key == "set") { lua_pushcfunction(L, selfData_set); } - else if (file.data.is_table() && file.data.table.has(key)) { - lua_push_attr(L, file.data.table.get(key)); + else if (file.data.is_table() && file.data.table->has(key)) { + lua_push_attr(L, file.data.table->get(key)); } else return 0; return 1; @@ -558,10 +572,10 @@ int SelfData_newindex(lua_State* L) { if (file.data.is_null())file.data = AttrVars(); else if (!file.data.is_table())return 0; if (std::lock_guard lock(file.exWrite); lua_isnoneornil(L,3)) { - file.data.table.reset(key); + file.data.table->reset(key); } else { - file.data.table.set(key, lua_to_attr(L, 3)); + file.data.table->set(key, lua_to_attr(L, 3)); } file.save(); return 0; @@ -700,8 +714,8 @@ LUADEF(getGroupConf) { if (item.empty())return 0; lua_newtable(L); for (auto& [id, data] : ChatList) { - if (data.confs.has(item)) { - lua_push_attr(L, data.confs.get(item)); + if (data->has(item)) { + lua_push_attr(L, data->get(item)); lua_set_field(L, -2, to_string(id)); } } @@ -710,7 +724,7 @@ LUADEF(getGroupConf) { long long id{ lua_to_int_or_zero(L, 1) }; if (!id)return 0; if (item.empty()) { - lua_push_Context(L, chat(id).confs); + lua_push_Context(L, chat(id).shared_from_this()); return 1; } else if (item == "members") { @@ -797,8 +811,8 @@ LUADEF(getUserConf) { if (item.empty())return 0; lua_newtable(L); for (auto& [uid, data] : UserList) { - if (data.isset(item)) { - lua_push_attr(L, data.confs.get(item)); + if (data->has(item)) { + lua_push_attr(L, data->get(item)); lua_set_field(L, -2, to_string(uid)); } } @@ -807,7 +821,7 @@ LUADEF(getUserConf) { long long uid{ lua_to_int_or_zero(L, 1) }; if (!uid)return 0; if (UserList.count(uid) && item.empty()) { - lua_push_Context(L, getUser(uid).confs); + lua_push_Context(L, getUser(uid).shared_from_this()); return 1; } auto val{ getUserItem(uid,item) }; @@ -862,8 +876,8 @@ LUADEF(getUserToday) { if (item.empty())return 0; lua_newtable(L); for (auto& [uid, data] : today->getUserInfo()) { - if (data.has(item) && uid) { - lua_push_attr(L,data.get(item)); + if (data->has(item) && uid) { + lua_push_attr(L,data->get(item)); lua_set_field(L, -2, to_string(uid)); } } @@ -991,28 +1005,28 @@ LUADEF(sendMsg) { if (top < 1)return 0; AttrObject chat; if (lua_istable(L, 1)) { - chat = lua_to_dict(L, 1); + chat = lua_to_table(L, 1); } else { - chat["fwdMsg"] = lua_to_gbstring(L, 1); + chat->at("fwdMsg") = lua_to_gbstring(L, 1); if (top < 2)return 0; - chat["gid"] = lua_to_int_or_zero(L, 2); - if (top >= 3)chat["uid"] = lua_to_int_or_zero(L, 3); - if (top >= 4)chat["chid"] = lua_to_int_or_zero(L, 4); + chat->at("gid") = lua_to_int_or_zero(L, 2); + if (top >= 3)chat->at("uid") = lua_to_int_or_zero(L, 3); + if (top >= 4)chat->at("chid") = lua_to_int_or_zero(L, 4); } - if (!chat.get_ll("gid") && !chat.get_ll("uid"))return 0; - msgtype type{ chat.get_ll("gid") ? msgtype::Group + if (!chat->get_ll("gid") && !chat->get_ll("uid"))return 0; + msgtype type{ chat->get_ll("gid") ? msgtype::Group : msgtype::Private }; - AddMsgToQueue(fmt->format(chat.get_str("fwdMsg"), chat), - { chat.get_ll("uid"),chat.get_ll("gid"),chat.get_ll("chid") }); + AddMsgToQueue(fmt->format(chat->get_str("fwdMsg"), chat), + { chat->get_ll("uid"),chat->get_ll("gid"),chat->get_ll("chid") }); return 0; } LUADEF(eventMsg) { int top{ lua_gettop(L) }; if (top < 1)return 0; - AttrVars eve; + AnysTable eve; if (lua_istable(L, 1)) { - eve = lua_to_dict(L, 1); + eve = lua_to_table(L, 1); } else { string fromMsg{ lua_to_gbstring(L, 1) }; @@ -1032,7 +1046,7 @@ LUADEF(eventMsg) { LUADEF(askExtra) { string data; //utf-8 if (lua_istable(L, 1)) { - data = to_json(lua_to_dict(L, 1)).dump(); + data = to_json(lua_to_table(L, 1)).dump(); } else { data = lua_to_raw_string(L, 1); @@ -1051,17 +1065,17 @@ LUADEF(askExtra) { } int Msg_echo(lua_State* L) { - AttrObject& vars{ **(AttrObject**)luaL_checkudata(L, 1, "Context") }; + LUA2OBJ(1); string msg{ lua_to_gbstring(L, 2) }; - if (lua_isboolean(L, 3))reply(vars, msg, !lua_toboolean(L,3)); - else reply(vars, msg); + if (lua_isboolean(L, 3))reply(obj, msg, !lua_toboolean(L,3)); + else reply(obj, msg); return 0; } int Context_format(lua_State* L) { if (lua_gettop(L) < 2)return 0; - AttrObject vars{ lua_isuserdata(L,1) ? **(AttrObject**)luaL_checkudata(L, 1, "Context") - : lua_istable(L, 1) ? lua_to_dict(L,1) + AttrObject vars{ lua_isuserdata(L,1) ? *(AttrObject*)luaL_checkudata(L, 1, "Context") + : lua_istable(L, 1) ? AnysTable(lua_to_table(L,1)) : AttrObject{} }; string msg{ lua_to_gbstring(L, 2) }; lua_push_string(L, fmt->format(msg, vars)); @@ -1069,7 +1083,7 @@ int Context_format(lua_State* L) { } int Context_get(lua_State* L) { AttrObject obj{ lua_isuserdata(L,1) ? **(AttrObject**)luaL_checkudata(L, 1, "Context") - : lua_istable(L, 1) ? lua_to_dict(L,1) + : lua_istable(L, 1) ? AnysTable(lua_to_table(L,1)) : AttrObject{} }; if (lua_isnoneornil(L, 2)) { lua_push_attr(L, obj); @@ -1089,13 +1103,13 @@ int Context_get(lua_State* L) { } int Context_add(lua_State* L) { if (lua_gettop(L) < 2)return 0; - AttrObject& vars{ **(AttrObject**)luaL_checkudata(L, 1, "Context") }; - string key{ fmt->format(lua_to_gbstring(L, 2), vars) }; + LUA2OBJ(1); + string key{ fmt->format(lua_to_gbstring(L, 2), obj) }; if (lua_isnoneornil(L, 3)) { - vars.inc(key); + obj->inc(key); } else { - vars.add(key, lua_to_attr(L, 3)); + obj->add(key, lua_to_attr(L, 3)); } return 0; } @@ -1117,26 +1131,26 @@ int Context_index(lua_State* L) { lua_pushcfunction(L, Context_add); return 1; } - AttrObject& vars{ **(AttrObject**)luaL_checkudata(L, 1, "Context") }; - if (key == "user" && vars.has("uid")) { - lua_push_Context(L, getUser(vars.get_ll("uid")).confs); + LUA2OBJ(1); + if (key == "user" && obj->has("uid")) { + lua_push_Context(L, getUser(obj->get_ll("uid")).shared_from_this()); return 1; } - else if((key == "grp" || key == "group") && vars.has("gid")) { - lua_push_Context(L, chat(vars.get_ll("gid")).confs); + else if((key == "grp" || key == "group") && obj->has("gid")) { + lua_push_Context(L, chat(obj->get_ll("gid")).shared_from_this()); return 1; } - else if (key == "pc" && vars.has("uid")) { - lua_push_Actor(L, getPlayer(vars.get_ll("uid"))[vars.get_ll("gid")]); + else if (key == "pc" && obj->has("uid")) { + lua_push_Actor(L, getPlayer(obj->get_ll("uid"))[obj->get_ll("gid")]); return 1; } else if (key == "game") { - if (auto game = sessions.get_if(vars)) { + if (auto game = sessions.get_if(*obj)) { lua_push_GameTable(L, game); return 1; } } - else if (auto val{ getContextItem(vars,key) }) { + else if (auto val{ getContextItem(obj, key) }) { lua_push_attr(L, val); return 1; } @@ -1144,19 +1158,32 @@ int Context_index(lua_State* L) { } int Context_newindex(lua_State* L) { if (lua_gettop(L) < 2)return 0; - AttrObject& vars{ **(AttrObject**)luaL_checkudata(L, 1, "Context") }; - string key{ fmt->format(lua_to_gbstring(L, 2), vars) }; + LUA2OBJ(1); + string key{ fmt->format(lua_to_gbstring(L, 2), obj) }; if (lua_isnoneornil(L, 3)) { - vars.reset(key); + obj->reset(key); } else { - vars.set(key, lua_to_attr(L, 3)); + obj->set(key, lua_to_attr(L, 3)); + } + return 0; +} +int Context_gc(lua_State* L) { + if (lua_gettop(L) < 2)return 0; + LUA2OBJ(1); + string key{ fmt->format(lua_to_gbstring(L, 2), obj) }; + if (lua_isnoneornil(L, 3)) { + obj->reset(key); + } + else { + obj->set(key, lua_to_attr(L, 3)); } return 0; } static const luaL_Reg Context_funcs[] = { {"__index", Context_index}, {"__newindex", Context_newindex}, + {"__gc", Context_gc}, //{"format", Context_format}, {NULL, NULL} }; @@ -1172,12 +1199,12 @@ int GameTable_set(lua_State* L) { if (lua_isstring(L, 2)) { string key{ lua_to_gbstring(L, 2) }; if (lua_gettop(L) < 3) { - game->rmAttr(key); + game->reset(key); } else if (AttrVar val{ lua_to_attr(L, 3) }; val.is_null()) { - game->rmAttr(key); + game->reset(key); } - else game->setAttr(key, val); + else game->set(key, val); } else if (lua_istable(L, 2)) { int cnt = 0; @@ -1185,10 +1212,10 @@ int GameTable_set(lua_State* L) { lua_settop(L, 3); while (lua_next(L, 2)) { if (lua_type(L, 3) == LUA_TNUMBER) { - game->rmAttr(lua_to_gbstring(L, 4)); + game->reset(lua_to_gbstring(L, 4)); } else { - game->setAttr(lua_to_gbstring(L, 3), lua_to_attr(L, 4)); + game->set(lua_to_gbstring(L, 3), lua_to_attr(L, 4)); } lua_pop(L, 1); } @@ -1232,13 +1259,13 @@ int GameTable_newindex(lua_State* L) { LUA2GAME(1); string key{ lua_to_gbstring(L, 2) }; if (lua_gettop(L) < 3) { - game->rmAttr(key); + game->reset(key); } else if (AttrVar val{ lua_to_attr(L, 3) }; val.is_null()) { - game->rmAttr(key); + game->reset(key); } else { - game->setAttr(key, val); + game->set(key, val); } return 0; } @@ -1404,7 +1431,7 @@ int httpGet(lua_State* L) { int httpPost(lua_State* L) { if (lua_gettop(L) < 2)return 0; string url{ lua_tostring(L,1) }; - string content{ lua_istable(L,2) ? to_json(lua_to_dict(L,2)).dump() : lua_to_raw_string(L,2) }; + string content{ lua_istable(L,2) ? to_json(lua_to_table(L,2)).dump() : lua_to_raw_string(L,2) }; if (url.empty() || content.empty()) { return 0; } @@ -1563,7 +1590,7 @@ void DiceModManager::loadPlugin(ResList& res) { if (pathFile.extension() != ".toml")continue; if (ifstream fs{ pathFile }) try { auto tab{ AttrVar(toml::parse(fs)).to_obj() }; - if (auto items{ tab.get_dict("reply") })for (auto& [key, val] : *items) { + if (auto items{ tab->get_dict("reply") })for (auto& [key, val] : **items) { ptr reply{ std::make_shared() }; reply->title = key; reply->from_obj(val.to_obj()); @@ -1593,7 +1620,7 @@ void DiceModManager::loadPlugin(ResList& res) { err << "msg_order类型错误(" + string(LuaTypes[lua_type(L, -1)]) + "):" + file; continue; } - for (auto& [key, val] : lua_to_dict(L)) { + for (auto& [key, val] : lua_to_table(L).as_dict()) { if (val.is_table()) { ptr reply{ std::make_shared() }; reply->title = key; @@ -1619,7 +1646,7 @@ void DiceModManager::loadPlugin(ResList& res) { err << "task_kill类型错误(" + string(LuaTypes[lua_type(L, -1)]) + "):" + file; continue; } - for (auto& [key, val] : lua_to_dict(L)) { + for (auto& [key, val] : lua_to_table(L).as_dict()) { taskcall[key] = { {"file",file},{"func",val} }; ++cntTask; } @@ -1644,20 +1671,20 @@ void DiceMod::loadLua() { if (file.extension() != ".toml")continue; if (ifstream fs{ file }) try{ auto tab{ AttrVar(toml::parse(fs)).to_obj()}; - if (auto items{ tab.get_dict("reply") })for (auto& [key, val] : *items) { + if (auto items{ tab->get_dict("reply") })for (auto& [key, val] : **items) { ptr reply{ std::make_shared() }; reply->title = key; auto item{ val.to_obj() }; reply->from_obj(item); - if (item.has("rule")) { - rules[item.get_str("rule")].orders.add(key, reply); + if (item->has("rule")) { + rules[item->get_str("rule")].orders.add(key, reply); } else { reply_list[key] = reply; } } - if (auto items{ tab.get_dict("event") })for (auto& [key, val] : *items) { - events[key] = val.to_obj(); + if (auto items{ tab->get_dict("event") })for (auto& [key, val] : **items) { + events[key] = *val.to_obj(); } } catch (std::exception& e) { @@ -1687,8 +1714,8 @@ void DiceMod::loadLua() { reply->title = key; auto item{ val.to_obj() }; reply->from_obj(item); - if (item.has("rule")) { - rules[item.get_str("rule")].orders.add(key, reply); + if (item->has("rule")) { + rules[item->get_str("rule")].orders.add(key, reply); } else { reply_list[key] = reply; @@ -1703,7 +1730,7 @@ void DiceMod::loadLua() { continue; } for (auto& [key, val] : lua_to_dict(L)) { - events[key] = val.to_obj(); + events[key] = *val.to_obj(); } } } diff --git a/Dice/DiceLua.h b/Dice/DiceLua.h index 1a85bf72..55636525 100644 --- a/Dice/DiceLua.h +++ b/Dice/DiceLua.h @@ -1,11 +1,12 @@ /** * lua脚本嵌入 * 用于自定义前缀指令等 - * Copyright (C) 2019-2023 String.Empty + * Copyright (C) 2019-2024 String.Empty */ #pragma once #include #include +#include class Lua_State; class DiceEvent; diff --git a/Dice/DiceMod.cpp b/Dice/DiceMod.cpp index c0097f69..24e0f0c9 100644 --- a/Dice/DiceMod.cpp +++ b/Dice/DiceMod.cpp @@ -406,7 +406,7 @@ class Parser { shared_ptr root; AttrVar res; public: - Parser(const string& s, const AttrObject& obj, bool t = true, const dict_ci& con = {}) + Parser(const string& s, AttrObject obj, bool t = true, const dict_ci& con = {}) :root(std::make_shared(s, 0, char(0xAA))), context(obj), isTrust(t), dict(con) { string& exp{ root->leaf }; auto parent{ root }; @@ -466,9 +466,9 @@ class Parser { if (key == "{" || key == "}") { val = key; } - else if (context.has(key)) { - if (key == "res")val = fmt->format(context.print(key), context, isTrust, dict); - else val = context.print(key); + else if (context->has(key)) { + if (key == "res")val = fmt->format(context->print(key), context, isTrust, dict); + else val = context->print(key); } else if (AttrVar res{ getContextItem(context, key, isTrust) }) { val = res; @@ -490,13 +490,13 @@ class Parser { if (posQ < posE) { auto [field, exp] = readini(para, '?'); field = format_token(field, it); - context.set(field, val = (exp[0] == char(0xAA)) ? format_token(exp, it) : AttrVar::parse(exp)); + context->set(field, val = (exp[0] == char(0xAA)) ? format_token(exp, it) : AttrVar::parse(exp)); } else { auto exps{ splitPairs(para,'=','&') }; for (auto& [field, exp] : exps) { - if (exp.empty())context.set(field); - else context.set(field, (exp[0] == char(0xAA)) ? format_token(exp, it) : AttrVar::parse(exp)); + if (exp.empty())context->set(field); + else context->set(field, (exp[0] == char(0xAA)) ? format_token(exp, it) : AttrVar::parse(exp)); } val.des(); } @@ -516,18 +516,18 @@ class Parser { else if (!para.empty()) { val = "[CQ:at,qq=" + para + "]"; } - else if (context.has("uid")) { - val = "[CQ:at,qq=" + context.get_str("uid") + "]"; + else if (context->has("uid")) { + val = "[CQ:at,qq=" + context->get_str("uid") + "]"; } else val.des(); break; case FmtMethod::Print: if (auto paras{ splitPairs(para,'=','&') }; paras.count("uid")) { - if (isTrust && paras["uid"].empty())val = printUser(context.get_ll("uid")); + if (isTrust && paras["uid"].empty())val = printUser(context->get_ll("uid")); else val = printUser(AttrVar(paras["uid"]).to_ll()); } else if (paras.count("gid")) { - if (isTrust && paras["gid"].empty())val = printGroup(context.get_ll("gid")); + if (isTrust && paras["gid"].empty())val = printGroup(context->get_ll("gid")); else val = printGroup(AttrVar(paras["gid"]).to_ll()); } else if (paras.count("master")) { @@ -658,7 +658,7 @@ void DiceModManager::msg_edit(const string& key, const string& val){ saveJMap(DiceDir / "conf" / "CustomMsg.json", EditedMsg); } -string DiceModManager::get_help(const string& key, AttrObject context) const{ +string DiceModManager::get_help(const string& key, const AttrObject& context) const{ if (const auto it = global_helpdoc.find(key); it != global_helpdoc.end()){ return format(it->second, context, true, global_helpdoc); } @@ -683,15 +683,15 @@ struct help_sorter { return _Left < _Right; } }; -string DiceModManager::prev_help(const string& key, AttrObject context) const { +string DiceModManager::prev_help(const string& key, const AttrObject& context) const { if (const auto it = global_helpdoc.find(key); it != global_helpdoc.end()) { return it->second; } else if (auto keys = querier.search(key); !keys.empty()) { if (keys.size() == 1) { auto word{ *keys.begin() }; - context.set("redirect_key", word); - context.set("redirect_res", global_helpdoc.at(word)); + context->set("redirect_key", word); + context->set("redirect_res", global_helpdoc.at(word)); return getMsg("strHelpRedirect", context); } else { @@ -705,7 +705,7 @@ string DiceModManager::prev_help(const string& key, AttrObject context) const { qKey.pop(); if (res.size() > 20)break; } - context.set("res", res.show("\n")); + context->set("res", res.show("\n")); return getMsg("strHelpSuggestion", context); } } @@ -764,15 +764,15 @@ void DiceModManager::rm_help(const string& key){ time_t parse_seconds(const AttrVar& time) { if (time.is_numberic())return time.to_int(); - if (AttrObject t{ time.to_obj() }; !t.empty()) - return t.get_ll("second") + t.get_ll("minute") * 60 + t.get_ll("hour") * 3600 + t.get_ll("day") * 86400; + if (auto t{ time.to_obj() }; !t->empty()) + return t->get_ll("second") + t->get_ll("minute") * 60 + t->get_ll("hour") * 3600 + t->get_ll("day") * 86400; return 0; } Clock parse_clock(const AttrVar& time) { Clock clock{ 0,0 }; - if (AttrObject t{ time.to_obj() }; !t.empty()) { - clock.first = t.get_int("hour"); - clock.second = t.get_int("minute"); + if (auto t{ time.to_obj() }; !t->empty()) { + clock.first = t->get_int("hour"); + clock.second = t->get_int("minute"); } return clock; } @@ -780,32 +780,32 @@ Clock parse_clock(const AttrVar& time) { void DiceModManager::call_cycle_event(const string& id) { if (id.empty() || !global_events.count(id))return; AttrObject eve{ global_events[id] }; - if (auto trigger{ eve.get_dict("trigger") }; trigger->count("cycle")) { + if (auto trigger{ eve->get_obj("trigger") }; trigger->has("cycle")) { sch.add_job_for(parse_seconds(trigger->at("cycle")), eve); } - if (auto action{ eve.get_dict("action") })call_event(eve, action); + if (auto action{ eve->get_obj("action") })call_event(eve, action); } void DiceModManager::call_clock_event(const string& id) { if (id.empty() || !global_events.count(id))return; AttrObject eve{ global_events[id] }; - if (auto action{ eve.get_dict("action") })call_event(eve, action); + if (auto action{ eve->get_obj("action") })call_event(eve, action); } bool DiceModManager::call_hook_event(AttrObject eve) { - string hookEvent{ eve.has("hook") ? eve.get_str("hook") : eve.get_str("Event") }; + string hookEvent{ eve->has("hook") ? eve->get_str("hook") : eve->get_str("Event") }; if (hookEvent.empty())return false; for (auto& [id, hook] : multi_range(hook_events, hookEvent)) { - if (auto action{ hook["action"].to_dict()}) { + if (auto action{ hook.at("action").to_obj()}) { if (hookEvent == "StartUp" || hookEvent == "DayEnd" || hookEvent == "DayNew") { - if (action->count("lua")) { + if (action->has("lua")) { std::thread th(lua_call_event, eve, action->at("lua")); th.detach(); } - if (action->count("js")) { + if (action->has("js")) { std::thread th(js_call_event, eve, action->at("js")); th.detach(); } #ifdef DICE_PYTHON - if (action->count("py")) { + if (action->has("py")) { std::thread th(py_call_event, eve, action->at("py")); th.detach(); } @@ -814,7 +814,7 @@ bool DiceModManager::call_hook_event(AttrObject eve) { else call_event(eve, action); } } - return eve.is("blocked"); + return eve->is("blocked"); } string DiceModManager::list_reply(int type)const { @@ -1066,7 +1066,7 @@ void DiceMod::loadDir() { rule.manual[UTF8toGBK(it.first.Scalar())] = UTF8toGBK(it.second.Scalar()); } if (yaml["tape"])for (auto it : yaml["tape"]) { - rule.cassettes[UTF8toGBK(it.first.Scalar())] = AttrVar(it.second).to_dict(); + rule.cassettes[UTF8toGBK(it.first.Scalar())] = AttrVar(it.second).to_obj(); } } else console.log(UTF8toGBK(cut_relative(p, pathDir).u8string()) + "yaml格式不为对象!", 0b10); @@ -1300,13 +1300,13 @@ void DiceModManager::build() { for (auto& [id, eve] : global_events) { eve["id"] = id; auto trigger{ eve.get_obj("trigger") }; - if (trigger.has("cycle")) { + if (trigger->has("cycle")) { if (!cycle_events.count(id)) { call_cycle_event(id); } cycle.insert(id); } - if (trigger.has("clock")) { + if (trigger->has("clock")) { auto& clock{ trigger->at("clock") }; if (auto list{ clock.to_list() }) { for (auto& clc : *list) { @@ -1317,7 +1317,7 @@ void DiceModManager::build() { clock_events.emplace(parse_clock(clock), id); } } - if (trigger.has("hook")) { + if (trigger->has("hook")) { string nameEvent{ trigger->at("hook").to_str() }; hook_events.emplace(nameEvent, eve); } @@ -1353,10 +1353,10 @@ void DiceModManager::save() { remove(DiceDir / "conf" / "ModList.json"); } } -void call_event(AttrObject eve, const ptr& action) { - if (action->count("lua"))lua_call_event(eve, action->at("lua")); - if (action->count("js"))js_call_event(eve, action->at("js")); +void call_event(AttrObject eve, const AttrObject& action) { + if (action->has("lua"))lua_call_event(eve, action->at("lua")); + if (action->has("js"))js_call_event(eve, action->at("js")); #ifdef DICE_PYTHON - if (action->count("py"))py_call_event(eve, action->at("py")); + if (action->has("py"))py_call_event(eve, action->at("py")); #endif //DICE_PYTHON } \ No newline at end of file diff --git a/Dice/DiceMod.h b/Dice/DiceMod.h index d745a7a0..f1b27932 100644 --- a/Dice/DiceMod.h +++ b/Dice/DiceMod.h @@ -128,7 +128,7 @@ class DiceMod { dict_cipy_scripts; vectorluaFiles; dict>reply_list; - AttrObjects events; + dict events; size_t cntImage{ 0 }; size_t cntAudio{ 0 }; }; @@ -154,10 +154,10 @@ class DiceModManager { dict_ci global_js_scripts; dict_ci global_py_scripts; dict_ci taskcall; - AttrObjects global_events; //events by id + dict global_events; //events by id //Event unordered_set cycle_events; //重载时唯一性检查 - multidict_ci hook_events; + multidict_ci hook_events; WordQuerier querier; friend class DiceMod; @@ -192,7 +192,7 @@ class DiceModManager { void uninstall(const string& name); bool reorder(size_t, size_t); - AttrVar format(const string&, const AttrObject& = {}, + AttrVar format(const string&, const AttrObject & = {}, bool isTrust = true, const dict_ci& = {}) const; string msg_get(const string& key)const; @@ -200,8 +200,8 @@ class DiceModManager { void msg_edit(const string& key, const string& val); fifo_dict_cicntHelp; - [[nodiscard]] string get_help(const string&, AttrObject = {}) const; - [[nodiscard]] string prev_help(const string&, AttrObject = {}) const; + [[nodiscard]] string get_help(const string&, const AttrObject & = {}) const; + [[nodiscard]] string prev_help(const string&, const AttrObject& = {}) const; void _help(DiceEvent*); void set_help(const string&, const string&); void rm_help(const string&); @@ -238,4 +238,4 @@ class DiceModManager { }; extern std::shared_ptr fmt; -void call_event(AttrObject eve, const ptr& action); \ No newline at end of file +void call_event(AttrObject eve, const AttrObject& action); \ No newline at end of file diff --git a/Dice/DiceMsgReply.cpp b/Dice/DiceMsgReply.cpp index a1ef41d9..29ee3a7e 100644 --- a/Dice/DiceMsgReply.cpp +++ b/Dice/DiceMsgReply.cpp @@ -43,29 +43,29 @@ string parse_vary(const AttrVars& raw, fifo_dict_ci } else { auto& tab{ exp.table }; - if (tab.has("equal")) { - vary[var] = { &AttrVar::equal,tab["equal"] }; - vars << var + "=" + tab.print("equal"); + if (tab->has("equal")) { + vary[var] = { &AttrVar::equal,tab->get("equal") }; + vars << var + "=" + tab->print("equal"); } - else if (tab.has("neq")) { - vary[var] = { &AttrVar::not_equal , tab["neq"] }; - vars << var + "=" + tab.print("neq") + "!"; + else if (tab->has("neq")) { + vary[var] = { &AttrVar::not_equal , tab->get("neq") }; + vars << var + "=" + tab->print("neq") + "!"; } - else if (tab.has("at_least")) { - vary[var] = { &AttrVar::equal_or_more , tab["at_least"] }; - vars << var + "=" + tab.print("at_least") + "+"; + else if (tab->has("at_least")) { + vary[var] = { &AttrVar::equal_or_more , tab->get("at_least") }; + vars << var + "=" + tab->print("at_least") + "+"; } - else if (tab.has("at_most")) { - vary[var] = { &AttrVar::equal_or_less , tab["at_most"] }; - vars << var + "=" + tab.print("at_most") + "-"; + else if (tab->has("at_most")) { + vary[var] = { &AttrVar::equal_or_less , tab->get("at_most") }; + vars << var + "=" + tab->print("at_most") + "-"; } - else if (tab.has("more")) { - vary[var] = { &AttrVar::more , tab["more"] }; - vars << var + "=" + tab.print("more") + "++"; + else if (tab->has("more")) { + vary[var] = { &AttrVar::more , tab->get("more") }; + vars << var + "=" + tab->print("more") + "++"; } - else if (tab.has("less")) { - vary[var] = { &AttrVar::less , tab["less"] }; - vars << var + "=" + tab.print("less") + "--"; + else if (tab->has("less")) { + vary[var] = { &AttrVar::less , tab->get("less") }; + vars << var + "=" + tab->print("less") + "--"; } } } @@ -260,7 +260,7 @@ DiceTriggerLimit& DiceTriggerLimit::parse(const AttrVar& var) { new(this)DiceTriggerLimit(); ShowList limits; ShowList notes; - for (auto& [key, item] : *var.to_dict()) { + for (auto& [key, item] : **var.to_dict()) { if (key == "prob") { if (int prob{ item.to_int() }) { limits << "prob:" + to_string(prob); @@ -273,9 +273,9 @@ DiceTriggerLimit& DiceTriggerLimit::parse(const AttrVar& var) { } else if (!item.is_table())continue; AttrObject& tab{ item.table }; - if (tab.has("nor")) { + if (tab->has("nor")) { user_id_negative = true; - auto id{ tab.get("nor") }; + auto id{ tab->get("nor") }; if (id.is_numberic()) { user_id = { item.to_ll() }; } @@ -283,7 +283,7 @@ DiceTriggerLimit& DiceTriggerLimit::parse(const AttrVar& var) { user_id.emplace(i.to_ll()); } } - else for (auto& id : *tab.to_list()) { + else for (auto& id : *tab->to_list()) { user_id.emplace(id.to_ll()); } if (!user_id.empty()) { @@ -297,9 +297,9 @@ DiceTriggerLimit& DiceTriggerLimit::parse(const AttrVar& var) { } else if (!item.is_table())continue; AttrObject& tab{ item.table }; - if (tab.has("nor")) { + if (tab->has("nor")) { grp_id_negative = true; - auto id{ tab.get("nor") }; + auto id{ tab->get("nor") }; if (id.is_numberic()) { grp_id = { item.to_ll() }; } @@ -307,7 +307,7 @@ DiceTriggerLimit& DiceTriggerLimit::parse(const AttrVar& var) { grp_id.emplace(i.to_ll()); } } - else if (tab.to_list())for (auto& id : *tab.to_list()) { + else if (tab->to_list())for (auto& id : *tab->to_list()) { grp_id.emplace(id.to_ll()); } if (!grp_id.empty()) { @@ -328,7 +328,7 @@ DiceTriggerLimit& DiceTriggerLimit::parse(const AttrVar& var) { if (auto v{ item.to_list() }) { cd_timer.emplace_back(type, name, (time_t)v->begin()->to_ll()); } - for (auto& [subkey, value] : *item.to_dict()) { + for (auto& [subkey, value] : **item.to_dict()) { if (CDConfig::eType.count(subkey)) { type = (CDType)CDConfig::eType[subkey]; if (value.is_numberic()) { @@ -338,7 +338,7 @@ DiceTriggerLimit& DiceTriggerLimit::parse(const AttrVar& var) { if (auto v{ value.to_list() }) { cd_timer.emplace_back(type, name, (time_t)v->begin()->to_ll()); } - if (value.is_table())for (auto& [name, ct] : *value.to_dict()) { + if (value.is_table())for (auto& [name, ct] : **value.to_dict()) { cd_timer.emplace_back(type, name, (time_t)ct.to_ll()); } continue; @@ -371,7 +371,7 @@ DiceTriggerLimit& DiceTriggerLimit::parse(const AttrVar& var) { if (auto v{ item.to_list() }) { today_cnt.emplace_back(type, name, (time_t)v->begin()->to_ll()); } - for (auto& [subkey, value] : *item.to_dict()) { + for (auto& [subkey, value] : **item.to_dict()) { if (CDConfig::eType.count(subkey)) { type = (CDType)CDConfig::eType[subkey]; if (value.is_numberic()) { @@ -381,7 +381,7 @@ DiceTriggerLimit& DiceTriggerLimit::parse(const AttrVar& var) { if (auto v{ value.to_list() }) { today_cnt.emplace_back(type, name, (time_t)v->begin()->to_ll()); } - if (value.is_table())for (auto& [name, ct] : *value.to_dict()) { + if (value.is_table())for (auto& [name, ct] : **value.to_dict()) { today_cnt.emplace_back(type, name, (time_t)ct.to_ll()); } continue; @@ -419,7 +419,7 @@ DiceTriggerLimit& DiceTriggerLimit::parse(const AttrVar& var) { locks.emplace_back(type, k.to_str(), 1); } } - for (auto& [subkey, value] : *item.to_dict()) { + for (auto& [subkey, value] : **item.to_dict()) { if (CDConfig::eType.count(subkey)) { type = (CDType)CDConfig::eType[subkey]; if (value.is_character()) { @@ -446,36 +446,36 @@ DiceTriggerLimit& DiceTriggerLimit::parse(const AttrVar& var) { } else if (key == "user_var") { if (!item.is_table())continue; - string code{ parse_vary(*item.to_dict(), user_vary) }; - if (user_vary.empty())continue; - limits << "user_var:" + code; - ShowList vars; - for (auto& [key, cmpr] : user_vary) { - vars << key + showAttrCMPR(cmpr.first) + cmpr.second.print(); + if (string code{ parse_vary(**item.to_dict(), user_vary) }; !user_vary.empty()) { + limits << "user_var:" + code; + ShowList vars; + for (auto& [key, cmpr] : user_vary) { + vars << key + showAttrCMPR(cmpr.first) + cmpr.second.print(); + } + notes << "- 用户触发阈值: " + vars.show(); } - notes << "- 用户触发阈值: " + vars.show(); } else if (key == "grp_var") { if (!item.is_table())continue; - string code{ parse_vary(*item.to_dict(), grp_vary) }; - if (code.empty())continue; - limits << "grp_var:" + code; - ShowList vars; - for (auto& [key, cmpr] : grp_vary) { - vars << key + showAttrCMPR(cmpr.first) + cmpr.second.print(); + if (string code{ parse_vary(**item.to_dict(), grp_vary) }; !code.empty()) { + limits << "grp_var:" + code; + ShowList vars; + for (auto& [key, cmpr] : grp_vary) { + vars << key + showAttrCMPR(cmpr.first) + cmpr.second.print(); + } + notes << "- 群聊触发阈值: " + vars.show(); } - notes << "- 群聊触发阈值: " + vars.show(); } else if (key == "self_var") { if (!item.is_table())continue; - string code{ parse_vary(*item.to_dict(), self_vary) }; - if (code.empty())continue; - limits << "self_var:" + code; - ShowList vars; - for (auto& [key, cmpr] : self_vary) { - vars << key + showAttrCMPR(cmpr.first) + cmpr.second.print(); + if (string code{ parse_vary(**item.to_dict(), self_vary) }; !code.empty()) { + limits << "self_var:" + code; + ShowList vars; + for (auto& [key, cmpr] : self_vary) { + vars << key + showAttrCMPR(cmpr.first) + cmpr.second.print(); + } + notes << "- 自身触发阈值: " + vars.show(); } - notes << "- 自身触发阈值: " + vars.show(); } else if (key == "dicemaid") { string val{ item.to_str() }; @@ -579,12 +579,12 @@ bool DiceMsgReply::exec(DiceEvent* msg) { if (!limit.check(msg, lock_list))return false; if (type == Type::Reply) { if (!msg->isCalled && (chon < 0 || - (!chon && (msg->pGrp->isset("禁用回复"))))) + (!chon && (msg->pGrp->is("禁用回复"))))) return false; } else { //type == Type::Order if (!msg->isCalled && (chon < 0 || - (!chon && msg->pGrp->isset("停用指令")))) + (!chon && msg->pGrp->is("停用指令")))) return false; } if (msg->WordCensor()) { @@ -658,8 +658,8 @@ string DiceMsgReply::show_ans()const { } void DiceMsgReply::from_obj(AttrObject obj) { - if (obj.is_table("keyword")) { - for (auto& [match, word] : *obj.get_dict("keyword")) { + if (obj->is_table("keyword")) { + for (auto& [match, word] : **obj->get_dict("keyword")) { if (!sMode.count(match))continue; if (word.is_character()) { keyMatch[sMode[match]] = std::make_unique>(vector{ word.to_str() }); @@ -674,10 +674,10 @@ void DiceMsgReply::from_obj(AttrObject obj) { } } } - if (obj.has("type"))type = (Type)sType[obj.get_str("type")]; - if (obj.has("limit"))limit.parse(obj["limit"]); - if (obj.has("echo")) { - AttrVar& ans{ obj["echo"] }; + if (obj->has("type"))type = (Type)sType[obj->get_str("type")]; + if (obj->has("limit"))limit.parse(obj->at("limit")); + if (obj->has("echo")) { + AttrVar& ans{ obj->at("echo") }; if (ans.is_character()) { echo = Echo::Text; answer.set("text", ans); @@ -686,17 +686,17 @@ void DiceMsgReply::from_obj(AttrObject obj) { echo = Echo::Lua; answer.set("lua", ans); } - else if (auto tab{ ans.to_obj() }; tab.has("lua")) { + else if (auto tab{ ans.to_obj() }; tab->has("lua")) { echo = Echo::Lua; - answer = tab; + answer = *tab; } - else if (tab.has("js")) { + else if (tab->has("js")) { echo = Echo::JavaScript; - answer = tab; + answer = *tab; } - else if (tab.has("py")) { + else if (tab->has("py")) { echo = Echo::Python; - answer = tab; + answer = *tab; } else if (auto v{ answer.to_list() }) { auto li{ answer.new_list() }; @@ -736,7 +736,7 @@ void DiceMsgReply::readJson(const fifo_json& j) { if (j.count("limit"))limit.parse(UTF8toGBK(j["limit"].get())); if (j.count("echo"))echo = (Echo)sEcho[j["echo"].get()]; if (j.count("answer")) { - if (echo == Echo::Deck)answer = AttrVar(j["answer"]).to_obj(); + if (echo == Echo::Deck)from_json(j["answer"], answer.as_dict()); else if (echo == Echo::Lua)answer.set("lua", j["answer"]); else if (echo == Echo::JavaScript)answer.set("js", j["answer"]); else if (echo == Echo::Python)answer.set("py", j["answer"]); @@ -757,10 +757,10 @@ fifo_json DiceMsgReply::writeJson()const { if (keyMatch[3])j["regex"] = GBKtoUTF8(*keyMatch[3]); if (!limit.empty())j["limit"] = GBKtoUTF8(limit.print()); if (echo == Echo::Deck)j["answer"] = answer.to_json(); - else if (echo == Echo::Text)j["answer"] = GBKtoUTF8(answer["text"]); - else if (echo == Echo::Lua)j["answer"] = GBKtoUTF8(answer["lua"]); - else if (echo == Echo::JavaScript)j["answer"] = GBKtoUTF8(answer["js"]); - else if (echo == Echo::Python)j["answer"] = GBKtoUTF8(answer["py"]); + else if (echo == Echo::Text)j["answer"] = GBKtoUTF8(answer.get_str("text")); + else if (echo == Echo::Lua)j["answer"] = GBKtoUTF8(answer.get_str("lua")); + else if (echo == Echo::JavaScript)j["answer"] = GBKtoUTF8(answer.get_str("js")); + else if (echo == Echo::Python)j["answer"] = GBKtoUTF8(answer.get_str("py")); return j; } fifo_json DiceMsgReply::to_line()const { diff --git a/Dice/DiceMsgReply.h b/Dice/DiceMsgReply.h index 07caaaea..edaca133 100644 --- a/Dice/DiceMsgReply.h +++ b/Dice/DiceMsgReply.h @@ -44,7 +44,7 @@ class DiceMsgReply { Type type{ Type::Reply }; Echo echo{ Echo::Deck }; DiceTriggerLimit limit; - AttrObject answer; + AnysTable answer; static ptr set_order(const string& key, const AttrVars&); string show()const; string show_ans()const; diff --git a/Dice/DiceMsgSend.cpp b/Dice/DiceMsgSend.cpp index 19f7b19e..11a77ea5 100644 --- a/Dice/DiceMsgSend.cpp +++ b/Dice/DiceMsgSend.cpp @@ -8,6 +8,7 @@ * * Dice! QQ Dice Robot for TRPG * Copyright (C) 2018-2019 w4123溯洄 + * Copyright (C) 2019-2024 String.Empty * * This program is free software: you can redistribute it and/or modify it under the terms * of the GNU Affero General Public License as published by the Free Software Foundation, @@ -41,7 +42,7 @@ chatInfo::chatInfo(long long u, long long g, long long c) :uid(u), gid(g), chid( else type = msgtype::Private; } } -chatInfo::chatInfo(const AttrObject& obj):uid(obj.get_ll("uid")), chid(obj.get_ll("chid")) { +chatInfo::chatInfo(const AnysTable& obj):uid(obj.get_ll("uid")), chid(obj.get_ll("chid")) { type = (gid = obj.get_ll("gid")) ? chid ? msgtype::ChannelPrivate : msgtype::Private : chid ? msgtype::Channel : msgtype::Group; diff --git a/Dice/DiceMsgSend.h b/Dice/DiceMsgSend.h index 35661144..a3cfb05e 100644 --- a/Dice/DiceMsgSend.h +++ b/Dice/DiceMsgSend.h @@ -10,7 +10,7 @@ * * Dice! QQ Dice Robot for TRPG * Copyright (C) 2018-2021 w4123溯洄 - * Copyright (C) 2019-2021 String.Empty + * Copyright (C) 2019-2024 String.Empty * * This program is free software: you can redistribute it and/or modify it under the terms * of the GNU Affero General Public License as published by the Free Software Foundation, @@ -28,7 +28,7 @@ #define DICE_MSG_SEND #include "fifo_json.hpp" -class AttrObject; +class AnysTable; enum class msgtype : int { Private = 0, Group = 1, Discuss = 2, ChannelPrivate = 3, Channel = 4}; struct chatInfo { long long uid{ 0 }; @@ -37,7 +37,7 @@ struct chatInfo { msgtype type{ 0 }; chatInfo() {} chatInfo(long long, long long = 0, long long = 0); - chatInfo(const AttrObject&); + chatInfo(const AnysTable&); bool operator<(const chatInfo&)const; bool operator==(const chatInfo&)const; operator bool()const { return uid || gid || chid; } diff --git a/Dice/DiceNetwork.cpp b/Dice/DiceNetwork.cpp index ed470fdf..5ee64655 100644 --- a/Dice/DiceNetwork.cpp +++ b/Dice/DiceNetwork.cpp @@ -8,6 +8,7 @@ * * Dice! QQ Dice Robot for TRPG * Copyright (C) 2018-2019 w4123溯洄 + * Copyright (C) 2019-2024 String.Empty * * This program is free software: you can redistribute it and/or modify it under the terms * of the GNU Affero General Public License as published by the Free Software Foundation, @@ -174,7 +175,7 @@ namespace Network } if (dwRetCode != 200) { - des = getMsg("strRequestRetCodeErr", AttrVars{ {"error", std::to_string(dwRetCode)} }); + des = getMsg("strRequestRetCodeErr", AnysTable{ {"error", std::to_string(dwRetCode)} }); goto InternetClose; } DWORD preRcvCnt; @@ -318,7 +319,7 @@ namespace Network } if (dwRetCode != 200) { - des = getMsg("strRequestRetCodeErr", AttrVars{ {"error", std::to_string(dwRetCode)} }); + des = getMsg("strRequestRetCodeErr", AnysTable{ {"error", std::to_string(dwRetCode)} }); InternetCloseHandle(hRequest); InternetCloseHandle(hConnect); InternetCloseHandle(hInternet); diff --git a/Dice/DicePython.cpp b/Dice/DicePython.cpp index 0803c3d5..4ff292f8 100644 --- a/Dice/DicePython.cpp +++ b/Dice/DicePython.cpp @@ -161,23 +161,23 @@ PyObject* py_build_attr(const AttrVar& var) { return PyUnicode_FromString(GBKtoUTF8(var.text).c_str()); break; case AttrVar::Type::Table: - if (!var.table.to_dict()->empty()) { + if (!var.table->empty()) { auto dict = PyDict_New(); - if (var.table.to_list()) { + if (var.table->to_list()) { long idx{ 0 }; - for (auto& val : *var.table.to_list()) { + for (auto& val : *var.table->to_list()) { PyDict_SetItem(dict, PyLong_FromLong(idx++), py_build_attr(val)); } } - for (auto& [key, val] : *var.table.to_dict()) { + for (auto& [key, val] : var.table->as_dict()) { PyDict_SetItem(dict, py_from_gbstring(key), py_build_attr(val)); } return dict; } - else if (var.table.to_list()) { - auto ary = PyList_New(var.table.to_list()->size()); + else if (var.table->to_list()) { + auto ary = PyList_New(var.table->to_list()->size()); Py_ssize_t i{ 0 }; - for (auto& val : *var.table.to_list()) { + for (auto& val : *var.table->to_list()) { PyList_SetItem(ary, i++, py_build_attr(val)); } return ary; @@ -384,22 +384,22 @@ void PyGameTable_dealloc(PyObject* o) { } int PyGameTable_setattr(PyObject* self, char* attr, PyObject* val) { PY2GAME(self); - if (game)game->attrs.set(UTF8toGBK(attr), py_to_attr(val)); + if (game)game->set(UTF8toGBK(attr), py_to_attr(val)); return 0; } static Py_ssize_t pyGameTable_size(PyObject* self) { PY2GAME(self); - return game ? (Py_ssize_t)game->attrs.size() : 0; + return game ? (Py_ssize_t)game->size() : 0; } PyObject* PyGameTable_getattro(PyObject* self, PyObject* attr) { PY2GAME(self); string key{ py_to_gbstring(attr) }; - return game ? py_build_attr(game->attrs.get(key)) : NULL; + return game ? py_build_attr(game->get(key)) : NULL; } int PyGameTable_setattro(PyObject* self, PyObject* attr, PyObject* val) { PY2GAME(self); string key{ py_to_gbstring(attr) }; - if (game)game->attrs.set(key, py_to_attr(val)); + if (game)game->set(key, py_to_attr(val)); return 0; } static PyMappingMethods PyGameTableMappingMethods = { @@ -491,24 +491,24 @@ void PyContext_dealloc(PyObject* o) { PyObject* py_newContext(const AttrObject& obj); int PyContext_setattr(PyObject* self, char* attr, PyObject* val) { AttrObject& obj{ ((PyContextObject*)self)->obj }; - obj.set(UTF8toGBK(attr), py_to_attr(val)); + obj->set(UTF8toGBK(attr), py_to_attr(val)); return 0; } PyObject* PyContext_getattro(PyObject* self, PyObject* attr) { AttrObject& obj{ ((PyContextObject*)self)->obj }; string key{ py_to_gbstring(attr) }; //console.log("PyContext_getattro:" + key, 0); - if (key == "user" && obj.has("uid")) { - return py_newContext(getUser(obj.get_ll("uid")).confs); + if (key == "user" && obj->has("uid")) { + return py_newContext(getUser(obj->get_ll("uid")).shared_from_this()); } - else if ((key == "grp" || key == "group") && obj.has("gid")) { - return py_newContext(chat(obj.get_ll("gid")).confs); + else if ((key == "grp" || key == "group") && obj->has("gid")) { + return py_newContext(chat(obj->get_ll("gid")).shared_from_this()); } - else if (key == "pc" && obj.has("uid")) { - return py_newActor(getPlayer(obj.get_ll("uid"))[obj.get_ll("gid")]); + else if (key == "pc" && obj->has("uid")) { + return py_newActor(getPlayer(obj->get_ll("uid"))[obj->get_ll("gid")]); } else if (key == "game") { - if (auto game = sessions.get_if(obj)) { + if (auto game = sessions.get_if(*obj)) { return py_newGame(game); } } @@ -517,7 +517,7 @@ PyObject* PyContext_getattro(PyObject* self, PyObject* attr) { int PyContext_setattro(PyObject* self, PyObject* attr, PyObject* val) { AttrObject& obj{ ((PyContextObject*)self)->obj }; string key{ py_to_gbstring(attr) }; - obj.set(key, py_to_attr(val)); + obj->set(key, py_to_attr(val)); return 0; } static PyObject* pyContext_echo(PyObject* self, PyObject* args) { @@ -545,7 +545,7 @@ static PyObject* pyContext_inc(PyObject* self, PyObject* args) { if (!PyArg_ParseTuple(args, "s|i", &field, &cnt)) { return nullptr; } - return PyLong_FromSsize_t(obj.inc(UTF8toGBK(field, cnt))); + return PyLong_FromSsize_t(obj->inc(UTF8toGBK(field, cnt))); } static PyMethodDef ContextMethods[] = { {"echo", pyContext_echo, METH_VARARGS, "echo message"}, @@ -692,23 +692,23 @@ void PySelfData_dealloc(PyObject* o) { } PyObject* PySelfData_getattr(PyObject* self, char* attr) { auto& data{ ((PySelfDataObject*)self)->p->data }; - return data.is_table() ? py_build_attr(data.table.get(UTF8toGBK(attr))) : Py_BuildValue(""); + return data.is_table() ? py_build_attr(data.table->get(UTF8toGBK(attr))) : Py_BuildValue(""); } int PySelfData_setattr(PyObject* self, char* attr, PyObject* val) { auto& data{ ((PySelfDataObject*)self)->p->data }; - if (data.is_table())data.table.set(UTF8toGBK(attr), py_to_attr(val)); + if (data.is_table())data.table->set(UTF8toGBK(attr), py_to_attr(val)); return 0; } PyObject* PySelfData_getattro(PyObject* self, PyObject* attr) { auto& data{ ((PySelfDataObject*)self)->p }; if (!attr)return py_build_attr(data->data); string key{ py_to_gbstring(attr) }; - return data && data->data.is_table() ? py_build_attr(data->data.table.get(key)) : Py_BuildValue(""); + return data && data->data.is_table() ? py_build_attr(data->data.table->get(key)) : Py_BuildValue(""); } int PySelfData_setattro(PyObject* self, PyObject* attr, PyObject* val) { auto& data{ ((PySelfDataObject*)self)->p->data }; string key{ py_to_gbstring(attr) }; - if (data.is_table())data.table.set(key, py_to_attr(val)); + if (data.is_table())data.table->set(key, py_to_attr(val)); return 0; } static Py_ssize_t pySelfData_size(PyObject* self) { @@ -720,7 +720,7 @@ PyObject* PySelfData_set(PyObject* self, PyObject* args) { PyObject* item{ nullptr }, * val{ nullptr }; if (PyArg_ParseTuple(args, "O|O", &item, &val)) { if (Py_IS_TYPE(item, &PyUnicode_Type) && data->data.is_table()) { - data->data.table.set(py_to_gbstring(item), py_to_attr(val)); + data->data.table->set(py_to_gbstring(item), py_to_attr(val)); data->save(); } else if (!val) { @@ -810,7 +810,7 @@ PYDEFKEY(getGroupAttr) { } auto items{ PyDict_New() }; for (auto& [gid, data] : ChatList) { - if (data.confs.has(item))PyDict_SetItem(items, PyLong_FromLongLong(gid), py_build_attr(data.confs.get(item))); + if (data->has(item))PyDict_SetItem(items, PyLong_FromLongLong(gid), py_build_attr(data->get(item))); } return items; } @@ -819,7 +819,7 @@ PYDEFKEY(getGroupAttr) { PyErr_SetString(PyExc_ValueError, "group id can't be zero"); return NULL; } - if (item.empty()) return py_newContext(chat(gid).confs); + if (item.empty()) return py_newContext(chat(gid).shared_from_this()); else if (item == "members") { if (Py_IS_TYPE(sub, &PyUnicode_Type)) { string subitem{ py_to_gbstring(sub)}; @@ -907,7 +907,7 @@ PYDEFKEY(getUserAttr) { } auto items{ PyDict_New() }; for (auto& [uid, data] : UserList) { - if (data.confs.has(item))PyDict_SetItem(items, PyLong_FromLongLong(uid), py_build_attr(data.confs.get(item))); + if (data->has(item))PyDict_SetItem(items, PyLong_FromLongLong(uid), py_build_attr(data->get(item))); } return items; } @@ -916,7 +916,7 @@ PYDEFKEY(getUserAttr) { PyErr_SetString(PyExc_ValueError, "uid can't be zero"); return NULL; } - if (item.empty()) return py_newContext(getUser(uid).confs); + if (item.empty()) return py_newContext(getUser(uid).shared_from_this()); if (auto val{ getUserItem(uid,item) }; !val.is_null())return py_build_attr(val); else return sub ? sub : Py_BuildValue(""); } @@ -975,7 +975,7 @@ PYDEFKEY(getUserToday) { } auto items{ PyDict_New() }; for (auto& [uid, data] : today->getUserInfo()) { - if (data.has(item))PyDict_SetItem(items, PyLong_FromLongLong(uid), py_build_attr(data.get(item))); + if (data->has(item))PyDict_SetItem(items, PyLong_FromLongLong(uid), py_build_attr(data->get(item))); } return items; } @@ -1040,16 +1040,16 @@ PYDEFKEY(sendMsg) { AttrObject chat; if (Py_IS_TYPE(msg, &PyUnicode_Type)) { chat = py_to_obj(msg); - AddMsgToQueue(fmt->format(chat.get_str("fwdMsg"), chat), chatInfo{ chat.get_ll("uid") ,chat.get_ll("gid") ,chat.get_ll("chid") }); + AddMsgToQueue(fmt->format(chat->get_str("fwdMsg"), chat), chatInfo{ chat->get_ll("uid") ,chat->get_ll("gid") ,chat->get_ll("chid") }); } else { if (!gid && !uid) { PyErr_SetString(PyExc_ValueError, "chat id can't be zero"); return NULL; } - if (uid)chat["uid"] = uid; - if (gid)chat["gid"] = gid; - if (chid)chat["chid"] = chid; + if (uid)chat->at("uid") = uid; + if (gid)chat->at("gid") = gid; + if (chid)chat->at("chid") = chid; AddMsgToQueue(fmt->format(py_to_gbstring(msg), chat), { uid,gid,chid }); } return Py_BuildValue(""); @@ -1071,11 +1071,11 @@ PYDEFKEY(eventMsg) { else { string fromMsg{ py_to_gbstring(msg)}; eve = gid - ? AttrVars{ {"fromMsg",fromMsg},{"gid",gid}, {"uid", uid} } - : AttrVars{ {"fromMsg",fromMsg}, {"uid", uid} }; + ? AnysTable{ { {"fromMsg",fromMsg},{"gid",gid}, {"uid", uid} } } + : AnysTable{ { {"fromMsg",fromMsg}, {"uid", uid} } }; } std::thread th([=]() { - DiceEvent msg(eve); + DiceEvent msg(*eve); msg.virtualCall(); }); th.detach(); diff --git a/Dice/DiceRule.h b/Dice/DiceRule.h index d0a118b4..fb59afd0 100644 --- a/Dice/DiceRule.h +++ b/Dice/DiceRule.h @@ -9,7 +9,7 @@ class DiceRule { void clear() { subrules.clear(); } - dict_ci> cassettes; + dict_ci cassettes; public: ptr meta; dict_ci> subrules; diff --git a/Dice/DiceSchedule.cpp b/Dice/DiceSchedule.cpp index d5449dae..75760445 100644 --- a/Dice/DiceSchedule.cpp +++ b/Dice/DiceSchedule.cpp @@ -42,13 +42,13 @@ std::priority_queue,std::greater> std::mutex mtJobWaited; void exec(AttrObject& job) { - if (job.has("cmd")) { - if (auto it = mCommand.find(job.get_str("cmd")); it != mCommand.end()) { + if (job->has("cmd")) { + if (auto it = mCommand.find(job->get_str("cmd")); it != mCommand.end()) { it->second(job); } } - else if (job.has("id")) { - fmt->call_cycle_event(job.get_str("id")); + else if (job->has("id")) { + fmt->call_cycle_event(job->get_str("id")); } } void jobHandle() { @@ -98,7 +98,7 @@ void DiceScheduler::push_job(const char* job_name, bool isSelf, const AttrVars& { std::unique_lock lock_queue(mtQueueJob); AttrObject obj{ vars }; - obj["cmd"] = job_name; + obj->at("cmd") = job_name; queueJob.emplace(obj); } //cvJob.notify_one(); @@ -177,18 +177,18 @@ void DiceScheduler::end() { } AttrVar DiceToday::getJrrp(long long uid) { - if (UserInfo.count(uid) && UserInfo[uid].has("jrrp")) + if (UserInfo.count(uid) && UserInfo[uid]->has("jrrp")) return UserInfo[uid]["jrrp"]; string frmdata = "QQ=" + to_string(console.DiceMaid) + "&v=20190114" + "&QueryQQ=" + to_string(uid); string res; if (Network::POST("http://api.kokona.tech:5555/jrrp", frmdata, "", res)) { - return UserInfo[uid]["jrrp"] = stoi(res); + return UserInfo[uid]->at("jrrp") = stoi(res); } else { - if (!UserInfo[uid].has("jrrp_local")) { - UserInfo[uid]["jrrp_local"] = RandomGenerator::Randint(1, 100); + if (!UserInfo[uid]->has("jrrp_local")) { + UserInfo[uid]->at("jrrp_local") = RandomGenerator::Randint(1, 100); console.log(getMsg("strJrrpErr", - AttrVars{ {"res", res} } + AnysTable{ {"res", res} } ), 0); } return UserInfo[uid]["jrrp_local"]; @@ -205,7 +205,7 @@ void DiceToday::daily_clear() { localtime_r(&tt, &newDay); #endif if (stToday.tm_mday != newDay.tm_mday) { - fmt->call_hook_event(AttrVars{ { + fmt->call_hook_event(AnysTable{ { {"Event","DayEnd"}, {"year",stToday.tm_year + 1900}, {"month",stToday.tm_mon + 1}, @@ -219,7 +219,7 @@ void DiceToday::daily_clear() { UserInfo.clear(); pathFile = DiceDir / "user" / "daily" / ("daily_" + printDate() + ".json"); - fmt->call_hook_event(AttrVars{ { + fmt->call_hook_event(AnysTable{ { {"Event","DayNew"}, {"year",newDay.tm_year + 1900}, {"month",newDay.tm_mon + 1}, @@ -229,9 +229,9 @@ void DiceToday::daily_clear() { } void DiceToday::set(long long qq, const string& key, const AttrVar& val) { if (val) - UserInfo[qq].set(key, val); - else if (UserInfo.count(qq) && UserInfo[qq].has(key)) { - UserInfo[qq].reset(key); + UserInfo[qq]->set(key, val); + else if (UserInfo.count(qq) && UserInfo[qq]->has(key)) { + UserInfo[qq]->reset(key); } else return; save(); @@ -246,7 +246,7 @@ void DiceToday::save() { if (!UserInfo.empty()) { fifo_json& jCnt{ jFile["user"] = fifo_json::object() }; for (auto& [id, user] : UserInfo) { - jCnt[to_string(id)] = user.to_json(); + jCnt[to_string(id)] = user->to_json(); } } if (!counter.empty()) { diff --git a/Dice/DiceSchedule.h b/Dice/DiceSchedule.h index d9025993..084dd55c 100644 --- a/Dice/DiceSchedule.h +++ b/Dice/DiceSchedule.h @@ -82,15 +82,15 @@ class DiceToday { void load(); void save(); void set(long long qq, const string& key, const AttrVar& val); - void inc(const string& key) { UserInfo[0].inc(key); save(); } + void inc(const string& key) { UserInfo[0]->inc(key); save(); } //void inc(long long qq, const string& key, int cnt = 1) { cntUser[qq][key] += cnt; save(); } unordered_map& getUserInfo() { return UserInfo; } - AttrVar& get(const string& key) { return UserInfo[0].at(key); } + AttrVar& get(const string& key) { return UserInfo[0]->at(key); } AttrObject& get(long long uid) { return UserInfo[uid]; } //AttrVar& get(long long uid, const string& key) { return UserInfo[uid].to_dict()[key]; } std::optional get_if(long long qq, const string& key) { - if (UserInfo.count(qq) && UserInfo[qq].has(key)) - return UserInfo[qq].at(key); + if (UserInfo.count(qq) && UserInfo[qq]->has(key)) + return UserInfo[qq]->at(key); else return std::nullopt; } AttrVar getJrrp(long long); diff --git a/Dice/DiceSelfData.cpp b/Dice/DiceSelfData.cpp index 9dd06474..af249f0e 100644 --- a/Dice/DiceSelfData.cpp +++ b/Dice/DiceSelfData.cpp @@ -40,7 +40,7 @@ void SelfData::save() { break; case Toml: if (std::ofstream fs{ pathFile }) { - if (data.is_table())fs << data.to_obj().to_toml(); + if (data.is_table())fs << data.to_obj()->to_toml(); else fs << data.to_json(); } break; diff --git a/Dice/DiceSession.cpp b/Dice/DiceSession.cpp index 45100638..80a7692f 100644 --- a/Dice/DiceSession.cpp +++ b/Dice/DiceSession.cpp @@ -33,7 +33,7 @@ size_t DiceSession::roll(size_t face) { string DiceSession::show()const { ShowList li; li << "桌号: " + name; - if (attrs.has("rule"))li << "规则: " + attrs.get_str("rule"); + if (has("rule"))li << "规则: " + get_str("rule"); if (is_logging())li << "日志记录中:" + logger.name; if (!master->empty()) { ShowList sub; @@ -66,34 +66,34 @@ string DiceSession::show()const { return li.show("\n"); } bool DiceSession::hasAttr(const string& key) { - return attrs.has(key); + return has(key); } AttrVar DiceSession::getAttr(const string& key) { - return attrs.get(key); + return get(key); } bool DiceSession::table_del(const string& tab, const string& item) { - if (!attrs.has(tab) || !attrs.get_obj(tab).has(item))return false; - attrs.get_obj(tab).reset(item); + if (!has(tab) || !get_obj(tab)->has(item))return false; + get_obj(tab)->reset(item); update(); return true; } bool DiceSession::table_add(const string& tab, int prior, const string& item) { - if (!attrs.has(tab))attrs.set(tab, AttrObject()); - attrs.get_obj(tab).set(item,prior); + if (!has(tab))set(tab, AttrObject()); + get_obj(tab)->set(item,prior); update(); return true; } string DiceSession::table_prior_show(const string& tab) const{ - return attrs.is_table(tab) ? PriorList(*attrs.get_dict(tab)).show() : ""; + return is_table(tab) ? PriorList(**get_dict(tab)).show() : ""; } bool DiceSession::table_clr(const string& tab) { - if (attrs.has(tab)){ - attrs.reset(tab); + if (has(tab)){ + reset(tab); update(); return true; } @@ -538,7 +538,7 @@ void DiceSession::deck_new(DiceEvent* msg) { } string DiceSession::deck_draw(const string& key) { if (decks.count(key)) { - if (!decks[key].sizRes)return getMsg("strDeckRestEmpty", AttrVars{ {"deck_name",key} }); + if (!decks[key].sizRes)return getMsg("strDeckRestEmpty", AnysTable{ {"deck_name",key} }); return decks[key].draw(); } else if (CardDeck::mPublicDeck.count(key)) { @@ -660,9 +660,9 @@ void DiceSession::save() const std::filesystem::create_directories(DiceDir / "user" / "session", ec); std::filesystem::path fpFile{ DiceDir / "user" / "session" / (name + ".json") }; fifo_json jData; - if (!master->empty())jData["master"] = to_json(*master); - if (!player->empty())jData["player"] = to_json(*player); - if (!obs->empty())jData["observer"] = to_json(*obs); + if (!master->empty())jData["master"] = ::to_json(*master); + if (!player->empty())jData["player"] = ::to_json(*player); + if (!obs->empty())jData["observer"] = ::to_json(*obs); if (logger.tStart || !logger.fileLog.empty()) { fifo_json jLog; jLog["start"] = logger.tStart; @@ -694,7 +694,7 @@ void DiceSession::save() const } jData["roulette"] = jDecks; } - if (!attrs.empty())jData["data"] = attrs.to_json(); + if (!empty())jData["data"] = to_json(); std::lock_guard lock(exSessionSave); if (jData.empty()) { remove(fpFile); @@ -702,7 +702,7 @@ void DiceSession::save() const } auto& jChat{ jData["chats"] = fifo_json::array() }; for (const auto& chat : areas) { - jChat.push_back(to_json(chat)); + jChat.push_back(::to_json(chat)); } jData["create_time"] = tCreate; jData["update_time"] = tUpdate; @@ -777,7 +777,7 @@ int DiceSessionManager::load() { if (auto fileGM{ DiceDir / "user" / "GameTable.toml" };std::filesystem::exists(fileGM)) { if (ifstream ifs{ fileGM }) { AttrObject cfg = AttrVar(toml::parse(ifs)).to_obj(); - inc = cfg.get_int("inc"); + inc = cfg->get_int("inc"); } } LOCK_REC(sessionMutex); @@ -811,7 +811,7 @@ int DiceSessionManager::load() { pSession->areas.insert(chatInfo::from_json(ct)); } } - if (j.count("conf")) pSession->attrs = AttrVar(j["conf"]).to_obj(); + if (j.count("conf")) from_json(j["conf"], pSession->dict); if (j.count("log")) { fifo_json& jLog = j["log"]; jLog["start"].get_to(pSession->logger.tStart); @@ -857,10 +857,10 @@ int DiceSessionManager::load() { it.value()["pool"].get>(), it.value()["rest"])); } if (j.count("tables"))for (auto& it : j["tables"].items()) { - pSession->attrs.set(UTF8toGBK(it.key()), it.value()); + pSession->set(UTF8toGBK(it.key()), it.value()); } if (j.count("data"))for (auto& it : j["data"].items()) { - pSession->attrs.set(UTF8toGBK(it.key()), it.value()); + pSession->set(UTF8toGBK(it.key()), it.value()); } if (j.count("master"))for (auto& it : j["master"]) { pSession->master->emplace(it.get()); @@ -893,6 +893,6 @@ int DiceSessionManager::load() { void DiceSessionManager::save() { if (std::ofstream fs{ DiceDir / "user" / "GameTable.toml" }) { AttrObject cfg = AttrVars{ { "inc",inc } }; - fs << cfg.to_toml(); + fs << cfg->to_toml(); } } \ No newline at end of file diff --git a/Dice/DiceSession.h b/Dice/DiceSession.h index a12bcf3e..a281133b 100644 --- a/Dice/DiceSession.h +++ b/Dice/DiceSession.h @@ -88,7 +88,7 @@ struct DiceRoulette { string hist(); }; -class DiceSession{ +class DiceSession: public AnysTable{ //管理员 AttrSet master; //玩家 @@ -101,8 +101,6 @@ class DiceSession{ dict_ci decks; void save() const; public: - //数值表 - AttrObject attrs; //native filename const string name; fifo_set areas; @@ -132,8 +130,7 @@ class DiceSession{ return *this; } - DiceSession& update() - { + DiceSession& update(){ tUpdate = time(nullptr); save(); return *this; @@ -141,13 +138,16 @@ class DiceSession{ string show()const; bool hasAttr(const string& key); AttrVar getAttr(const string& key); - void setAttr(const string& key, const AttrVar& val) { - attrs.set(key, val); - update(); + void set(const string& key, const AttrVar& val){ + if (!key.empty()) { + if (val.is_null())dict.erase(key); + else dict[key] = val; + update(); + } } - void rmAttr(const string& key) { - if (attrs.has(key)) { - attrs.reset(key); + void reset(const string& key){ + if (dict.count(key)) { + dict.erase(key); update(); } } @@ -187,7 +187,6 @@ class DiceSession{ return true; } - [[nodiscard]] bool table_count(const string& key) const { return attrs.has(key); } bool table_del(const string&, const string&); bool table_add(const string&, int, const string&); [[nodiscard]] string table_prior_show(const string& key) const; diff --git a/Dice/GlobalVar.cpp b/Dice/GlobalVar.cpp index f35dbd8a..d8082d1b 100644 --- a/Dice/GlobalVar.cpp +++ b/Dice/GlobalVar.cpp @@ -975,7 +975,7 @@ const dict_ci<> HelpDoc = { {"世界逆位", "未完成、失败、准备不足、盲目接受、一时不顺利、半途而废、精神颓废、饱和状态、合谋、态度不够融洽、感情受挫。"}, }; -const std::string getMsg(const std::string& key, AttrObject maptmp){ +const std::string getMsg(const std::string& key, const AttrObject& maptmp){ return fmt->format(fmt->msg_get(key), maptmp); } const std::string getComment(const std::string& key) { diff --git a/Dice/GlobalVar.h b/Dice/GlobalVar.h index b6ebb83b..bb9017f5 100644 --- a/Dice/GlobalVar.h +++ b/Dice/GlobalVar.h @@ -101,7 +101,7 @@ extern const dict_ci GlobalComment; extern const dict_ci HelpDoc; // 修改后的帮助文档 extern fifo_dict_ci CustomHelp; -const std::string getMsg(const std::string& key, AttrObject tmp = {}); +const std::string getMsg(const std::string& key, const AttrObject& tmp = {}); const std::string getComment(const std::string& key); #endif /*DICE_GLOBAL_VAR*/ diff --git a/Dice/ManagerSystem.cpp b/Dice/ManagerSystem.cpp index 884e4864..543b28ae 100644 --- a/Dice/ManagerSystem.cpp +++ b/Dice/ManagerSystem.cpp @@ -43,8 +43,8 @@ const map mChatConf{ User& getUser(long long uid){ if (TinyList.count(uid))uid = TinyList[uid]; - if (!UserList.count(uid))UserList[uid].id(uid); - return UserList[uid]; + if (!UserList.count(uid))UserList.emplace(uid,std::make_shared(uid)); + return *UserList[uid]; } AttrVar getUserItem(long long uid, const string& item) { if (!uid)return {}; @@ -87,8 +87,8 @@ AttrVar getUserItem(long long uid, const string& item) { } if (user.getNick(nick, gid))return nick; } - else if (user.isset(item)) { - return user.confs.get(item); + else if (user.is(item)) { + return user.get(item); } } if (item == "gender") { @@ -143,8 +143,8 @@ AttrVar getGroupItem(long long id, const string& item) { else if (item == "lastUpdate") { return (long long)grp.updated(); } - else if (grp.confs.has(item)) { - return grp.confs.get(item); + else if (grp.has(item)) { + return grp.get(item); } } else if (item == "name") { @@ -162,7 +162,7 @@ AttrVar getSelfItem(string item) { while (!(sub = splitOnce(item)).empty()) { file += sub; if (selfdata_byStem.count(file) - && !(var = selfdata_byStem[file]->data.to_obj().index(item)).is_null()) { + && !(var = selfdata_byStem[file]->data.to_obj()->index(item)).is_null()) { return var; } file += "."; @@ -170,20 +170,20 @@ AttrVar getSelfItem(string item) { } return var; } -AttrVar getContextItem(AttrObject context, string item, bool isTrust) { +AttrVar getContextItem(const AttrObject& context, string item, bool isTrust) { if (item.empty())return context; AttrVar var; if (item[0] == '&')item = fmt->format(item, context); string sub; - if (!context.empty()) { - if (context.has(item))return context.get(item); + if (!context->empty()) { + if (context->has(item))return context->get(item); if (MsgIndexs.count(item))return MsgIndexs[item](context); if (item.find(':') <= item.find('.'))return var; if (!(sub = splitOnce(item)).empty()) { - if (context.has(sub) && context.is_table(sub)) - return getContextItem(context.get_obj(sub), item); - if (sub == "user")return getUserItem(context.get_ll("uid"), item); - if (isTrust && (sub == "grp" || sub == "group"))return getGroupItem(context.get_ll("gid"), item); + if (context->has(sub) && context->is_table(sub)) + return getContextItem(context->get_obj(sub), item); + if (sub == "user")return getUserItem(context->get_ll("uid"), item); + if (isTrust && (sub == "grp" || sub == "group"))return getGroupItem(context->get_ll("gid"), item); } } if (isTrust) { @@ -192,27 +192,27 @@ AttrVar getContextItem(AttrObject context, string item, bool isTrust) { return item.empty() ? AttrVar(getMsg("strSelfCall")) : getSelfItem(item); } else if (selfdata_byStem.count(sub)) { - var = selfdata_byStem[sub]->data.to_obj().index(item); + var = selfdata_byStem[sub]->data.to_obj()->index(item); } } return var; } [[nodiscard]] bool User::empty() const { - return (!nTrust) && (!updated()) && confs.empty() && strNick.empty(); + return (!nTrust) && (!updated()) && empty() && strNick.empty(); } void User::setConf(const string& key, const AttrVar& val) { if (key.empty())return; std::lock_guard lock_queue(ex_user); - if (val)confs.set(key, val); - else confs.reset(key); + if (val)set(key, val); + else reset(key); } void User::rmConf(const string& key) { if (key.empty())return; std::lock_guard lock_queue(ex_user); - confs.reset(key); + reset(key); } bool User::getNick(string& nick, long long group) const @@ -231,13 +231,13 @@ bool User::getNick(string& nick, long long group) const void User::writeb(std::ofstream& fout) { std::lock_guard lock_queue(ex_user); - confs.set("trust", (int)nTrust); - confs.set("tCreated", (long long)tCreated); + set("trust", (int)nTrust); + set("tCreated", (long long)tCreated); fwrite(fout, string("ID")); fwrite(fout, ID); - if (!confs.empty()) { + if (!empty()) { fwrite(fout, string("Conf")); - confs.writeb(fout); + writeb(fout); } if (!strNick.empty()) { fwrite(fout, string("Nick")); @@ -252,12 +252,12 @@ void User::old_readb(std::ifstream& fin) map intConf; fread(fin, intConf); for (auto& [key, val] : intConf) { - confs.set(key, val); + set(key, val); } map strConf; fread(fin, strConf); for (auto& [key, val] : strConf) { - confs.set(key, val); + set(key, val); } fread(fin, strNick); } @@ -267,19 +267,19 @@ void User::readb(std::ifstream& fin) string tag; while ((tag = fread(fin)) != "END") { if (tag == "ID")ID = fread(fin); - else if (tag == "Conf")confs.readb(fin); + else if (tag == "Conf")readb(fin); else if (tag == "Nick")fread(fin, strNick); } - nTrust = confs.get_int("trust"); - if (confs.has("tCreated"))tCreated = confs.get_ll("tCreated"); - if (confs.has("tinyID"))TinyList.emplace(confs.get_ll("tinyID"), ID); + nTrust = get_int("trust"); + if (has("tCreated"))tCreated = get_ll("tCreated"); + if (has("tinyID"))TinyList.emplace(get_ll("tinyID"), ID); } int trustedQQ(long long uid){ if (TinyList.count(uid))uid = TinyList[uid]; if (uid == console)return 256; if (uid == console.DiceMaid)return 255; else if (!UserList.count(uid))return 0; - else return UserList[uid].nTrust; + else return UserList[uid]->nTrust; } int clearUser() { @@ -288,13 +288,13 @@ int clearUser() { time_t userline{ tNow - console["InactiveUserLine"] * (time_t)86400 }; bool isClearInactive{ console["InactiveUserLine"] > 0 }; for (const auto& [uid, user] : UserList) { - if (user.nTrust > 0 || console.is_self(uid))continue; - if (user.empty()) { + if (user->nTrust > 0 || console.is_self(uid))continue; + if (user->empty()) { UserDelete.push_back(uid); } else if (isClearInactive) { - time_t tLast{ user.updated() }; - if (!tLast)tLast = user.tCreated; + time_t tLast{ user->updated() }; + if (!tLast)tLast = user->tCreated; if (auto s{ sessions.get_if({ uid }) }) tLast = s->tUpdate > tLast ? s->tUpdate : tLast; if (tLast >= userline)continue; @@ -316,8 +316,8 @@ int clearGroup() { time_t tNow{ time(nullptr) }; time_t grpline{ tNow - console["InactiveGroupLine"] * (time_t)86400 }; for (const auto& [id, grp] : ChatList) { - if (grp.is_except() || grp.isset("免清") || grp.isset("忽略"))continue; - time_t tLast{ grp.updated() }; + if (grp->is_except() || grp->is("免清") || grp->is("忽略"))continue; + time_t tLast{ grp->updated() }; if (auto s{ sessions.get_if({ 0,id }) }) tLast = s->tUpdate > tLast ? s->tUpdate : tLast; if (tLast && tLast < grpline)GrpDelete.push_back(id); @@ -374,12 +374,12 @@ string getName(long long uid, long long GroupID){ // Unknown return (UserList.count(uid) ? getMsg("strCallUser") : getMsg("stranger")) + "(" + to_string(uid) + ")"; } -AttrVar idx_nick(AttrObject& eve) { - if (eve.has("nick"))return eve["nick"]; - if (!eve.has("uid"))return {}; - long long uid{ eve.get_ll("uid") }; - long long gid{ eve.get_ll("gid") }; - return eve["nick"] = getName(uid, gid); +AttrVar idx_nick(const AttrObject& eve) { + if (eve->has("nick"))return eve->get("nick"); + if (!eve->has("uid"))return {}; + long long uid{ eve->get_ll("uid") }; + long long gid{ eve->get_ll("gid") }; + return eve->at("nick") = getName(uid, gid); } string filter_CQcode(const string& raw, long long fromGID){ @@ -504,43 +504,38 @@ string forward_filter(const string& raw, long long fromGID) { Chat& chat(long long id) { - if (!ChatList.count(id))ChatList[id].id(id); - return ChatList[id]; -} -Chat& Chat::id(long long grp) { - ID = grp; - Name = DD::getGroupName(grp); - if (!Enabled)return *this; - return *this; + if (!ChatList.count(id)) { + ChatList.emplace(id, std::make_shared(id)); + } + return *ChatList[id]; } void Chat::leave(const string& msg) { if (!msg.empty()) { - if (isGroup)DD::sendGroupMsg(ID, msg); - else DD::sendDiscussMsg(ID, msg); + DD::sendGroupMsg(ID, msg); std::this_thread::sleep_for(500ms); } - isGroup ? DD::setGroupLeave(ID) : DD::setDiscussLeave(ID); + DD::setGroupLeave(ID); reset("已入群").rmLst(); } bool Chat::is_except()const { - return confs.has("免黑") || confs.has("协议无效"); + return has("免黑") || has("协议无效"); } void Chat::writeb(std::ofstream& fout) { - confs["Name"] = Name; - confs["inviter"] = (long long)inviter; - confs["tCreated"] = (long long)tCreated; + dict["Name"] = Name; + dict["inviter"] = (long long)inviter; + dict["tCreated"] = (long long)tCreated; fwrite(fout, ID); if (!Name.empty()) { fwrite(fout, static_cast(0)); fwrite(fout, Name); } - if (!confs.empty()) + if (!empty()) { fwrite(fout, static_cast(10)); - confs.writeb(fout); + writeb(fout); } if (!ChConf.empty()) { @@ -563,21 +558,21 @@ void Chat::readb(std::ifstream& fin) break; case 1: for (auto& key : fread(fin)) { - confs.set(key, true); + set(key, true); } break; case 2: for (auto& [key, val] : fread(fin)) { - confs.set(key, val); + set(key, val); } break; case 3: for (auto& [key, val] : fread(fin)) { - confs.set(key, val); + set(key, val); } break; case 10: - confs.readb(fin); + readb(fin); break; case 20: fread(fin, ChConf); @@ -587,21 +582,18 @@ void Chat::readb(std::ifstream& fin) } tag = fread(fin); } - if (confs.has("Name"))Name = confs.get_str("Name"); - inviter = confs.get_ll("inviter"); - if (confs.has("tCreated"))tCreated = confs.get_ll("tCreated"); + if (has("Name"))Name = get_str("Name"); + inviter = get_ll("inviter"); + if (has("tCreated"))tCreated = get_ll("tCreated"); } int groupset(long long id, const string& st){ - return ChatList.count(id) ? ChatList[id].isset(st) : -1; + return ChatList.count(id) ? ChatList[id]->is(st) : -1; } -string printChat(Chat& grp) -{ - string name{ DD::getGroupName(grp.ID) }; - if (!name.empty())return "[" + name + "](" + to_string(grp.ID) + ")"; - if (!grp.Name.empty())return "[" + grp.Name + "](" + to_string(grp.ID) + ")"; - if (grp.isGroup) return "群(" + to_string(grp.ID) + ")"; - return "讨论组(" + to_string(grp.ID) + ")"; +string Chat::print(){ + if (string name{ DD::getGroupName(ID) }; !name.empty())Name = name; + if (!Name.empty())return "[" + Name + "](" + to_string(ID) + ")"; + return "群(" + to_string(ID) + ")"; } #ifdef _WIN32 diff --git a/Dice/ManagerSystem.h b/Dice/ManagerSystem.h index 5c82a475..e303fcdd 100644 --- a/Dice/ManagerSystem.h +++ b/Dice/ManagerSystem.h @@ -40,7 +40,7 @@ void loadData(); void dataBackUp(); //用户记录 -class User +class User :public AnysTable { public: long long ID = 0; @@ -48,18 +48,10 @@ class User int nTrust = 0; time_t tCreated = time(nullptr); - User(){} - - AttrObject confs; + explicit User(long long id): ID(id){} unordered_map strNick{}; std::mutex ex_user; - User& id(long long qq) - { - ID = qq; - return *this; - } - User& create(time_t tt) { if (tt < tCreated)tCreated = tt; @@ -67,27 +59,24 @@ class User } User& update(time_t tt) { - confs.set("tUpdated", (long long)tt); + dict.at("tUpdated") = (long long)tt; return *this; } - time_t updated()const { return confs.get_ll("tUpdated"); } + time_t updated()const { return get_ll("tUpdated"); } User& trust(int n) { nTrust = n; - confs["trust"] = n; + dict["trust"] = n; return *this; } [[nodiscard]] bool empty() const; - [[nodiscard]] bool isset(const string& key) const{ - return confs.has(key); - } void setConf(const string& key, const AttrVar& val); void rmConf(const string& key); int getConf(const string& key, int def = 0) { - if (confs.has(key))return confs.get_int(key); + if (has(key))return get_int(key); return def; } @@ -123,20 +112,19 @@ class User void readb(std::ifstream& fin); }; -ifstream& operator>>(ifstream& fin, User& user); -extern unordered_map UserList; +extern unordered_map> UserList; extern unordered_map TinyList; User& getUser(long long qq); AttrVar getUserItem(long long uid, const string& item); AttrVar getGroupItem(long long uid, const string& item); AttrVar getSelfItem(string item); -AttrVar getContextItem(AttrObject context, string item, bool isTrust = true); +AttrVar getContextItem(const AttrObject& context, string item, bool isTrust = true); int trustedQQ(long long qq); int clearUser(); int clearGroup(); string getName(long long QQ, long long GroupID = 0); -AttrVar idx_nick(AttrObject&); +AttrVar idx_nick(const AttrObject&); string filter_CQcode(const string&, long long fromGID = 0); //forward msg string forward_filter(const string&, long long fromGID = 0); @@ -144,42 +132,29 @@ string forward_filter(const string&, long long fromGID = 0); extern const map mChatConf; //群聊记录 -class Chat +class Chat :public AnysTable { public: - bool isGroup = true; long long inviter = 0; long long ID = 0; string Name = ""; time_t tCreated = time(nullptr); - Chat() {} - - AttrObject confs; - mapChConf; + explicit Chat(long long id):ID(id) {} - Chat& id(long long grp); + mapChConf; - Chat& group() - { - isGroup = true; - return *this; - } - - Chat& channel() - { - isGroup = false; - return *this; - } - time_t getLst()const { return (time_t)confs.get_ll("lastMsg"); } - void rmLst()const { confs.reset("lastMsg"); } - Chat& setLst(time_t t) { confs.set("lastMsg", (long long)t); return *this; } + //Chat& id(long long grp); + time_t getLst()const { return (time_t)get_ll("lastMsg"); } + void rmLst() { reset("lastMsg"); } + Chat& setLst(time_t t) { dict.at("lastMsg") = (long long)t; return *this; } Chat& name(string s) { Name = std::move(s); return *this; } + string print(); Chat& create(time_t tt) { @@ -188,32 +163,35 @@ class Chat } Chat& update(){ - confs.set("tUpdated", (long long)time(nullptr)); + at("tUpdated") = (long long)time(nullptr); return *this; } Chat& update(time_t tt) { - confs.set("tUpdated", (long long)tt); + at("tUpdated") = (long long)tt; return *this; } - time_t updated()const { return confs.get_ll("tUpdated"); } + time_t updated()const { return get_ll("tUpdated"); } Chat& set(const string& item){ - confs.set(item); + at(item) = true; return *this; } - void set(const string& item, const AttrVar& val) { - confs.set(item, val); - update(); + void set(const string& key, const AttrVar& val) { + if (!key.empty()) { + if (val.is_null())dict.erase(key); + else dict[key] = val; + update(); + } } Chat& reset(const string& item) { - confs.reset(item); + dict.erase(item); update(); return *this; } int getConf(const string& key, int def = 0) { - if (confs.has(key))return confs.get_int(key); + if (has(key))return get_int(key); return def; } int getChConf(long long chid, const string& key, int def = 0) { @@ -227,11 +205,6 @@ class Chat void leave(const string& msg = ""); - [[nodiscard]] bool isset(const string& key) const - { - return confs.is(key); - } - bool is_except()const; @@ -239,7 +212,7 @@ class Chat { ResList res; for (const auto& [it,n] : mChatConf) { - if (confs.has(it))res << it; + if (has(it))res << it; } return res.dot("+").show(); } @@ -249,12 +222,9 @@ class Chat void readb(std::ifstream& fin); }; -extern unordered_map ChatList; +extern unordered_map> ChatList; Chat& chat(long long id); int groupset(long long id, const string& st); -string printChat(Chat& grp); -ifstream& operator>>(ifstream& fin, Chat& grp); -ofstream& operator<<(ofstream& fout, const Chat& grp); #ifdef _WIN32 DWORD getRamPort(); diff --git a/Dice/MsgMonitor.cpp b/Dice/MsgMonitor.cpp index a204c475..b6862b78 100644 --- a/Dice/MsgMonitor.cpp +++ b/Dice/MsgMonitor.cpp @@ -30,7 +30,7 @@ void AddFrq(DiceEvent& msg) EarlyMsgQueue.push(newFrq); FrqMonitor::sumFrqTotal++; today->inc("frq"); - today->set(msg.fromChat.uid, "frq", today->get(msg.fromChat.uid).get_int("frq") + 1); + today->set(msg.fromChat.uid, "frq", today->get(msg.fromChat.uid)->get_int("frq") + 1); } void frqHandler() diff --git a/Dice/RD.cpp b/Dice/RD.cpp index de0129c9..f488ea59 100644 --- a/Dice/RD.cpp +++ b/Dice/RD.cpp @@ -669,7 +669,7 @@ string DND(int intNum) return strOutput; } -void TempInsane(AttrObject& vars) { +void TempInsane(AnysTable& vars) { const int intSymRes = RandomGenerator::Randint(1, 10); vars["res"] = "1D10=" + to_string(intSymRes) + "\n症状: " + TempInsanity[intSymRes]; vars["dur"] = "1D10=" + to_string(RandomGenerator::Randint(1, 10)); @@ -685,7 +685,7 @@ void TempInsane(AttrObject& vars) { } } -void LongInsane(AttrObject& vars) { +void LongInsane(AnysTable& vars) { const int intSymRes = RandomGenerator::Randint(1, 10); vars["res"] = "1D10=" + to_string(intSymRes) + "\n症状: " + LongInsanity[intSymRes]; vars["dur"] = "1D10=" + to_string(RandomGenerator::Randint(1, 10)); diff --git a/Dice/RD.h b/Dice/RD.h index f92c215e..e64be77c 100644 --- a/Dice/RD.h +++ b/Dice/RD.h @@ -522,8 +522,8 @@ std::string COC6(int); std::string COC7D(); std::string COC7(int); std::string DND(int); -class AttrObject; -void LongInsane(AttrObject&); -void TempInsane(AttrObject&); +class AnysTable; +void LongInsane(AnysTable&); +void TempInsane(AnysTable&); int RollSuccessLevel(int, int, int); #endif /*DICE_RD*/