// BeamMP, the BeamNG.drive multiplayer mod. // Copyright (C) 2024 BeamMP Ltd., BeamMP team and contributors. // // BeamMP Ltd. can be contacted by electronic mail via contact@beammp.com. // // 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, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. // // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . #include "TLuaPlugin.h" #include #include #include #include TLuaPlugin::TLuaPlugin(TLuaEngine& Engine, const TLuaPluginConfig& Config, const fs::path& MainFolder) : mConfig(Config) , mEngine(Engine) , mFolder(MainFolder) , mPluginName(MainFolder.stem().string()) , mFileContents(0) { beammp_debug("Lua plugin \"" + mPluginName + "\" starting in \"" + mFolder.string() + "\""); std::vector Entries; for (const auto& Entry : fs::directory_iterator(mFolder)) { if (Entry.is_regular_file() && Entry.path().extension() == ".lua") { Entries.push_back(Entry); } } // sort alphabetically (not needed if config is used to determine call order) // TODO: Use config to figure out what to run in which order std::sort(Entries.begin(), Entries.end(), [](const fs::path& first, const fs::path& second) { auto firstStr = first.string(); auto secondStr = second.string(); std::transform(firstStr.begin(), firstStr.end(), firstStr.begin(), ::tolower); std::transform(secondStr.begin(), secondStr.end(), secondStr.begin(), ::tolower); return firstStr < secondStr; }); std::vector>> ResultsToCheck; for (const auto& Entry : Entries) { // read in entire file try { std::ifstream FileStream(Entry.string(), std::ios::in | std::ios::binary); auto Size = std::filesystem::file_size(Entry); auto Contents = std::make_shared(); Contents->resize(Size); FileStream.read(Contents->data(), Contents->size()); mFileContents[fs::relative(Entry).string()] = Contents; // Execute first time auto Result = mEngine.EnqueueScript(mConfig.StateId, TLuaChunk(Contents, Entry.string(), MainFolder.string())); ResultsToCheck.emplace_back(Entry.string(), std::move(Result)); } catch (const std::exception& e) { beammp_error("Error loading file \"" + Entry.string() + "\": " + e.what()); } } for (auto& Result : ResultsToCheck) { Result.second->WaitUntilReady(); if (Result.second->Error) { beammp_lua_error("Failed: \"" + Result.first.string() + "\": " + Result.second->ErrorMessage); } } }