#ifndef V8SCRIPTWRAPPERS_H #define V8SCRIPTWRAPPERS_H #include #include #include #include const std::regex word_regex(R"((public[\s]+function[\s]+){1}(\w+)[\s]*\()"); //TODO: Move to CPP-file inline std::string getPublicFunctions(const std::string_view& code) { std::vector eventList; std::string s(code); auto words_begin = std::sregex_iterator(s.begin(), s.end(), word_regex); auto words_end = std::sregex_iterator(); for (std::sregex_iterator i = words_begin; i != words_end; ++i) { std::smatch match = *i; std::string match_str = match.str(); if (match.size() == 3) eventList.push_back(match[2]); } std::string varNames = ""; std::string varNameQuotes = ""; for (const auto eventName: eventList) { varNames += eventName + ","; varNameQuotes += "\"" + eventName + "\"" + ","; } if (!varNames.empty()) { varNames.pop_back(); varNameQuotes.pop_back(); } std::string out; if (!varNames.empty()) { out += "const __publicNames = [" + varNameQuotes + "];\n"; out += "const __publicFuncs = [" + varNames + "];\n"; out += R"( for (let i = 0; i < __publicNames.length; ++i) { if (__publicFuncs[i]) { //print("Found fn ", __publicNames[i]); self[__publicNames[i]] = __publicFuncs[i]; } else { //print("Not found fn ", __publicNames[i]); } } )"; } return out; } template inline std::string wrapScript(const std::string& code) { return code; } template inline std::string wrapScript(const std::string_view& code) { return code.data(); } class NPC; template<> inline std::string wrapScript(const std::string_view& code) { // self.onCreated || onCreated, for first declared to take precedence // if (onCreated) for latest function to override static const char* prefixString = "(function(npc) {" "var onCreated, onTimeout, onNpcWarped, onPlayerChats, onPlayerEnters, onPlayerLeaves, onPlayerTouchsMe, onPlayerLogin, onPlayerLogout;" "const self = npc;" "if (onCreated) self.onCreated = onCreated;" "if (onTimeout) self.onTimeout = onTimeout;" "if (onNpcWarped) self.onNpcWarped = onNpcWarped;" "if (onPlayerChats) self.onPlayerChats = onPlayerChats;" "if (onPlayerEnters) self.onPlayerEnters = onPlayerEnters;" "if (onPlayerLeaves) self.onPlayerLeaves = onPlayerLeaves;" "if (onPlayerTouchsMe) self.onPlayerTouchsMe = onPlayerTouchsMe;" "if (onPlayerLogin) self.onPlayerLogin = onPlayerLogin;" "if (onPlayerLogout) self.onPlayerLogout = onPlayerLogout;" "\n"; std::string wrappedCode = std::string(prefixString); std::string publicFunctions = getPublicFunctions(code); std::string fixedCode = std::regex_replace(std::string(code), word_regex, "function $2("); wrappedCode.append(fixedCode); wrappedCode.append(publicFunctions); wrappedCode.append("\n});"); return wrappedCode; } class Player; template<> inline std::string wrapScript(const std::string_view& code) { static const char* prefixString = "(function(player) {" "const self = player;\n"; std::string wrappedCode = std::string(prefixString); std::string publicFunctions = getPublicFunctions(code); std::string fixedCode = std::regex_replace(std::string(code), word_regex, "function $2("); wrappedCode.append(fixedCode); wrappedCode.append(publicFunctions); wrappedCode.append("\n});"); return wrappedCode; } class Weapon; template<> inline std::string wrapScript(const std::string_view& code) { static const char* prefixString = "(function(weapon) {" "var onCreated, onActionServerSide;" "const self = weapon;" "self.onCreated = onCreated;" "self.onActionServerSide = onActionServerSide;\n"; std::string wrappedCode = std::string(prefixString); std::string publicFunctions = getPublicFunctions(code); std::string fixedCode = std::regex_replace(std::string(code), word_regex, "function $2("); wrappedCode.append(fixedCode); wrappedCode.append(publicFunctions); wrappedCode.append("\n});"); return wrappedCode; } #endif