commit 3aa1cfe10471e40869e04f3b12c3362b137fbe25 Author: Pax1601 Date: Sun Nov 20 12:05:38 2022 +0100 First commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..3f52fae8 --- /dev/null +++ b/.gitignore @@ -0,0 +1,8 @@ +bin +/scripts/old +.vs +x64 +core.user +core.vcxproj.user +.vscode +*.user diff --git a/scripts/OlympusCommand.lua b/scripts/OlympusCommand.lua new file mode 100644 index 00000000..717b6918 --- /dev/null +++ b/scripts/OlympusCommand.lua @@ -0,0 +1,30 @@ +dofile("C:\\Users\\dpass\\Documents\\Olympus\\scripts\\mist_4_4_90.lua") + +Olympus = {} + +function Olympus.notify(message, displayFor) + trigger.action.outText(message, displayFor) +end + +function Olympus.move(name, lat, lng, v) + Olympus.notify("Olympus.move " .. name .. " (" .. lat .. ", " .. lng ..")", 10) + local unit = Unit.getByName(name) + if unit ~= nil then + local unitDestination = mist.utils.makeVec2(coord.LLtoLO(lat, lng, 0)) + vars = + { + group = unit:getGroup(), + point = mist.utils.makeVec3(unitDestination), + form = "Off Road", + heading = 0, + speed = v, + disableRoads = true + } + mist.groupToRandomPoint(vars) + Olympus.notify("Olympus.move executed succesfully", 10) + else + Olympus.notify("Error in Olympus.move " .. name, 10) + end +end + +Olympus.notify("OlympusCommand script loaded correctly", 10) \ No newline at end of file diff --git a/scripts/OlympusMission.lua b/scripts/OlympusMission.lua new file mode 100644 index 00000000..029bd084 --- /dev/null +++ b/scripts/OlympusMission.lua @@ -0,0 +1,25 @@ + +Olympus = {} +function Olympus.notify(message, displayFor) + trigger.action.outText(message, displayFor) +end + +function Olympus.setMissionData(arg, time) + local bullseyeVec3 = coalition.getMainRefPoint(0) + local bullseyeLatitude, bullseyeLongitude, bullseyeAltitude = coord.LOtoLL(bullseyeVec3) + local command = "Olympus.missionData = " .. + "{" .. + "bullseye = {" .. + "x = " .. bullseyeVec3.x .. "," .. + "y = " .. bullseyeVec3.z .. "," .. + "lat = " .. bullseyeLatitude .. "," .. + "lng = " .. bullseyeLongitude .. "," .. + "}" .. + "}\n" .. + "Olympus.OlympusDLL.setMissionData()" + net.dostring_in("export", command) + return time + 5 +end + +timer.scheduleFunction(Olympus.setMissionData, {}, timer.getTime() + 5) +Olympus.notify("OlympusMission script loaded correctly", 10) diff --git a/src/Olympus.sln b/src/Olympus.sln new file mode 100644 index 00000000..ce6e35c4 --- /dev/null +++ b/src/Olympus.sln @@ -0,0 +1,51 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.3.32929.385 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Olympus", "Olympus\Olympus.vcxproj", "{5F3FC91E-1FBC-4223-8011-9708DE913474}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core", "core\core.vcxproj", "{8A48D855-0E01-42BA-BD8C-07B0877C68DF}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "utils", "utils\utils.vcxproj", "{B85009CE-4A5C-4A5A-B85D-001B3A2651B2}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {5F3FC91E-1FBC-4223-8011-9708DE913474}.Debug|x64.ActiveCfg = Debug|x64 + {5F3FC91E-1FBC-4223-8011-9708DE913474}.Debug|x64.Build.0 = Debug|x64 + {5F3FC91E-1FBC-4223-8011-9708DE913474}.Debug|x86.ActiveCfg = Debug|x64 + {5F3FC91E-1FBC-4223-8011-9708DE913474}.Debug|x86.Build.0 = Debug|x64 + {5F3FC91E-1FBC-4223-8011-9708DE913474}.Release|x64.ActiveCfg = Release|x64 + {5F3FC91E-1FBC-4223-8011-9708DE913474}.Release|x64.Build.0 = Release|x64 + {5F3FC91E-1FBC-4223-8011-9708DE913474}.Release|x86.ActiveCfg = Release|x64 + {5F3FC91E-1FBC-4223-8011-9708DE913474}.Release|x86.Build.0 = Release|x64 + {8A48D855-0E01-42BA-BD8C-07B0877C68DF}.Debug|x64.ActiveCfg = Debug|x64 + {8A48D855-0E01-42BA-BD8C-07B0877C68DF}.Debug|x64.Build.0 = Debug|x64 + {8A48D855-0E01-42BA-BD8C-07B0877C68DF}.Debug|x86.ActiveCfg = Debug|Win32 + {8A48D855-0E01-42BA-BD8C-07B0877C68DF}.Debug|x86.Build.0 = Debug|Win32 + {8A48D855-0E01-42BA-BD8C-07B0877C68DF}.Release|x64.ActiveCfg = Release|x64 + {8A48D855-0E01-42BA-BD8C-07B0877C68DF}.Release|x64.Build.0 = Release|x64 + {8A48D855-0E01-42BA-BD8C-07B0877C68DF}.Release|x86.ActiveCfg = Release|Win32 + {8A48D855-0E01-42BA-BD8C-07B0877C68DF}.Release|x86.Build.0 = Release|Win32 + {B85009CE-4A5C-4A5A-B85D-001B3A2651B2}.Debug|x64.ActiveCfg = Debug|x64 + {B85009CE-4A5C-4A5A-B85D-001B3A2651B2}.Debug|x64.Build.0 = Debug|x64 + {B85009CE-4A5C-4A5A-B85D-001B3A2651B2}.Debug|x86.ActiveCfg = Debug|Win32 + {B85009CE-4A5C-4A5A-B85D-001B3A2651B2}.Debug|x86.Build.0 = Debug|Win32 + {B85009CE-4A5C-4A5A-B85D-001B3A2651B2}.Release|x64.ActiveCfg = Release|x64 + {B85009CE-4A5C-4A5A-B85D-001B3A2651B2}.Release|x64.Build.0 = Release|x64 + {B85009CE-4A5C-4A5A-B85D-001B3A2651B2}.Release|x86.ActiveCfg = Release|Win32 + {B85009CE-4A5C-4A5A-B85D-001B3A2651B2}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {FAB9F592-7511-4EB9-B365-078842ED9BDD} + EndGlobalSection +EndGlobal diff --git a/src/Olympus/Olympus.filters b/src/Olympus/Olympus.filters new file mode 100644 index 00000000..2bcbeefa --- /dev/null +++ b/src/Olympus/Olympus.filters @@ -0,0 +1,29 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + + + inc + + + inc + + + + + src + + + src + + + \ No newline at end of file diff --git a/src/Olympus/Olympus.vcxproj b/src/Olympus/Olympus.vcxproj new file mode 100644 index 00000000..62b2e9b0 --- /dev/null +++ b/src/Olympus/Olympus.vcxproj @@ -0,0 +1,114 @@ + + + + + Debug + x64 + + + Release + x64 + + + + + + + + {b85009ce-4a5c-4a5a-b85d-001b3a2651b2} + false + + + + 16.0 + Win32Proj + {5f3fc91e-1fbc-4223-8011-9708de913474} + Olympus + 10.0 + Olympus + + + + DynamicLibrary + true + v143 + Unicode + + + DynamicLibrary + false + v143 + true + Unicode + + + + + + + + + + + + + + + false + .\..\..\bin\$(Platform)\$(Configuration)\ + + + false + .\..\..\bin\$(Platform)\$(Configuration)\ + + + true + + + + Level3 + true + _CRT_SECURE_NO_WARNINGS; _DEBUG;OLYMPUS_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + NotUsing + pch.h + include; ..\..\third-party\lua\include; ..\utils\include; ..\shared\include + stdcpp17 + AssemblyCode + + + Windows + true + false + lua.lib + ..\..\third-party\lua + + + + + Level3 + true + true + true + _CRT_SECURE_NO_WARNINGS; NDEBUG;OLYMPUS_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + NotUsing + pch.h + include; ..\..\third-party\lua\include; ..\utils\include; ..\shared\include + stdcpp17 + NoListing + + + Windows + true + true + true + false + lua.lib + ..\..\third-party\lua + + + + + + \ No newline at end of file diff --git a/src/Olympus/Olympus.vcxproj.filters b/src/Olympus/Olympus.vcxproj.filters new file mode 100644 index 00000000..e94b4033 --- /dev/null +++ b/src/Olympus/Olympus.vcxproj.filters @@ -0,0 +1,16 @@ + + + + + {c021f649-26ec-4040-abd4-13132def4a81} + + + {2809fbbc-77d2-465e-afef-230525a60c66} + + + + + Source Files + + + \ No newline at end of file diff --git a/src/Olympus/src/main.cpp b/src/Olympus/src/main.cpp new file mode 100644 index 00000000..3b294ffa --- /dev/null +++ b/src/Olympus/src/main.cpp @@ -0,0 +1,159 @@ +#include "framework.h" + +#include "DCSUtils.h" +#include "Logger.h" + +#define DllExport __declspec( dllexport ) + +BOOL APIENTRY DllMain( HMODULE hModule, + DWORD ul_reason_for_call, + LPVOID lpReserved + ) +{ + switch (ul_reason_for_call) + { + case DLL_PROCESS_ATTACH: + case DLL_THREAD_ATTACH: + case DLL_THREAD_DETACH: + case DLL_PROCESS_DETACH: + break; + } + return TRUE; +} + +/* Run-time linking to core dll allows for "hot swap"*/ +HINSTANCE hGetProcIDDLL = NULL; +typedef int(__stdcall* f_coreInit)(lua_State* L); +typedef int(__stdcall* f_coreDeinit)(lua_State* L); +typedef int(__stdcall* f_coreFrame)(lua_State* L); +typedef int(__stdcall* f_coreMissionData)(lua_State* L); +f_coreInit coreInit = nullptr; +f_coreDeinit coreDeinit = nullptr; +f_coreFrame coreFrame = nullptr; +f_coreMissionData coreMissionData = nullptr; + +static int onSimulationStart(lua_State* L) +{ + LOGGER->Log("onSimulationStart callback called successfully"); +#ifdef _DEBUG + LOGGER->Log("Loading Debug core.dll"); + hGetProcIDDLL = LoadLibrary(L"C:\\Users\\dpass\\Documents\\Olympus\\bin\\x64\\Debug\\core.dll"); +#else + LOGGER->Log("Loading Release core.dll"); + hGetProcIDDLL = LoadLibrary(L"C:\\Users\\dpass\\Documents\\Olympus\\bin\\x64\\Release\\core.dll"); +#endif + + if (!hGetProcIDDLL) { + DCSUtils::LogError(L, "Error loading core DLL"); + goto error; + } + + LOGGER->Log("Core DLL loaded successfully"); + + coreInit = (f_coreInit)GetProcAddress(hGetProcIDDLL, "coreInit"); + if (!coreInit) + { + DCSUtils::LogError(L, "Error getting coreInit ProcAddress from DLL"); + goto error; + } + + coreDeinit = (f_coreDeinit)GetProcAddress(hGetProcIDDLL, "coreDeinit"); + if (!coreInit) + { + DCSUtils::LogError(L, "Error getting coreDeinit ProcAddress from DLL"); + goto error; + } + + coreFrame = (f_coreFrame)GetProcAddress(hGetProcIDDLL, "coreFrame"); + if (!coreFrame) + { + DCSUtils::LogError(L, "Error getting coreFrame ProcAddress from DLL"); + goto error; + } + + coreMissionData = (f_coreFrame)GetProcAddress(hGetProcIDDLL, "coreMissionData"); + if (!coreFrame) + { + DCSUtils::LogError(L, "Error getting coreMissionData ProcAddress from DLL"); + goto error; + } + + coreInit(L); + + DCSUtils::LogInfo(L, "Module loaded and started successfully."); + + return 0; + +error: + DCSUtils::LogError(L, "Error while loading module, see Olympus.log in temporary folder for additional details."); + return 0; +} + +static int onSimulationFrame(lua_State* L) +{ + if (coreFrame) + { + coreFrame(L); + } + return 0; +} + +static int onSimulationStop(lua_State* L) +{ + LOGGER->Log("onSimulationStop callback called successfully"); + if (hGetProcIDDLL) + { + LOGGER->Log("Trying to unload core DLL"); + if (coreDeinit) + { + coreDeinit(L); + } + + if (FreeLibrary(hGetProcIDDLL)) + { + LOGGER->Log("Core DLL unloaded successfully"); + } + else + { + DCSUtils::LogError(L, "Error unloading DLL"); + goto error; + } + + coreInit = nullptr; + coreDeinit = nullptr; + coreFrame = nullptr; + coreMissionData = nullptr; + } + + hGetProcIDDLL = NULL; + + return 0; + +error: + DCSUtils::LogError(L, "Error while unloading module, see Olympus.log in temporary folder for additional details."); + return 0; +} + + +static int setMissionData(lua_State* L) +{ + if (coreMissionData) + { + coreMissionData(L); + } + return 0; +} + +static const luaL_Reg Map[] = { + {"onSimulationStart", onSimulationStart}, + {"onSimulationFrame", onSimulationFrame}, + {"onSimulationStop", onSimulationStop}, + {"setMissionData", setMissionData }, + {NULL, NULL} +}; + +extern "C" DllExport int luaopen_Olympus(lua_State * L) +{ + luaL_register(L, "Olympus", Map); + return 1; +} diff --git a/src/Olympus/src/pch.cpp b/src/Olympus/src/pch.cpp new file mode 100644 index 00000000..ce9b7399 --- /dev/null +++ b/src/Olympus/src/pch.cpp @@ -0,0 +1,2 @@ +#include "pch.h" + diff --git a/src/core/core.filters b/src/core/core.filters new file mode 100644 index 00000000..c32080a3 --- /dev/null +++ b/src/core/core.filters @@ -0,0 +1,90 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + \ No newline at end of file diff --git a/src/core/core.vcxproj b/src/core/core.vcxproj new file mode 100644 index 00000000..ee9a11ea --- /dev/null +++ b/src/core/core.vcxproj @@ -0,0 +1,182 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + + + + + + + + + + + + + + + + + + + {b85009ce-4a5c-4a5a-b85d-001b3a2651b2} + true + false + + + + 16.0 + Win32Proj + {8a48d855-0e01-42ba-bd8c-07b0877c68df} + core + 10.0 + + + + DynamicLibrary + true + v143 + Unicode + + + DynamicLibrary + false + v143 + true + Unicode + + + DynamicLibrary + true + v143 + Unicode + + + DynamicLibrary + false + v143 + true + Unicode + + + + + + + + + + + + + + + + + + + + + .\..\..\bin\$(Platform)\$(Configuration)\ + + + .\..\..\bin\$(Platform)\$(Configuration)\ + + + + Level3 + true + WIN32;_DEBUG;OLYMPUSCORE_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + Use + pch.h + + + Windows + true + false + + + + + Level3 + true + true + true + WIN32;NDEBUG;OLYMPUSCORE_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + Use + pch.h + + + Windows + true + true + true + false + + + + + Level3 + true + _DEBUG;CORE_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + NotUsing + pch.h + include; ..\..\third-party\lua\include; ..\utils\include; ..\shared\include + stdcpp17 + + + Windows + true + false + lua.lib;%(AdditionalDependencies) + ..\..\third-party\lua + + + + + Level3 + true + true + true + NDEBUG;CORE_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + NotUsing + pch.h + include; ..\..\third-party\lua\include; ..\utils\include; ..\shared\include + stdcpp17 + + + Windows + true + true + true + false + lua.lib;%(AdditionalDependencies) + ..\..\third-party\lua + + + + + + \ No newline at end of file diff --git a/src/core/core.vcxproj.filters b/src/core/core.vcxproj.filters new file mode 100644 index 00000000..8276d6d5 --- /dev/null +++ b/src/core/core.vcxproj.filters @@ -0,0 +1,54 @@ + + + + + {cc40b2d0-5e40-4a2b-bfc7-df3aef133737} + + + {1be98bb1-2aa0-40b5-bac9-3d073e079771} + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + \ No newline at end of file diff --git a/src/core/include/Commands.h b/src/core/include/Commands.h new file mode 100644 index 00000000..abfa1dbe --- /dev/null +++ b/src/core/include/Commands.h @@ -0,0 +1,37 @@ +#pragma once +#include "LUAUtils.h" +#include "Utils.h" + +namespace CommandPriority { + enum CommandPriorities { LOW, MEDIUM, HIGH }; +}; + +namespace CommandType { + enum CommandTypes { NO_TYPE, MOVE }; +}; + +/* Base command class */ +class Command +{ +public: + int getPriority() { return priority; } + int getType() { return type; } + virtual void execute(lua_State* L) {}; + +protected: + int priority = CommandPriority::LOW; + int type = CommandType::NO_TYPE; +}; + +/* Simple low priority move command (from user click) */ +class MoveCommand : public Command +{ +public: + MoveCommand(int ID, wstring unitName, Coords destination) : ID(ID), unitName(unitName), destination(destination) { priority = CommandPriority::LOW; type = CommandType::MOVE; }; + virtual void execute(lua_State* L); + +private: + const int ID; + const wstring unitName; + const Coords destination; +}; \ No newline at end of file diff --git a/src/core/include/LUAFunctions.h b/src/core/include/LUAFunctions.h new file mode 100644 index 00000000..6b86a8b7 --- /dev/null +++ b/src/core/include/LUAFunctions.h @@ -0,0 +1,7 @@ +#pragma once +#include "framework.h" + +namespace LUAFunctions +{ + void registerLuaFunctions(lua_State* L); +} \ No newline at end of file diff --git a/src/core/include/RESTServer.h b/src/core/include/RESTServer.h new file mode 100644 index 00000000..c207b479 --- /dev/null +++ b/src/core/include/RESTServer.h @@ -0,0 +1,29 @@ +#pragma once +#include "framework.h" +#include "LUAUtils.h" + +using namespace web::http; +using namespace web::http::experimental::listener; + +class UnitsHandler; +class Scheduler; + +class RESTServer +{ +public: + RESTServer(lua_State* L); + ~RESTServer(); + +private: + std::thread* serverThread; + + void handle_options(http_request request); + void handle_get(http_request request); + void handle_request(http_request request, function action); + void handle_put(http_request request); + + void task(); + + atomic runListener; +}; + diff --git a/src/core/include/Scheduler.h b/src/core/include/Scheduler.h new file mode 100644 index 00000000..649a2ac4 --- /dev/null +++ b/src/core/include/Scheduler.h @@ -0,0 +1,20 @@ +#pragma once +#include "LUAUtils.h" +#include "framework.h" +#include "Commands.h" + +class Scheduler +{ +public: + Scheduler(lua_State* L); + ~Scheduler(); + + void appendCommand(Command* command); + void execute(lua_State* L); + void handleRequest(wstring key, json::value value); + +private: + list commands; + mutex lock; +}; + diff --git a/src/core/include/Unit.h b/src/core/include/Unit.h new file mode 100644 index 00000000..e34c3525 --- /dev/null +++ b/src/core/include/Unit.h @@ -0,0 +1,50 @@ +#pragma once +#include "Utils.h" +#include "DCSUtils.h" +#include "LUAUtils.h" +#include "framework.h" + +class Unit +{ +public: + Unit(json::value json, int ID); + ~Unit(); + + void update(json::value json); + + void setPath(list path); + + int getID() { return ID; } + wstring getName() { return name; } + wstring getUnitName() { return unitName; } + wstring getGroupName() { return groupName; } + int getType() { return type; } + wstring getCountry() { return country; } + int getCoalitionID() { return coalitionID; } + double getLatitude() { return latitude; } + double getLongitude() { return longitude; } + double getAltitude() { return altitude; } + double getHeading() { return heading; } + + json::value json(); + +protected: + int ID; + wstring name = L"undefined"; + wstring unitName = L"undefined"; + wstring groupName = L"undefined"; + int type = 0; + wstring country = L"undefined"; + int coalitionID = 0; + double latitude = 0; + double longitude = 0; + double altitude = 0; + double heading = 0; + + list activePath; + Coords activeDestination; + +private: + virtual void AIloop(); +}; + diff --git a/src/core/include/UnitsHandler.h b/src/core/include/UnitsHandler.h new file mode 100644 index 00000000..cf9e0c70 --- /dev/null +++ b/src/core/include/UnitsHandler.h @@ -0,0 +1,23 @@ +#pragma once +#include "framework.h" +#include "DCSUtils.h" + +class Unit; + +class UnitsHandler +{ +public: + UnitsHandler(lua_State* L); + ~UnitsHandler(); + + Unit* getUnit(int ID); + void getMissionDB(lua_State* L); + void update(lua_State* L); + void updateAnswer(json::value& answer); + +private: + map units; + json::value missionDB; + +}; + diff --git a/src/core/src/Commands.cpp b/src/core/src/Commands.cpp new file mode 100644 index 00000000..18ade4cf --- /dev/null +++ b/src/core/src/Commands.cpp @@ -0,0 +1,23 @@ +#include "Commands.h" +#include "framework.h" +#include "Logger.h" + +void MoveCommand::execute(lua_State* L) +{ + std::ostringstream command; + + command << "Olympus.move(\"" << Utils::to_string(unitName) << "\"," << destination.lat << "," << destination.lng << "," << 10 << ")"; + + lua_getglobal(L, "net"); + lua_getfield(L, -1, "dostring_in"); + lua_pushstring(L, "server"); + lua_pushstring(L, command.str().c_str()); + if (lua_pcall(L, 2, 0, 0) != 0) + { + LOGGER->Log("Error executing MoveCommand"); + } + else + { + LOGGER->Log("MoveCommand executed successfully"); + } +} \ No newline at end of file diff --git a/src/core/src/LUAFunctions.cpp b/src/core/src/LUAFunctions.cpp new file mode 100644 index 00000000..94366a38 --- /dev/null +++ b/src/core/src/LUAFunctions.cpp @@ -0,0 +1,28 @@ +#include "LUAFunctions.h" +#include "Logger.h" + +void LUAFunctions::registerLuaFunctions(lua_State* L) +{ + ifstream f("C:\\Users\\dpass\\Documents\\Olympus\\scripts\\OlympusCommand.lua"); + string str; + if (f) { + ostringstream ss; + ss << f.rdbuf(); + str = ss.str(); + } + + lua_getglobal(L, "net"); + lua_getfield(L, -1, "dostring_in"); + lua_pushstring(L, "server"); + lua_pushstring(L, str.c_str()); + + if (lua_pcall(L, 2, 0, 0) != 0) + { + LOGGER->Log("Error registering LUA functions"); + } + else + { + LOGGER->Log("Lua functions registered successfully"); + } + +} \ No newline at end of file diff --git a/src/core/src/RESTServer.cpp b/src/core/src/RESTServer.cpp new file mode 100644 index 00000000..408ee0b2 --- /dev/null +++ b/src/core/src/RESTServer.cpp @@ -0,0 +1,130 @@ +#include "RESTServer.h" +#include "Logger.h" +#include "defines.h" +#include "UnitsHandler.h" +#include "Scheduler.h" +#include "LUAUtils.h" + +extern UnitsHandler* unitsHandler; +extern Scheduler* scheduler; +extern json::value missionData; + +RESTServer::RESTServer(lua_State* L): + runListener(true) +{ + DCSUtils::LogInfo(L, "Starting RESTServer"); + serverThread = new thread(&RESTServer::task, this); +} + +RESTServer::~RESTServer() +{ + runListener = false; +} + +void RESTServer::handle_options(http_request request) +{ + http_response response(status_codes::OK); + response.headers().add(U("Allow"), U("GET, POST, PUT, OPTIONS")); + response.headers().add(U("Access-Control-Allow-Origin"), U("*")); + response.headers().add(U("Access-Control-Allow-Methods"), U("GET, POST, PUT, OPTIONS")); + response.headers().add(U("Access-Control-Allow-Headers"), U("Content-Type")); + + request.reply(response); +} + +void RESTServer::handle_get(http_request request) +{ + http_response response(status_codes::OK); + response.headers().add(U("Allow"), U("GET, POST, PUT, OPTIONS")); + response.headers().add(U("Access-Control-Allow-Origin"), U("*")); + response.headers().add(U("Access-Control-Allow-Methods"), U("GET, POST, PUT, OPTIONS")); + response.headers().add(U("Access-Control-Allow-Headers"), U("Content-Type")); + + auto answer = json::value::object(); + try + { + unitsHandler->updateAnswer(answer); + answer[L"missionData"] = missionData; + } + catch (http_exception const& e) + { + LOGGER->Log(e.what()); + } + response.set_body(answer); + + request.reply(response); +} + +void RESTServer::handle_request(http_request request, function action) +{ + auto answer = json::value::object(); + + request.extract_json().then([&answer, &action](pplx::task task) + { + try + { + auto const& jvalue = task.get(); + + if (!jvalue.is_null()) + { + action(jvalue, answer); + } + } + catch (http_exception const& e) + { + LOGGER->Log(e.what()); + } + }).wait(); + + http_response response(status_codes::OK); + response.headers().add(U("Allow"), U("GET, POST, PUT, OPTIONS")); + response.headers().add(U("Access-Control-Allow-Origin"), U("*")); + response.headers().add(U("Access-Control-Allow-Methods"), U("GET, POST, PUT, OPTIONS")); + response.headers().add(U("Access-Control-Allow-Headers"), U("Content-Type")); + response.set_body(answer); + request.reply(response); +} + +void RESTServer::handle_put(http_request request) +{ + handle_request( + request, + [](json::value const& jvalue, json::value& answer) + { + for (auto const& e : jvalue.as_object()) + { + auto key = e.first; + auto value = e.second; + scheduler->handleRequest(key, value); + } + }); +} + +void RESTServer::task() +{ + http_listener listener(REST_ADDRESS); + + std::function handle_options = std::bind(&RESTServer::handle_options, this, std::placeholders::_1); + std::function handle_get = std::bind(&RESTServer::handle_get, this, std::placeholders::_1); + std::function handle_put = std::bind(&RESTServer::handle_put, this, std::placeholders::_1); + + listener.support(methods::OPTIONS, handle_options); + listener.support(methods::GET, handle_get); + listener.support(methods::PUT, handle_put); + + try + { + listener.open() + .then([&listener]() {LOGGER->Log("RESTServer starting to listen"); }) + .wait(); + + while (runListener); + + listener.close(); + LOGGER->Log("RESTServer stopped listening"); + } + catch (exception const& e) + { + LOGGER->Log(e.what()); + } +} diff --git a/src/core/src/Scheduler.cpp b/src/core/src/Scheduler.cpp new file mode 100644 index 00000000..f965e34c --- /dev/null +++ b/src/core/src/Scheduler.cpp @@ -0,0 +1,100 @@ +#include "Scheduler.h" +#include "Logger.h" +#include "DCSUtils.h" +#include "UnitsHandler.h" +#include "Utils.h" +#include "Unit.h" + +extern UnitsHandler* unitsHandler; + +Scheduler::Scheduler(lua_State* L) +{ + DCSUtils::LogInfo(L, "Units Factory constructor called successfully"); +} + +Scheduler::~Scheduler() +{ + +} + +void Scheduler::appendCommand(Command* command) +{ + commands.push_back(command); +} + +void Scheduler::execute(lua_State* L) +{ + lock.lock(); + int priority = CommandPriority::HIGH; + while (priority >= CommandPriority::LOW) + { + for (auto command : commands) + { + if (command->getPriority() == priority) + { + LOGGER->Log("Executing command"); + switch (command->getType()) + { + case CommandType::MOVE: + { + MoveCommand* moveCommand = dynamic_cast(command); + moveCommand->execute(L); + commands.remove(command); + break; + } + default: + break; + } + goto exit; + } + } + priority--; + } + +exit: + lock.unlock(); + return; +} + + +void Scheduler::handleRequest(wstring key, json::value value) +{ + lock.lock(); + Command* command = nullptr; + + LOGGER->Log(L"Received request with ID: " + key); + if (key.compare(L"setPath") == 0) + { + int ID = value[L"ID"].as_integer(); + wstring unitName = value[L"unitName"].as_string(); + LOGGER->Log(unitName); + json::value path = value[L"path"]; + list newPath; + for (auto const& e : path.as_object()) + { + wstring WP = e.first; + double lat = path[WP][L"lat"].as_double(); + double lng = path[WP][L"lng"].as_double(); + LOGGER->Log(unitName + L" set path destination " + WP + L" (" + to_wstring(lat) + L", " + to_wstring(lng) + L")"); + Coords dest; dest.lat = lat; dest.lng = lng; + newPath.push_back(dest); + Unit* unit = unitsHandler->getUnit(ID); + if (unit != nullptr) + { + unit->setPath(newPath); + LOGGER->Log(unitName + L" new path set successfully"); + } + else + { + LOGGER->Log(unitName + L" not found, request will be discarded"); + } + } + } + + if (command != nullptr) + { + appendCommand(command); + } + lock.unlock(); +} + diff --git a/src/core/src/Unit.cpp b/src/core/src/Unit.cpp new file mode 100644 index 00000000..749ae662 --- /dev/null +++ b/src/core/src/Unit.cpp @@ -0,0 +1,88 @@ +#include "Unit.h" +#include "Utils.h" +#include "Logger.h" +#include "Commands.h" +#include "Scheduler.h" + +extern Scheduler* scheduler; + +Unit::Unit(json::value json, int ID) : + ID(ID) +{ + LOGGER->Log("Creating unit with ID: " + to_string(ID)); + update(json); +} + +Unit::~Unit() +{ + +} + +void Unit::update(json::value json) +{ + name = json[L"Name"].as_string(); + unitName = json[L"UnitName"].as_string(); + groupName = json[L"GroupName"].as_string(); + //type = json[L"Type"].as_number().to_int32(); + //country = json[L"Country"].as_string(); + //coalitionID = json[L"CoalitionID"].as_number().to_int32(); + latitude = json[L"LatLongAlt"][L"Lat"].as_number().to_double(); + longitude = json[L"LatLongAlt"][L"Long"].as_number().to_double(); + altitude = json[L"LatLongAlt"][L"Alt"].as_number().to_double(); + heading = json[L"Heading"].as_number().to_double(); + + AIloop(); +} + +void Unit::setPath(list path) +{ + activePath = path; +} + +void Unit::AIloop() +{ + if (activePath.size() > 0) + { + if (activeDestination != activePath.front()) + { + activeDestination = activePath.front(); + Command* command = dynamic_cast(new MoveCommand(ID, unitName, activeDestination)); + scheduler->appendCommand(command); + } + } +} + +json::value Unit::json() +{ + auto json = json::value::object(); + + json[L"name"] = json::value::string(name); + json[L"unitName"] = json::value::string(unitName); + json[L"groupName"] = json::value::string(groupName); + //json[L"type"] = type; + //json[L"country"] = json::value::string(country); + json[L"coalitionID"] = type; + json[L"latitude"] = latitude; + json[L"longitude"] = longitude; + json[L"altitude"] = altitude; + json[L"heading"] = heading; + + /* Send the active path as a json object */ + if (activePath.size() > 0) { + auto path = json::value::object(); + int count = 1; + for (auto& destination : activePath) + { + auto json = json::value::object(); + json[L"lat"] = destination.lat; + json[L"lng"] = destination.lng; + json[L"alt"] = destination.alt; + path[to_wstring(count++)] = json; + } + json[L"activePath"] = path; + } + + return json; +} + + diff --git a/src/core/src/UnitsHandler.cpp b/src/core/src/UnitsHandler.cpp new file mode 100644 index 00000000..38394223 --- /dev/null +++ b/src/core/src/UnitsHandler.cpp @@ -0,0 +1,59 @@ +#include "UnitsHandler.h" +#include "Logger.h" +#include "Unit.h" +#include "framework.h" +#include "Utils.h" + +UnitsHandler::UnitsHandler(lua_State* L) +{ + DCSUtils::LogInfo(L, "Units Factory constructor called successfully"); +} + +UnitsHandler::~UnitsHandler() +{ + +} + +Unit* UnitsHandler::getUnit(int ID) +{ + if (units.find(ID) == units.end()) { + return nullptr; + } + else { + return units[ID]; + } +} + +void UnitsHandler::update(lua_State* L) +{ + //lua_getglobal(L, "net"); + //lua_getfield(L, -1, "dostring_in"); + //lua_pushstring(L, "server"); + //lua_pushstring(L, "dostring_in(\"export\", \"Olympus.OlympusDLL.test()\")"); + //lua_pcall(L, 2, 0, 0); + + map unitJSONs = DCSUtils::getAllUnits(L); + + for (auto const& p : unitJSONs) + { + int ID = p.first; + if (units.count(ID) == 0) + { + units[ID] = new Unit(p.second, ID); + } + units[ID]->update(p.second); + } +} + +void UnitsHandler::updateAnswer(json::value& answer) +{ + // TODO THREAT SAFEY! + auto unitsJson = json::value::object(); + + for (auto const& p : units) + { + unitsJson[to_wstring(p.first)] = p.second->json(); + } + + answer[L"units"] = unitsJson; +} diff --git a/src/core/src/main.cpp b/src/core/src/main.cpp new file mode 100644 index 00000000..2761a3b7 --- /dev/null +++ b/src/core/src/main.cpp @@ -0,0 +1,88 @@ +#include "framework.h" +#include "DCSUtils.h" +#include "Logger.h" +#include "defines.h" +#include "UnitsHandler.h" +#include "RESTServer.h" +#include "Scheduler.h" +#include "LUAFunctions.h" + + +auto before = std::chrono::system_clock::now(); +UnitsHandler* unitsHandler = nullptr; +RESTServer* restserver = nullptr; +Scheduler* scheduler = nullptr; +json::value missionData; + +BOOL APIENTRY DllMain( HMODULE hModule, + DWORD ul_reason_for_call, + LPVOID lpReserved + ) +{ + switch (ul_reason_for_call) + { + case DLL_PROCESS_ATTACH: + case DLL_THREAD_ATTACH: + case DLL_THREAD_DETACH: + case DLL_PROCESS_DETACH: + break; + } + return TRUE; +} + +#define DllExport __declspec( dllexport ) + +extern "C" DllExport int coreDeinit(lua_State* L) +{ + LOGGER->Log("Olympus coreDeinit called successfully"); + + delete unitsHandler; + delete restserver; + delete scheduler; + + LOGGER->Log("All singletons objects destroyed successfully"); + + return(0); +} + +extern "C" DllExport int coreInit(lua_State* L) +{ + unitsHandler = new UnitsHandler(L); + restserver = new RESTServer(L); + scheduler = new Scheduler(L); + + LUAFunctions::registerLuaFunctions(L); + + return(0); +} + +extern "C" DllExport int coreFrame(lua_State* L) +{ + const std::chrono::duration duration = std::chrono::system_clock::now() - before; + + // TODO make intervals editable + if (duration.count() > UPDATE_TIME_INTERVAL) + { + if (unitsHandler != nullptr) + { + unitsHandler->update(L); + } + + // TODO allow for different intervals + if (scheduler != nullptr) + { + scheduler->execute(L); + } + before = std::chrono::system_clock::now(); + } + return(0); +} + +extern "C" DllExport int coreMissionData(lua_State * L) +{ + lua_getglobal(L, "Olympus"); + lua_getfield(L, -1, "missionData"); + missionData = LUAUtils::tableToJSON(L, -1); + + return(0); +} \ No newline at end of file diff --git a/src/shared/include/defines.h b/src/shared/include/defines.h new file mode 100644 index 00000000..ae844c49 --- /dev/null +++ b/src/shared/include/defines.h @@ -0,0 +1,7 @@ +#pragma once + +#define VERSION "v0.0.1" +#define LOG_NAME "Olympus_log.txt" +#define REST_ADDRESS L"http://localhost:30000/restdemo" + +#define UPDATE_TIME_INTERVAL 0.25 \ No newline at end of file diff --git a/src/shared/include/framework.h b/src/shared/include/framework.h new file mode 100644 index 00000000..c1b6de88 --- /dev/null +++ b/src/shared/include/framework.h @@ -0,0 +1,33 @@ +#pragma once + +#define DllExport __declspec( dllexport ) + +#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers +// Windows Header Files +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; +using namespace web; + +extern "C" { + #include "lua.h" + #include "lualib.h" + #include "luaconf.h" + #include "lauxlib.h" +} \ No newline at end of file diff --git a/src/utils/include/DCSUtils.h b/src/utils/include/DCSUtils.h new file mode 100644 index 00000000..d28f59b3 --- /dev/null +++ b/src/utils/include/DCSUtils.h @@ -0,0 +1,13 @@ +#pragma once +#include "framework.h" +#include "LUAUtils.h" + +namespace DCSUtils +{ + void LogInfo(lua_State* L, string message); + void LogWarning(lua_State* L, string message); + void LogError(lua_State* L, string message); + void Log(lua_State* L, string message, int level); + + map getAllUnits(lua_State* L); +} diff --git a/src/utils/include/LUAUtils.h b/src/utils/include/LUAUtils.h new file mode 100644 index 00000000..b3041552 --- /dev/null +++ b/src/utils/include/LUAUtils.h @@ -0,0 +1,15 @@ +#pragma once +#include "framework.h" + +namespace LUAUtils +{ + void stackUpdate(lua_State* L, int& stackDepth, int initialStack = 0); + void stackPop(lua_State* L, int popDepth = 1); + void stackClean(lua_State* L, int stackDepth); + json::value tableToJSON(lua_State* L, int index); +} + +#define STACK_UPDATE LUAUtils::stackUpdate(L, stackDepth, initialStack); +#define STACK_INIT int stackDepth = 0; int initialStack = 0; LUAUtils::stackUpdate(L, initialStack); +#define STACK_POP(X) LUAUtils::stackPop(L, X); STACK_UPDATE; +#define STACK_CLEAN STACK_UPDATE; LUAUtils::stackClean(L, stackDepth); diff --git a/src/utils/include/Logger.h b/src/utils/include/Logger.h new file mode 100644 index 00000000..b0993aef --- /dev/null +++ b/src/utils/include/Logger.h @@ -0,0 +1,26 @@ +#pragma once +#include "framework.h" + +#define LOGGER Logger::GetLogger() +class Logger +{ +public: + void Log(const std::string& sMessage); + void Log(const std::wstring& sMessage); + void Log(const char* format, ...); + + Logger& operator<<(const string& sMessage); + + static Logger* GetLogger(); +private: + Logger(); + Logger(const Logger&) {}; // copy constructor is private + Logger& operator=(const Logger&) { return *this; }; // assignment operator is private + + static const std::string m_sFileName; + static Logger* m_pThis; + static ofstream m_Logfile; + + void Open(); + void Close(); +}; diff --git a/src/utils/include/Utils.h b/src/utils/include/Utils.h new file mode 100644 index 00000000..14351d00 --- /dev/null +++ b/src/utils/include/Utils.h @@ -0,0 +1,21 @@ +#pragma once +#include "framework.h" + +struct Coords { + double lat = 0; + double lng = 0; + double alt = 0; +}; + +bool operator== (const Coords& a, const Coords& b); +bool operator!= (const Coords& a, const Coords& b); +bool operator== (const Coords& a, const int& b); +bool operator!= (const Coords& a, const int& b); + +namespace Utils +{ + // Get current date/time, format is YYYY-MM-DD.HH:mm:ss + const std::string CurrentDateTime(); + std::wstring to_wstring(const std::string& str); + std::string to_string(const std::wstring& wstr); +} diff --git a/src/utils/src/DCSUtils.cpp b/src/utils/src/DCSUtils.cpp new file mode 100644 index 00000000..cc01727b --- /dev/null +++ b/src/utils/src/DCSUtils.cpp @@ -0,0 +1,96 @@ +#include "DCSUtils.h" +#include "Logger.h" + +void DCSUtils::LogInfo(lua_State* L, string message) +{ + STACK_INIT; + + lua_getglobal(L, "log"); + lua_getfield(L, -1, "INFO"); + int infoLevel = (int) lua_tointeger(L, -1); + STACK_POP(1); + + STACK_CLEAN; + + DCSUtils::Log(L, message, infoLevel); +} + +void DCSUtils::LogWarning(lua_State* L, string message) +{ + STACK_INIT; + + lua_getglobal(L, "log"); + lua_getfield(L, -1, "WARNING"); + int warningLevel = (int)lua_tointeger(L, -1); + STACK_POP(1); + + STACK_CLEAN; + + DCSUtils::Log(L, message, warningLevel); +} + +void DCSUtils::LogError(lua_State* L, string message) +{ + STACK_INIT; + + lua_getglobal(L, "log"); + lua_getfield(L, -1, "ERROR"); + int errorLevel = (int)lua_tointeger(L, -1); + STACK_POP(1); + + STACK_CLEAN; + + DCSUtils::Log(L, message, errorLevel); +} + +void DCSUtils::Log(lua_State* L, string message, int level) +{ + STACK_INIT; + + lua_getglobal(L, "log"); + lua_getfield(L, -1, "write"); + lua_pushstring(L, "Olympus.dll"); + lua_pushnumber(L, level); + lua_pushstring(L, message.c_str()); + lua_pcall(L, 3, 0, 0); + + STACK_CLEAN; +} + +map DCSUtils::getAllUnits(lua_State* L) +{ + int res = 0; + map units; + + STACK_INIT; + + lua_getglobal(L, "Export"); + lua_getfield(L, -1, "LoGetWorldObjects"); + res = lua_pcall(L, 0, 1, 0); + + if (res != 0) + { + DCSUtils::LogError(L, "Error retrieving World Objects"); + goto exit; + } + + if (!lua_istable(L, 2)) + { + DCSUtils::LogError(L, "Error retrieving World Objects"); + goto exit; + } + else + { + lua_pushnil(L); + while (lua_next(L, 2) != 0) + { + int ID = lua_tonumber(L, -2); + units[ID] = LUAUtils::tableToJSON(L, -1); + STACK_POP(1) + } + } + +exit: + STACK_CLEAN; + return units; +} \ No newline at end of file diff --git a/src/utils/src/LUAUtils.cpp b/src/utils/src/LUAUtils.cpp new file mode 100644 index 00000000..0b47e077 --- /dev/null +++ b/src/utils/src/LUAUtils.cpp @@ -0,0 +1,57 @@ +#include "LUAUtils.h" +#include "Logger.h" +#include "Utils.h" + +void LUAUtils::stackUpdate(lua_State* L, int& stackDepth, int initialStack) +{ + stackDepth = lua_gettop(L) - initialStack; +} + +void LUAUtils::stackPop(lua_State* L, int popDepth) +{ + lua_pop(L, popDepth); +} + +void LUAUtils::stackClean(lua_State* L, int stackDepth) +{ + lua_pop(L, stackDepth); +} + +json::value LUAUtils::tableToJSON(lua_State* L, int index) +{ + auto json = json::value::object(); + + if (lua_istable(L, index)) + { + STACK_INIT; + + lua_pushvalue(L, index); + lua_pushnil(L); + while (lua_next(L, -2)) + { + lua_pushvalue(L, -2); + const char* key = lua_tostring(L, -1); + if (lua_istable(L, -2)) + { + json[Utils::to_wstring(key)] = tableToJSON(L, -2); + } + else if (lua_isnumber(L, -2)) + { + json[Utils::to_wstring(key)] = json::value::number(lua_tonumber(L, -2)); + } + else if (lua_isboolean(L, -2)) + { + json[Utils::to_wstring(key)] = json::value::boolean(lua_toboolean(L, -2)); + } + else if (lua_isstring(L, -2)) // Keep last, only checks if it can be stringified + { + json[Utils::to_wstring(key)] = json::value::string(Utils::to_wstring(lua_tostring(L, -2))); + } + lua_pop(L, 2); + } + lua_pop(L, 1); + + STACK_CLEAN; + } + return json; +} diff --git a/src/utils/src/Logger.cpp b/src/utils/src/Logger.cpp new file mode 100644 index 00000000..4ec67b26 --- /dev/null +++ b/src/utils/src/Logger.cpp @@ -0,0 +1,79 @@ +#include "Logger.h" +#include "Utils.h" +#include "defines.h" + +const string Logger::m_sFileName = LOG_NAME; +Logger* Logger::m_pThis = NULL; +ofstream Logger::m_Logfile; + +Logger::Logger() +{ + +} +Logger* Logger::GetLogger() +{ + if (m_pThis == NULL) { + m_pThis = new Logger(); + std::filesystem::path dirPath = std::filesystem::temp_directory_path(); + m_Logfile.open((dirPath.string() + m_sFileName).c_str(), ios::out | ios::app); + m_pThis->Log("**************************************************"); + } + return m_pThis; +} + +void Logger::Open() +{ + std::filesystem::path dirPath = std::filesystem::temp_directory_path(); + m_Logfile.open((dirPath.string() + m_sFileName).c_str(), ios::out | ios::app); +} + +void Logger::Close() +{ + m_Logfile.close(); +} + +void Logger::Log(const char* format, ...) +{ + Open(); + char* sMessage = NULL; + int nLength = 0; + va_list args; + va_start(args, format); + // Return the number of characters in the string referenced the list of arguments. + // _vscprintf doesn't count terminating '\0' (that's why +1) + nLength = _vscprintf(format, args) + 1; + sMessage = new char[nLength]; + vsprintf_s(sMessage, nLength, format, args); + //vsprintf(sMessage, format, args); + m_Logfile << Utils::CurrentDateTime() << ":\t"; + m_Logfile << sMessage << "\n"; + va_end(args); + Close(); + + delete[] sMessage; +} + +void Logger::Log(const string& sMessage) +{ + Open(); + m_Logfile << Utils::CurrentDateTime() << ":\t"; + m_Logfile << sMessage << "\n"; + Close(); +} + +void Logger::Log(const wstring& sMessage) +{ + Open(); + m_Logfile << Utils::CurrentDateTime() << ":\t"; + m_Logfile << Utils::to_string(sMessage) << "\n"; + Close(); +} + +Logger& Logger::operator<<(const string& sMessage) +{ + Open(); + m_Logfile << "\n" << Utils::CurrentDateTime() << ":\t"; + m_Logfile << sMessage << "\n"; + return *this; + Close(); +} \ No newline at end of file diff --git a/src/utils/src/Utils.cpp b/src/utils/src/Utils.cpp new file mode 100644 index 00000000..5092b9a9 --- /dev/null +++ b/src/utils/src/Utils.cpp @@ -0,0 +1,44 @@ +#include "framework.h" +#include "Utils.h" + +// Get current date/time, format is YYYY-MM-DD.HH:mm:ss +const std::string Utils::CurrentDateTime() +{ + time_t now = time(NULL); + struct tm tstruct; + char buf[80]; + localtime_s(&tstruct, &now); + strftime(buf, sizeof(buf), "%Y-%m-%d.%X", &tstruct); + return buf; +} + +std::wstring Utils::to_wstring(const std::string& str) +{ + int size_needed = MultiByteToWideChar(CP_UTF8, 0, &str[0], (int)str.size(), NULL, 0); + std::wstring wstrTo(size_needed, 0); + MultiByteToWideChar(CP_UTF8, 0, &str[0], (int)str.size(), &wstrTo[0], size_needed); + return wstrTo; +} + +std::string Utils::to_string(const std::wstring& wstr) +{ + if (wstr.empty()) + { + return ""; + } + + const auto size_needed = WideCharToMultiByte(CP_UTF8, 0, &wstr.at(0), (int)wstr.size(), nullptr, 0, nullptr, nullptr); + if (size_needed <= 0) + { + throw std::runtime_error("WideCharToMultiByte() failed: " + std::to_string(size_needed)); + } + + std::string result(size_needed, 0); + WideCharToMultiByte(CP_UTF8, 0, &wstr.at(0), (int)wstr.size(), &result.at(0), size_needed, nullptr, nullptr); + return result; +} + +bool operator== (const Coords& a, const Coords& b) { return a.lat == b.lat && a.lng == b.lng && a.alt == b.alt; } +bool operator!= (const Coords& a, const Coords& b) { return !(a == b); } +bool operator== (const Coords& a, const int& b) { return a.lat == b && a.lng == b && a.alt == b; } +bool operator!= (const Coords& a, const int& b) { return !(a == b); } diff --git a/src/utils/src/main.cpp b/src/utils/src/main.cpp new file mode 100644 index 00000000..0e28dd00 --- /dev/null +++ b/src/utils/src/main.cpp @@ -0,0 +1,18 @@ +#include "framework.h" + +BOOL APIENTRY DllMain( HMODULE hModule, + DWORD ul_reason_for_call, + LPVOID lpReserved + ) +{ + switch (ul_reason_for_call) + { + case DLL_PROCESS_ATTACH: + case DLL_THREAD_ATTACH: + case DLL_THREAD_DETACH: + case DLL_PROCESS_DETACH: + break; + } + return TRUE; +} + diff --git a/src/utils/src/pch.cpp b/src/utils/src/pch.cpp new file mode 100644 index 00000000..64b7eef6 --- /dev/null +++ b/src/utils/src/pch.cpp @@ -0,0 +1,5 @@ +// pch.cpp: source file corresponding to the pre-compiled header + +#include "pch.h" + +// When you are using pre-compiled headers, this source file is necessary for compilation to succeed. diff --git a/src/utils/utils.vcxproj b/src/utils/utils.vcxproj new file mode 100644 index 00000000..6fddf8ed --- /dev/null +++ b/src/utils/utils.vcxproj @@ -0,0 +1,171 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + + + + + + + + + + + + + + 16.0 + Win32Proj + {b85009ce-4a5c-4a5a-b85d-001b3a2651b2} + utils + 10.0 + + + + DynamicLibrary + true + v143 + Unicode + + + DynamicLibrary + false + v143 + true + Unicode + + + StaticLibrary + true + v143 + Unicode + + + StaticLibrary + false + v143 + true + Unicode + + + + + + + + + + + + + + + + + + + + + .\..\..\bin\$(Platform)\$(Configuration)\ + + + .\..\..\bin\$(Platform)\$(Configuration)\ + + + + Level3 + true + WIN32;_DEBUG;UTILS_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + Use + pch.h + + + Windows + true + false + + + + + Level3 + true + true + true + WIN32;NDEBUG;UTILS_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + Use + pch.h + + + Windows + true + true + true + false + + + + + Level3 + true + _DEBUG;UTILS_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + NotUsing + pch.h + include;..\..\third-party\lua\include;..\shared\include + stdcpp17 + + + Windows + true + false + ..\..\third-party\lua + lua.lib; $(CoreLibraryDependencies);%(AdditionalDependencies) + + + + + Level3 + true + true + true + NDEBUG;UTILS_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + NotUsing + pch.h + include;..\..\third-party\lua\include;..\shared\include + stdcpp17 + + + Windows + true + true + true + false + lua.lib; $(CoreLibraryDependencies);%(AdditionalDependencies) + ..\..\third-party\lua + + + + + + \ No newline at end of file diff --git a/src/utils/utils.vcxproj.filters b/src/utils/utils.vcxproj.filters new file mode 100644 index 00000000..ede7f53f --- /dev/null +++ b/src/utils/utils.vcxproj.filters @@ -0,0 +1,44 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + \ No newline at end of file diff --git a/third-party/lua/include/lauxlib.h b/third-party/lua/include/lauxlib.h new file mode 100644 index 00000000..34258235 --- /dev/null +++ b/third-party/lua/include/lauxlib.h @@ -0,0 +1,174 @@ +/* +** $Id: lauxlib.h,v 1.88.1.1 2007/12/27 13:02:25 roberto Exp $ +** Auxiliary functions for building Lua libraries +** See Copyright Notice in lua.h +*/ + + +#ifndef lauxlib_h +#define lauxlib_h + + +#include +#include + +#include "lua.h" + + +#if defined(LUA_COMPAT_GETN) +LUALIB_API int (luaL_getn) (lua_State *L, int t); +LUALIB_API void (luaL_setn) (lua_State *L, int t, int n); +#else +#define luaL_getn(L,i) ((int)lua_objlen(L, i)) +#define luaL_setn(L,i,j) ((void)0) /* no op! */ +#endif + +#if defined(LUA_COMPAT_OPENLIB) +#define luaI_openlib luaL_openlib +#endif + + +/* extra error code for `luaL_load' */ +#define LUA_ERRFILE (LUA_ERRERR+1) + + +typedef struct luaL_Reg { + const char *name; + lua_CFunction func; +} luaL_Reg; + + + +LUALIB_API void (luaI_openlib) (lua_State *L, const char *libname, + const luaL_Reg *l, int nup); +LUALIB_API void (luaL_register) (lua_State *L, const char *libname, + const luaL_Reg *l); +LUALIB_API int (luaL_getmetafield) (lua_State *L, int obj, const char *e); +LUALIB_API int (luaL_callmeta) (lua_State *L, int obj, const char *e); +LUALIB_API int (luaL_typerror) (lua_State *L, int narg, const char *tname); +LUALIB_API int (luaL_argerror) (lua_State *L, int numarg, const char *extramsg); +LUALIB_API const char *(luaL_checklstring) (lua_State *L, int numArg, + size_t *l); +LUALIB_API const char *(luaL_optlstring) (lua_State *L, int numArg, + const char *def, size_t *l); +LUALIB_API lua_Number (luaL_checknumber) (lua_State *L, int numArg); +LUALIB_API lua_Number (luaL_optnumber) (lua_State *L, int nArg, lua_Number def); + +LUALIB_API lua_Integer (luaL_checkinteger) (lua_State *L, int numArg); +LUALIB_API lua_Integer (luaL_optinteger) (lua_State *L, int nArg, + lua_Integer def); + +LUALIB_API void (luaL_checkstack) (lua_State *L, int sz, const char *msg); +LUALIB_API void (luaL_checktype) (lua_State *L, int narg, int t); +LUALIB_API void (luaL_checkany) (lua_State *L, int narg); + +LUALIB_API int (luaL_newmetatable) (lua_State *L, const char *tname); +LUALIB_API void *(luaL_checkudata) (lua_State *L, int ud, const char *tname); + +LUALIB_API void (luaL_where) (lua_State *L, int lvl); +LUALIB_API int (luaL_error) (lua_State *L, const char *fmt, ...); + +LUALIB_API int (luaL_checkoption) (lua_State *L, int narg, const char *def, + const char *const lst[]); + +LUALIB_API int (luaL_ref) (lua_State *L, int t); +LUALIB_API void (luaL_unref) (lua_State *L, int t, int ref); + +LUALIB_API int (luaL_loadfile) (lua_State *L, const char *filename); +LUALIB_API int (luaL_loadbuffer) (lua_State *L, const char *buff, size_t sz, + const char *name); +LUALIB_API int (luaL_loadstring) (lua_State *L, const char *s); + +LUALIB_API lua_State *(luaL_newstate) (void); + + +LUALIB_API const char *(luaL_gsub) (lua_State *L, const char *s, const char *p, + const char *r); + +LUALIB_API const char *(luaL_findtable) (lua_State *L, int idx, + const char *fname, int szhint); + + + + +/* +** =============================================================== +** some useful macros +** =============================================================== +*/ + +#define luaL_argcheck(L, cond,numarg,extramsg) \ + ((void)((cond) || luaL_argerror(L, (numarg), (extramsg)))) +#define luaL_checkstring(L,n) (luaL_checklstring(L, (n), NULL)) +#define luaL_optstring(L,n,d) (luaL_optlstring(L, (n), (d), NULL)) +#define luaL_checkint(L,n) ((int)luaL_checkinteger(L, (n))) +#define luaL_optint(L,n,d) ((int)luaL_optinteger(L, (n), (d))) +#define luaL_checklong(L,n) ((long)luaL_checkinteger(L, (n))) +#define luaL_optlong(L,n,d) ((long)luaL_optinteger(L, (n), (d))) + +#define luaL_typename(L,i) lua_typename(L, lua_type(L,(i))) + +#define luaL_dofile(L, fn) \ + (luaL_loadfile(L, fn) || lua_pcall(L, 0, LUA_MULTRET, 0)) + +#define luaL_dostring(L, s) \ + (luaL_loadstring(L, s) || lua_pcall(L, 0, LUA_MULTRET, 0)) + +#define luaL_getmetatable(L,n) (lua_getfield(L, LUA_REGISTRYINDEX, (n))) + +#define luaL_opt(L,f,n,d) (lua_isnoneornil(L,(n)) ? (d) : f(L,(n))) + +/* +** {====================================================== +** Generic Buffer manipulation +** ======================================================= +*/ + + + +typedef struct luaL_Buffer { + char *p; /* current position in buffer */ + int lvl; /* number of strings in the stack (level) */ + lua_State *L; + char buffer[LUAL_BUFFERSIZE]; +} luaL_Buffer; + +#define luaL_addchar(B,c) \ + ((void)((B)->p < ((B)->buffer+LUAL_BUFFERSIZE) || luaL_prepbuffer(B)), \ + (*(B)->p++ = (char)(c))) + +/* compatibility only */ +#define luaL_putchar(B,c) luaL_addchar(B,c) + +#define luaL_addsize(B,n) ((B)->p += (n)) + +LUALIB_API void (luaL_buffinit) (lua_State *L, luaL_Buffer *B); +LUALIB_API char *(luaL_prepbuffer) (luaL_Buffer *B); +LUALIB_API void (luaL_addlstring) (luaL_Buffer *B, const char *s, size_t l); +LUALIB_API void (luaL_addstring) (luaL_Buffer *B, const char *s); +LUALIB_API void (luaL_addvalue) (luaL_Buffer *B); +LUALIB_API void (luaL_pushresult) (luaL_Buffer *B); + + +/* }====================================================== */ + + +/* compatibility with ref system */ + +/* pre-defined references */ +#define LUA_NOREF (-2) +#define LUA_REFNIL (-1) + +#define lua_ref(L,lock) ((lock) ? luaL_ref(L, LUA_REGISTRYINDEX) : \ + (lua_pushstring(L, "unlocked references are obsolete"), lua_error(L), 0)) + +#define lua_unref(L,ref) luaL_unref(L, LUA_REGISTRYINDEX, (ref)) + +#define lua_getref(L,ref) lua_rawgeti(L, LUA_REGISTRYINDEX, (ref)) + + +#define luaL_reg luaL_Reg + +#endif + + diff --git a/third-party/lua/include/lua.h b/third-party/lua/include/lua.h new file mode 100644 index 00000000..a4b73e74 --- /dev/null +++ b/third-party/lua/include/lua.h @@ -0,0 +1,388 @@ +/* +** $Id: lua.h,v 1.218.1.7 2012/01/13 20:36:20 roberto Exp $ +** Lua - An Extensible Extension Language +** Lua.org, PUC-Rio, Brazil (http://www.lua.org) +** See Copyright Notice at the end of this file +*/ + + +#ifndef lua_h +#define lua_h + +#include +#include + + +#include "luaconf.h" + + +#define LUA_VERSION "Lua 5.1" +#define LUA_RELEASE "Lua 5.1.5" +#define LUA_VERSION_NUM 501 +#define LUA_COPYRIGHT "Copyright (C) 1994-2012 Lua.org, PUC-Rio" +#define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo & W. Celes" + + +/* mark for precompiled code (`Lua') */ +#define LUA_SIGNATURE "\033Lua" + +/* option for multiple returns in `lua_pcall' and `lua_call' */ +#define LUA_MULTRET (-1) + + +/* +** pseudo-indices +*/ +#define LUA_REGISTRYINDEX (-10000) +#define LUA_ENVIRONINDEX (-10001) +#define LUA_GLOBALSINDEX (-10002) +#define lua_upvalueindex(i) (LUA_GLOBALSINDEX-(i)) + + +/* thread status; 0 is OK */ +#define LUA_YIELD 1 +#define LUA_ERRRUN 2 +#define LUA_ERRSYNTAX 3 +#define LUA_ERRMEM 4 +#define LUA_ERRERR 5 + + +typedef struct lua_State lua_State; + +typedef int (*lua_CFunction) (lua_State *L); + + +/* +** functions that read/write blocks when loading/dumping Lua chunks +*/ +typedef const char * (*lua_Reader) (lua_State *L, void *ud, size_t *sz); + +typedef int (*lua_Writer) (lua_State *L, const void* p, size_t sz, void* ud); + + +/* +** prototype for memory-allocation functions +*/ +typedef void * (*lua_Alloc) (void *ud, void *ptr, size_t osize, size_t nsize); + + +/* +** basic types +*/ +#define LUA_TNONE (-1) + +#define LUA_TNIL 0 +#define LUA_TBOOLEAN 1 +#define LUA_TLIGHTUSERDATA 2 +#define LUA_TNUMBER 3 +#define LUA_TSTRING 4 +#define LUA_TTABLE 5 +#define LUA_TFUNCTION 6 +#define LUA_TUSERDATA 7 +#define LUA_TTHREAD 8 + + + +/* minimum Lua stack available to a C function */ +#define LUA_MINSTACK 20 + + +/* +** generic extra include file +*/ +#if defined(LUA_USER_H) +#include LUA_USER_H +#endif + + +/* type of numbers in Lua */ +typedef LUA_NUMBER lua_Number; + + +/* type for integer functions */ +typedef LUA_INTEGER lua_Integer; + + + +/* +** state manipulation +*/ +LUA_API lua_State *(lua_newstate) (lua_Alloc f, void *ud); +LUA_API void (lua_close) (lua_State *L); +LUA_API lua_State *(lua_newthread) (lua_State *L); + +LUA_API lua_CFunction (lua_atpanic) (lua_State *L, lua_CFunction panicf); + + +/* +** basic stack manipulation +*/ +LUA_API int (lua_gettop) (lua_State *L); +LUA_API void (lua_settop) (lua_State *L, int idx); +LUA_API void (lua_pushvalue) (lua_State *L, int idx); +LUA_API void (lua_remove) (lua_State *L, int idx); +LUA_API void (lua_insert) (lua_State *L, int idx); +LUA_API void (lua_replace) (lua_State *L, int idx); +LUA_API int (lua_checkstack) (lua_State *L, int sz); + +LUA_API void (lua_xmove) (lua_State *from, lua_State *to, int n); + + +/* +** access functions (stack -> C) +*/ + +LUA_API int (lua_isnumber) (lua_State *L, int idx); +LUA_API int (lua_isstring) (lua_State *L, int idx); +LUA_API int (lua_iscfunction) (lua_State *L, int idx); +LUA_API int (lua_isuserdata) (lua_State *L, int idx); +LUA_API int (lua_type) (lua_State *L, int idx); +LUA_API const char *(lua_typename) (lua_State *L, int tp); + +LUA_API int (lua_equal) (lua_State *L, int idx1, int idx2); +LUA_API int (lua_rawequal) (lua_State *L, int idx1, int idx2); +LUA_API int (lua_lessthan) (lua_State *L, int idx1, int idx2); + +LUA_API lua_Number (lua_tonumber) (lua_State *L, int idx); +LUA_API lua_Integer (lua_tointeger) (lua_State *L, int idx); +LUA_API int (lua_toboolean) (lua_State *L, int idx); +LUA_API const char *(lua_tolstring) (lua_State *L, int idx, size_t *len); +LUA_API size_t (lua_objlen) (lua_State *L, int idx); +LUA_API lua_CFunction (lua_tocfunction) (lua_State *L, int idx); +LUA_API void *(lua_touserdata) (lua_State *L, int idx); +LUA_API lua_State *(lua_tothread) (lua_State *L, int idx); +LUA_API const void *(lua_topointer) (lua_State *L, int idx); + + +/* +** push functions (C -> stack) +*/ +LUA_API void (lua_pushnil) (lua_State *L); +LUA_API void (lua_pushnumber) (lua_State *L, lua_Number n); +LUA_API void (lua_pushinteger) (lua_State *L, lua_Integer n); +LUA_API void (lua_pushlstring) (lua_State *L, const char *s, size_t l); +LUA_API void (lua_pushstring) (lua_State *L, const char *s); +LUA_API const char *(lua_pushvfstring) (lua_State *L, const char *fmt, + va_list argp); +LUA_API const char *(lua_pushfstring) (lua_State *L, const char *fmt, ...); +LUA_API void (lua_pushcclosure) (lua_State *L, lua_CFunction fn, int n); +LUA_API void (lua_pushboolean) (lua_State *L, int b); +LUA_API void (lua_pushlightuserdata) (lua_State *L, void *p); +LUA_API int (lua_pushthread) (lua_State *L); + + +/* +** get functions (Lua -> stack) +*/ +LUA_API void (lua_gettable) (lua_State *L, int idx); +LUA_API void (lua_getfield) (lua_State *L, int idx, const char *k); +LUA_API void (lua_rawget) (lua_State *L, int idx); +LUA_API void (lua_rawgeti) (lua_State *L, int idx, int n); +LUA_API void (lua_createtable) (lua_State *L, int narr, int nrec); +LUA_API void *(lua_newuserdata) (lua_State *L, size_t sz); +LUA_API int (lua_getmetatable) (lua_State *L, int objindex); +LUA_API void (lua_getfenv) (lua_State *L, int idx); + + +/* +** set functions (stack -> Lua) +*/ +LUA_API void (lua_settable) (lua_State *L, int idx); +LUA_API void (lua_setfield) (lua_State *L, int idx, const char *k); +LUA_API void (lua_rawset) (lua_State *L, int idx); +LUA_API void (lua_rawseti) (lua_State *L, int idx, int n); +LUA_API int (lua_setmetatable) (lua_State *L, int objindex); +LUA_API int (lua_setfenv) (lua_State *L, int idx); + + +/* +** `load' and `call' functions (load and run Lua code) +*/ +LUA_API void (lua_call) (lua_State *L, int nargs, int nresults); +LUA_API int (lua_pcall) (lua_State *L, int nargs, int nresults, int errfunc); +LUA_API int (lua_cpcall) (lua_State *L, lua_CFunction func, void *ud); +LUA_API int (lua_load) (lua_State *L, lua_Reader reader, void *dt, + const char *chunkname); + +LUA_API int (lua_dump) (lua_State *L, lua_Writer writer, void *data); + + +/* +** coroutine functions +*/ +LUA_API int (lua_yield) (lua_State *L, int nresults); +LUA_API int (lua_resume) (lua_State *L, int narg); +LUA_API int (lua_status) (lua_State *L); + +/* +** garbage-collection function and options +*/ + +#define LUA_GCSTOP 0 +#define LUA_GCRESTART 1 +#define LUA_GCCOLLECT 2 +#define LUA_GCCOUNT 3 +#define LUA_GCCOUNTB 4 +#define LUA_GCSTEP 5 +#define LUA_GCSETPAUSE 6 +#define LUA_GCSETSTEPMUL 7 + +LUA_API int (lua_gc) (lua_State *L, int what, int data); + + +/* +** miscellaneous functions +*/ + +LUA_API int (lua_error) (lua_State *L); + +LUA_API int (lua_next) (lua_State *L, int idx); + +LUA_API void (lua_concat) (lua_State *L, int n); + +LUA_API lua_Alloc (lua_getallocf) (lua_State *L, void **ud); +LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud); + + + +/* +** =============================================================== +** some useful macros +** =============================================================== +*/ + +#define lua_pop(L,n) lua_settop(L, -(n)-1) + +#define lua_newtable(L) lua_createtable(L, 0, 0) + +#define lua_register(L,n,f) (lua_pushcfunction(L, (f)), lua_setglobal(L, (n))) + +#define lua_pushcfunction(L,f) lua_pushcclosure(L, (f), 0) + +#define lua_strlen(L,i) lua_objlen(L, (i)) + +#define lua_isfunction(L,n) (lua_type(L, (n)) == LUA_TFUNCTION) +#define lua_istable(L,n) (lua_type(L, (n)) == LUA_TTABLE) +#define lua_islightuserdata(L,n) (lua_type(L, (n)) == LUA_TLIGHTUSERDATA) +#define lua_isnil(L,n) (lua_type(L, (n)) == LUA_TNIL) +#define lua_isboolean(L,n) (lua_type(L, (n)) == LUA_TBOOLEAN) +#define lua_isthread(L,n) (lua_type(L, (n)) == LUA_TTHREAD) +#define lua_isnone(L,n) (lua_type(L, (n)) == LUA_TNONE) +#define lua_isnoneornil(L, n) (lua_type(L, (n)) <= 0) + +#define lua_pushliteral(L, s) \ + lua_pushlstring(L, "" s, (sizeof(s)/sizeof(char))-1) + +#define lua_setglobal(L,s) lua_setfield(L, LUA_GLOBALSINDEX, (s)) +#define lua_getglobal(L,s) lua_getfield(L, LUA_GLOBALSINDEX, (s)) + +#define lua_tostring(L,i) lua_tolstring(L, (i), NULL) + + + +/* +** compatibility macros and functions +*/ + +#define lua_open() luaL_newstate() + +#define lua_getregistry(L) lua_pushvalue(L, LUA_REGISTRYINDEX) + +#define lua_getgccount(L) lua_gc(L, LUA_GCCOUNT, 0) + +#define lua_Chunkreader lua_Reader +#define lua_Chunkwriter lua_Writer + + +/* hack */ +LUA_API void lua_setlevel (lua_State *from, lua_State *to); + + +/* +** {====================================================================== +** Debug API +** ======================================================================= +*/ + + +/* +** Event codes +*/ +#define LUA_HOOKCALL 0 +#define LUA_HOOKRET 1 +#define LUA_HOOKLINE 2 +#define LUA_HOOKCOUNT 3 +#define LUA_HOOKTAILRET 4 + + +/* +** Event masks +*/ +#define LUA_MASKCALL (1 << LUA_HOOKCALL) +#define LUA_MASKRET (1 << LUA_HOOKRET) +#define LUA_MASKLINE (1 << LUA_HOOKLINE) +#define LUA_MASKCOUNT (1 << LUA_HOOKCOUNT) + +typedef struct lua_Debug lua_Debug; /* activation record */ + + +/* Functions to be called by the debuger in specific events */ +typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar); + + +LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar); +LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar); +LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n); +LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n); +LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n); +LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n); + +LUA_API int lua_sethook (lua_State *L, lua_Hook func, int mask, int count); +LUA_API lua_Hook lua_gethook (lua_State *L); +LUA_API int lua_gethookmask (lua_State *L); +LUA_API int lua_gethookcount (lua_State *L); + + +struct lua_Debug { + int event; + const char *name; /* (n) */ + const char *namewhat; /* (n) `global', `local', `field', `method' */ + const char *what; /* (S) `Lua', `C', `main', `tail' */ + const char *source; /* (S) */ + int currentline; /* (l) */ + int nups; /* (u) number of upvalues */ + int linedefined; /* (S) */ + int lastlinedefined; /* (S) */ + char short_src[LUA_IDSIZE]; /* (S) */ + /* private part */ + int i_ci; /* active function */ +}; + +/* }====================================================================== */ + + +/****************************************************************************** +* Copyright (C) 1994-2012 Lua.org, PUC-Rio. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* "Software"), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject to +* the following conditions: +* +* The above copyright notice and this permission notice shall be +* included in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +******************************************************************************/ + + +#endif diff --git a/third-party/lua/include/lua.hpp b/third-party/lua/include/lua.hpp new file mode 100644 index 00000000..ec417f59 --- /dev/null +++ b/third-party/lua/include/lua.hpp @@ -0,0 +1,9 @@ +// lua.hpp +// Lua header files for C++ +// <> not supplied automatically because Lua also compiles as C++ + +extern "C" { +#include "lua.h" +#include "lualib.h" +#include "lauxlib.h" +} diff --git a/third-party/lua/include/luaconf.h b/third-party/lua/include/luaconf.h new file mode 100644 index 00000000..05354175 --- /dev/null +++ b/third-party/lua/include/luaconf.h @@ -0,0 +1,766 @@ +/* +** $Id: luaconf.h,v 1.82.1.7 2008/02/11 16:25:08 roberto Exp $ +** Configuration file for Lua +** See Copyright Notice in lua.h +*/ + + +#ifndef lconfig_h +#define lconfig_h + +#include +#include + + +/* +** ================================================================== +** Search for "@@" to find all configurable definitions. +** =================================================================== +*/ + + +/* +@@ LUA_ANSI controls the use of non-ansi features. +** CHANGE it (define it) if you want Lua to avoid the use of any +** non-ansi feature or library. +*/ +#if defined(__STRICT_ANSI__) +#define LUA_ANSI +#endif + + +#if !defined(LUA_ANSI) && defined(_WIN32) +#define LUA_WIN +#endif + +#if defined(LUA_USE_LINUX) +#define LUA_USE_POSIX +#define LUA_USE_DLOPEN /* needs an extra library: -ldl */ +#define LUA_USE_READLINE /* needs some extra libraries */ +#endif + +#if defined(LUA_USE_MACOSX) +#define LUA_USE_POSIX +#define LUA_DL_DYLD /* does not need extra library */ +#endif + + + +/* +@@ LUA_USE_POSIX includes all functionallity listed as X/Open System +@* Interfaces Extension (XSI). +** CHANGE it (define it) if your system is XSI compatible. +*/ +#if defined(LUA_USE_POSIX) +#define LUA_USE_MKSTEMP +#define LUA_USE_ISATTY +#define LUA_USE_POPEN +#define LUA_USE_ULONGJMP +#endif + + +/* +@@ LUA_PATH and LUA_CPATH are the names of the environment variables that +@* Lua check to set its paths. +@@ LUA_INIT is the name of the environment variable that Lua +@* checks for initialization code. +** CHANGE them if you want different names. +*/ +#define LUA_PATH "LUA_PATH" +#define LUA_CPATH "LUA_CPATH" +#define LUA_INIT "LUA_INIT" + + +/* +@@ LUA_PATH_DEFAULT is the default path that Lua uses to look for +@* Lua libraries. +@@ LUA_CPATH_DEFAULT is the default path that Lua uses to look for +@* C libraries. +** CHANGE them if your machine has a non-conventional directory +** hierarchy or if you want to install your libraries in +** non-conventional directories. +*/ +#if defined(_WIN32) +/* +** In Windows, any exclamation mark ('!') in the path is replaced by the +** path of the directory of the executable file of the current process. +*/ +#define LUA_LDIR "!\\lua\\" +#define LUA_CDIR "!\\" +#define LUA_PATH_DEFAULT \ + ".\\?.lua;" LUA_LDIR"?.lua;" LUA_LDIR"?\\init.lua;" \ + LUA_CDIR"?.lua;" LUA_CDIR"?\\init.lua" +#define LUA_CPATH_DEFAULT \ + ".\\?.dll;" LUA_CDIR"?.dll;" LUA_CDIR"loadall.dll;" \ + LUA_CDIR"clibs\\?.dll;" LUA_CDIR"clibs\\loadall.dll;" \ + ".\\?51.dll;" LUA_CDIR"?51.dll;" LUA_CDIR"clibs\\?51.dll" + +#else +#define LUA_ROOT "/usr/local/" +#define LUA_LDIR LUA_ROOT "share/lua/5.1/" +#define LUA_CDIR LUA_ROOT "lib/lua/5.1/" +#define LUA_PATH_DEFAULT \ + "./?.lua;" LUA_LDIR"?.lua;" LUA_LDIR"?/init.lua;" \ + LUA_CDIR"?.lua;" LUA_CDIR"?/init.lua" +#define LUA_CPATH_DEFAULT \ + "./?.so;" LUA_CDIR"?.so;" LUA_CDIR"loadall.so;" \ + "./lib?51.so;" LUA_CDIR"lib?51.so" +#endif + + +/* +@@ LUA_DIRSEP is the directory separator (for submodules). +** CHANGE it if your machine does not use "/" as the directory separator +** and is not Windows. (On Windows Lua automatically uses "\".) +*/ +#if defined(_WIN32) +#define LUA_DIRSEP "\\" +#else +#define LUA_DIRSEP "/" +#endif + + +/* +@@ LUA_PATHSEP is the character that separates templates in a path. +@@ LUA_PATH_MARK is the string that marks the substitution points in a +@* template. +@@ LUA_EXECDIR in a Windows path is replaced by the executable's +@* directory. +@@ LUA_IGMARK is a mark to ignore all before it when bulding the +@* luaopen_ function name. +** CHANGE them if for some reason your system cannot use those +** characters. (E.g., if one of those characters is a common character +** in file/directory names.) Probably you do not need to change them. +*/ +#define LUA_PATHSEP ";" +#define LUA_PATH_MARK "?" +#define LUA_EXECDIR "!" +#define LUA_IGMARK "-" + + +/* +@@ LUA_INTEGER is the integral type used by lua_pushinteger/lua_tointeger. +** CHANGE that if ptrdiff_t is not adequate on your machine. (On most +** machines, ptrdiff_t gives a good choice between int or long.) +*/ +#define LUA_INTEGER ptrdiff_t + + +/* +@@ LUA_API is a mark for all core API functions. +@@ LUALIB_API is a mark for all standard library functions. +** CHANGE them if you need to define those functions in some special way. +** For instance, if you want to create one Windows DLL with the core and +** the libraries, you may want to use the following definition (define +** LUA_BUILD_AS_DLL to get it). +*/ +#if defined(LUA_BUILD_AS_DLL) + +#if defined(LUA_CORE) || defined(LUA_LIB) +#define LUA_API __declspec(dllexport) +#else +#define LUA_API __declspec(dllimport) +#endif + +#else + +#define LUA_API extern + +#endif + +/* more often than not the libs go together with the core */ +#define LUALIB_API LUA_API + + +/* +@@ LUAI_FUNC is a mark for all extern functions that are not to be +@* exported to outside modules. +@@ LUAI_DATA is a mark for all extern (const) variables that are not to +@* be exported to outside modules. +** CHANGE them if you need to mark them in some special way. Elf/gcc +** (versions 3.2 and later) mark them as "hidden" to optimize access +** when Lua is compiled as a shared library. +*/ +#if defined(luaall_c) +#define LUAI_FUNC static +#define LUAI_DATA /* empty */ + +#elif defined(__GNUC__) && ((__GNUC__*100 + __GNUC_MINOR__) >= 302) && \ + defined(__ELF__) +#define LUAI_FUNC __attribute__((visibility("hidden"))) extern +#define LUAI_DATA LUAI_FUNC + +#else +#define LUAI_FUNC extern +#define LUAI_DATA extern +#endif + + + +/* +@@ LUA_QL describes how error messages quote program elements. +** CHANGE it if you want a different appearance. +*/ +#define LUA_QL(x) "'" x "'" +#define LUA_QS LUA_QL("%s") + + +/* +@@ LUA_IDSIZE gives the maximum size for the description of the source +@* of a function in debug information. +** CHANGE it if you want a different size. +*/ +#define LUA_IDSIZE 60 + + +/* +** {================================================================== +** Stand-alone configuration +** =================================================================== +*/ + +#if defined(lua_c) || defined(luaall_c) + +/* +@@ lua_stdin_is_tty detects whether the standard input is a 'tty' (that +@* is, whether we're running lua interactively). +** CHANGE it if you have a better definition for non-POSIX/non-Windows +** systems. +*/ +#if defined(LUA_USE_ISATTY) +#include +#define lua_stdin_is_tty() isatty(0) +#elif defined(LUA_WIN) +#include +#include +#define lua_stdin_is_tty() _isatty(_fileno(stdin)) +#else +#define lua_stdin_is_tty() 1 /* assume stdin is a tty */ +#endif + + +/* +@@ LUA_PROMPT is the default prompt used by stand-alone Lua. +@@ LUA_PROMPT2 is the default continuation prompt used by stand-alone Lua. +** CHANGE them if you want different prompts. (You can also change the +** prompts dynamically, assigning to globals _PROMPT/_PROMPT2.) +*/ +#define LUA_PROMPT "> " +#define LUA_PROMPT2 ">> " + + +/* +@@ LUA_PROGNAME is the default name for the stand-alone Lua program. +** CHANGE it if your stand-alone interpreter has a different name and +** your system is not able to detect that name automatically. +*/ +#define LUA_PROGNAME "lua" + + +/* +@@ LUA_MAXINPUT is the maximum length for an input line in the +@* stand-alone interpreter. +** CHANGE it if you need longer lines. +*/ +#define LUA_MAXINPUT 512 + + +/* +@@ lua_readline defines how to show a prompt and then read a line from +@* the standard input. +@@ lua_saveline defines how to "save" a read line in a "history". +@@ lua_freeline defines how to free a line read by lua_readline. +** CHANGE them if you want to improve this functionality (e.g., by using +** GNU readline and history facilities). +*/ +#if defined(LUA_USE_READLINE) +#include +#include +#include +#define lua_readline(L,b,p) ((void)L, ((b)=readline(p)) != NULL) +#define lua_saveline(L,idx) \ + if (lua_strlen(L,idx) > 0) /* non-empty line? */ \ + add_history(lua_tostring(L, idx)); /* add it to history */ +#define lua_freeline(L,b) ((void)L, free(b)) +#else +#define lua_readline(L,b,p) \ + ((void)L, fputs(p, stdout), fflush(stdout), /* show prompt */ \ + fgets(b, LUA_MAXINPUT, stdin) != NULL) /* get line */ +#define lua_saveline(L,idx) { (void)L; (void)idx; } +#define lua_freeline(L,b) { (void)L; (void)b; } +#endif + +#endif + +/* }================================================================== */ + + +/* +@@ LUAI_GCPAUSE defines the default pause between garbage-collector cycles +@* as a percentage. +** CHANGE it if you want the GC to run faster or slower (higher values +** mean larger pauses which mean slower collection.) You can also change +** this value dynamically. +*/ +#define LUAI_GCPAUSE 200 /* 200% (wait memory to double before next GC) */ + + +/* +@@ LUAI_GCMUL defines the default speed of garbage collection relative to +@* memory allocation as a percentage. +** CHANGE it if you want to change the granularity of the garbage +** collection. (Higher values mean coarser collections. 0 represents +** infinity, where each step performs a full collection.) You can also +** change this value dynamically. +*/ +#define LUAI_GCMUL 200 /* GC runs 'twice the speed' of memory allocation */ + + + +/* +@@ LUA_COMPAT_GETN controls compatibility with old getn behavior. +** CHANGE it (define it) if you want exact compatibility with the +** behavior of setn/getn in Lua 5.0. +*/ +#undef LUA_COMPAT_GETN + +/* +@@ LUA_COMPAT_LOADLIB controls compatibility about global loadlib. +** CHANGE it to undefined as soon as you do not need a global 'loadlib' +** function (the function is still available as 'package.loadlib'). +*/ +#undef LUA_COMPAT_LOADLIB + +/* +@@ LUA_COMPAT_VARARG controls compatibility with old vararg feature. +** CHANGE it to undefined as soon as your programs use only '...' to +** access vararg parameters (instead of the old 'arg' table). +*/ +#define LUA_COMPAT_VARARG + +/* +@@ LUA_COMPAT_MOD controls compatibility with old math.mod function. +** CHANGE it to undefined as soon as your programs use 'math.fmod' or +** the new '%' operator instead of 'math.mod'. +*/ +#define LUA_COMPAT_MOD + +/* +@@ LUA_COMPAT_LSTR controls compatibility with old long string nesting +@* facility. +** CHANGE it to 2 if you want the old behaviour, or undefine it to turn +** off the advisory error when nesting [[...]]. +*/ +#define LUA_COMPAT_LSTR 1 + +/* +@@ LUA_COMPAT_GFIND controls compatibility with old 'string.gfind' name. +** CHANGE it to undefined as soon as you rename 'string.gfind' to +** 'string.gmatch'. +*/ +#define LUA_COMPAT_GFIND + +/* +@@ LUA_COMPAT_OPENLIB controls compatibility with old 'luaL_openlib' +@* behavior. +** CHANGE it to undefined as soon as you replace to 'luaL_register' +** your uses of 'luaL_openlib' +*/ +#define LUA_COMPAT_OPENLIB + + + +/* +@@ luai_apicheck is the assert macro used by the Lua-C API. +** CHANGE luai_apicheck if you want Lua to perform some checks in the +** parameters it gets from API calls. This may slow down the interpreter +** a bit, but may be quite useful when debugging C code that interfaces +** with Lua. A useful redefinition is to use assert.h. +*/ +#if defined(LUA_USE_APICHECK) +#include +#define luai_apicheck(L,o) { (void)L; assert(o); } +#else +#define luai_apicheck(L,o) { (void)L; } +#endif + + +/* +@@ LUAI_BITSINT defines the number of bits in an int. +** CHANGE here if Lua cannot automatically detect the number of bits of +** your machine. Probably you do not need to change this. +*/ +/* avoid overflows in comparison */ +#if INT_MAX-20 < 32760 +#define LUAI_BITSINT 16 +#elif INT_MAX > 2147483640L +/* int has at least 32 bits */ +#define LUAI_BITSINT 32 +#else +#error "you must define LUA_BITSINT with number of bits in an integer" +#endif + + +/* +@@ LUAI_UINT32 is an unsigned integer with at least 32 bits. +@@ LUAI_INT32 is an signed integer with at least 32 bits. +@@ LUAI_UMEM is an unsigned integer big enough to count the total +@* memory used by Lua. +@@ LUAI_MEM is a signed integer big enough to count the total memory +@* used by Lua. +** CHANGE here if for some weird reason the default definitions are not +** good enough for your machine. (The definitions in the 'else' +** part always works, but may waste space on machines with 64-bit +** longs.) Probably you do not need to change this. +*/ +#if LUAI_BITSINT >= 32 +#define LUAI_UINT32 unsigned int +#define LUAI_INT32 int +#define LUAI_MAXINT32 INT_MAX +#define LUAI_UMEM size_t +#define LUAI_MEM ptrdiff_t +#else +/* 16-bit ints */ +#define LUAI_UINT32 unsigned long +#define LUAI_INT32 long +#define LUAI_MAXINT32 LONG_MAX +#define LUAI_UMEM unsigned long +#define LUAI_MEM long +#endif + + +/* +@@ LUAI_MAXCALLS limits the number of nested calls. +** CHANGE it if you need really deep recursive calls. This limit is +** arbitrary; its only purpose is to stop infinite recursion before +** exhausting memory. +*/ +#define LUAI_MAXCALLS 20000 + + +/* +@@ LUAI_MAXCSTACK limits the number of Lua stack slots that a C function +@* can use. +** CHANGE it if you need lots of (Lua) stack space for your C +** functions. This limit is arbitrary; its only purpose is to stop C +** functions to consume unlimited stack space. (must be smaller than +** -LUA_REGISTRYINDEX) +*/ +#define LUAI_MAXCSTACK 8000 + + + +/* +** {================================================================== +** CHANGE (to smaller values) the following definitions if your system +** has a small C stack. (Or you may want to change them to larger +** values if your system has a large C stack and these limits are +** too rigid for you.) Some of these constants control the size of +** stack-allocated arrays used by the compiler or the interpreter, while +** others limit the maximum number of recursive calls that the compiler +** or the interpreter can perform. Values too large may cause a C stack +** overflow for some forms of deep constructs. +** =================================================================== +*/ + + +/* +@@ LUAI_MAXCCALLS is the maximum depth for nested C calls (short) and +@* syntactical nested non-terminals in a program. +*/ +#define LUAI_MAXCCALLS 200 + + +/* +@@ LUAI_MAXVARS is the maximum number of local variables per function +@* (must be smaller than 250). +*/ +#define LUAI_MAXVARS 200 + + +/* +@@ LUAI_MAXUPVALUES is the maximum number of upvalues per function +@* (must be smaller than 250). +*/ +#define LUAI_MAXUPVALUES 60 + + +/* +@@ LUAL_BUFFERSIZE is the buffer size used by the lauxlib buffer system. +*/ +#define LUAL_BUFFERSIZE BUFSIZ + +/* }================================================================== */ + + + + +/* +** {================================================================== +@@ LUA_NUMBER is the type of numbers in Lua. +** CHANGE the following definitions only if you want to build Lua +** with a number type different from double. You may also need to +** change lua_number2int & lua_number2integer. +** =================================================================== +*/ + +#define LUA_NUMBER_DOUBLE +#define LUA_NUMBER double + +/* +@@ LUAI_UACNUMBER is the result of an 'usual argument conversion' +@* over a number. +*/ +#define LUAI_UACNUMBER double + + +/* +@@ LUA_NUMBER_SCAN is the format for reading numbers. +@@ LUA_NUMBER_FMT is the format for writing numbers. +@@ lua_number2str converts a number to a string. +@@ LUAI_MAXNUMBER2STR is maximum size of previous conversion. +@@ lua_str2number converts a string to a number. +*/ +#define LUA_NUMBER_SCAN "%lf" +#define LUA_NUMBER_FMT "%.14g" +#define lua_number2str(s,n) sprintf((s), LUA_NUMBER_FMT, (n)) +#define LUAI_MAXNUMBER2STR 32 /* 16 digits, sign, point, and \0 */ +#define lua_str2number(s,p) strtod((s), (p)) + + +/* +@@ The luai_num* macros define the primitive operations over numbers. +*/ +#if defined(LUA_CORE) +#include +#define luai_numadd(a,b) ((a)+(b)) +#define luai_numsub(a,b) ((a)-(b)) +#define luai_nummul(a,b) ((a)*(b)) +#define luai_numdiv(a,b) ((a)/(b)) +#define luai_nummod(a,b) ((a) - floor((a)/(b))*(b)) +#define luai_numpow(a,b) (pow(a,b)) +#define luai_numunm(a) (-(a)) +#define luai_numeq(a,b) ((a)==(b)) +#define luai_numlt(a,b) ((a)<(b)) +#define luai_numle(a,b) ((a)<=(b)) +#define luai_numisnan(a) (!luai_numeq((a), (a))) +#endif + + +/* +@@ lua_number2int is a macro to convert lua_Number to int. +@@ lua_number2integer is a macro to convert lua_Number to lua_Integer. +** CHANGE them if you know a faster way to convert a lua_Number to +** int (with any rounding method and without throwing errors) in your +** system. In Pentium machines, a naive typecast from double to int +** in C is extremely slow, so any alternative is worth trying. +*/ + +/* On a Pentium, resort to a trick */ +#if defined(LUA_NUMBER_DOUBLE) && !defined(LUA_ANSI) && !defined(__SSE2__) && \ + (defined(__i386) || defined (_M_IX86) || defined(__i386__)) + +/* On a Microsoft compiler, use assembler */ +#if defined(_MSC_VER) + +#define lua_number2int(i,d) __asm fld d __asm fistp i +#define lua_number2integer(i,n) lua_number2int(i, n) + +/* the next trick should work on any Pentium, but sometimes clashes + with a DirectX idiosyncrasy */ +#else + +union luai_Cast { double l_d; long l_l; }; +#define lua_number2int(i,d) \ + { volatile union luai_Cast u; u.l_d = (d) + 6755399441055744.0; (i) = u.l_l; } +#define lua_number2integer(i,n) lua_number2int(i, n) + +#endif + + +/* this option always works, but may be slow */ +#else +#define lua_number2int(i,d) ((i)=(int)(d)) +#define lua_number2integer(i,d) ((i)=(lua_Integer)(d)) + +#endif + +/* }================================================================== */ + + +/* +@@ LUAI_USER_ALIGNMENT_T is a type that requires maximum alignment. +** CHANGE it if your system requires alignments larger than double. (For +** instance, if your system supports long doubles and they must be +** aligned in 16-byte boundaries, then you should add long double in the +** union.) Probably you do not need to change this. +*/ +#define LUAI_USER_ALIGNMENT_T union { double u; void *s; long l; } + + +/* +@@ LUAI_THROW/LUAI_TRY define how Lua does exception handling. +** CHANGE them if you prefer to use longjmp/setjmp even with C++ +** or if want/don't to use _longjmp/_setjmp instead of regular +** longjmp/setjmp. By default, Lua handles errors with exceptions when +** compiling as C++ code, with _longjmp/_setjmp when asked to use them, +** and with longjmp/setjmp otherwise. +*/ +#if defined(__cplusplus) +/* C++ exceptions */ +#define LUAI_THROW(L,c) throw(c) +#define LUAI_TRY(L,c,a) try { a } catch(...) \ + { if ((c)->status == 0) (c)->status = -1; } +#define luai_jmpbuf int /* dummy variable */ + +#elif defined(LUA_USE_ULONGJMP) +/* in Unix, try _longjmp/_setjmp (more efficient) */ +#define LUAI_THROW(L,c) _longjmp((c)->b, 1) +#define LUAI_TRY(L,c,a) if (_setjmp((c)->b) == 0) { a } +#define luai_jmpbuf jmp_buf + +#else +/* default handling with long jumps */ +#define LUAI_THROW(L,c) longjmp((c)->b, 1) +#define LUAI_TRY(L,c,a) if (setjmp((c)->b) == 0) { a } +#define luai_jmpbuf jmp_buf + +#endif + + +/* +@@ LUA_MAXCAPTURES is the maximum number of captures that a pattern +@* can do during pattern-matching. +** CHANGE it if you need more captures. This limit is arbitrary. +*/ +#define LUA_MAXCAPTURES 32 + + +/* +@@ lua_tmpnam is the function that the OS library uses to create a +@* temporary name. +@@ LUA_TMPNAMBUFSIZE is the maximum size of a name created by lua_tmpnam. +** CHANGE them if you have an alternative to tmpnam (which is considered +** insecure) or if you want the original tmpnam anyway. By default, Lua +** uses tmpnam except when POSIX is available, where it uses mkstemp. +*/ +#if defined(loslib_c) || defined(luaall_c) + +#if defined(LUA_USE_MKSTEMP) +#include +#define LUA_TMPNAMBUFSIZE 32 +#define lua_tmpnam(b,e) { \ + strcpy(b, "/tmp/lua_XXXXXX"); \ + e = mkstemp(b); \ + if (e != -1) close(e); \ + e = (e == -1); } + +#else +#define LUA_TMPNAMBUFSIZE L_tmpnam +#define lua_tmpnam(b,e) { e = (tmpnam(b) == NULL); } +#endif + +#endif + + +/* +@@ lua_popen spawns a new process connected to the current one through +@* the file streams. +** CHANGE it if you have a way to implement it in your system. +*/ +#if defined(LUA_USE_POPEN) + +#define lua_popen(L,c,m) ((void)L, fflush(NULL), popen(c,m)) +#define lua_pclose(L,file) ((void)L, (pclose(file) != -1)) + +#elif defined(LUA_WIN) + +#define lua_popen(L,c,m) ((void)L, _popen(c,m)) +#define lua_pclose(L,file) ((void)L, (_pclose(file) != -1)) + +#else + +#define lua_popen(L,c,m) ((void)((void)c, m), \ + luaL_error(L, LUA_QL("popen") " not supported"), (FILE*)0) +#define lua_pclose(L,file) ((void)((void)L, file), 0) + +#endif + +/* +@@ LUA_DL_* define which dynamic-library system Lua should use. +** CHANGE here if Lua has problems choosing the appropriate +** dynamic-library system for your platform (either Windows' DLL, Mac's +** dyld, or Unix's dlopen). If your system is some kind of Unix, there +** is a good chance that it has dlopen, so LUA_DL_DLOPEN will work for +** it. To use dlopen you also need to adapt the src/Makefile (probably +** adding -ldl to the linker options), so Lua does not select it +** automatically. (When you change the makefile to add -ldl, you must +** also add -DLUA_USE_DLOPEN.) +** If you do not want any kind of dynamic library, undefine all these +** options. +** By default, _WIN32 gets LUA_DL_DLL and MAC OS X gets LUA_DL_DYLD. +*/ +#if defined(LUA_USE_DLOPEN) +#define LUA_DL_DLOPEN +#endif + +#if defined(LUA_WIN) +#define LUA_DL_DLL +#endif + + +/* +@@ LUAI_EXTRASPACE allows you to add user-specific data in a lua_State +@* (the data goes just *before* the lua_State pointer). +** CHANGE (define) this if you really need that. This value must be +** a multiple of the maximum alignment required for your machine. +*/ +#define LUAI_EXTRASPACE 0 + + +/* +@@ luai_userstate* allow user-specific actions on threads. +** CHANGE them if you defined LUAI_EXTRASPACE and need to do something +** extra when a thread is created/deleted/resumed/yielded. +*/ +#define luai_userstateopen(L) ((void)L) +#define luai_userstateclose(L) ((void)L) +#define luai_userstatethread(L,L1) ((void)L) +#define luai_userstatefree(L) ((void)L) +#define luai_userstateresume(L,n) ((void)L) +#define luai_userstateyield(L,n) ((void)L) + + +/* +@@ LUA_INTFRMLEN is the length modifier for integer conversions +@* in 'string.format'. +@@ LUA_INTFRM_T is the integer type correspoding to the previous length +@* modifier. +** CHANGE them if your system supports long long or does not support long. +*/ + +#if defined(LUA_USELONGLONG) + +#define LUA_INTFRMLEN "ll" +#define LUA_INTFRM_T long long + +#else + +#define LUA_INTFRMLEN "l" +#define LUA_INTFRM_T long + +#endif + + + +/* =================================================================== */ + +/* +** Local configuration. You can use this space to add your redefinitions +** without modifying the main part of the file. +*/ + + + +#endif + diff --git a/third-party/lua/include/lualib.h b/third-party/lua/include/lualib.h new file mode 100644 index 00000000..469417f6 --- /dev/null +++ b/third-party/lua/include/lualib.h @@ -0,0 +1,53 @@ +/* +** $Id: lualib.h,v 1.36.1.1 2007/12/27 13:02:25 roberto Exp $ +** Lua standard libraries +** See Copyright Notice in lua.h +*/ + + +#ifndef lualib_h +#define lualib_h + +#include "lua.h" + + +/* Key to file-handle type */ +#define LUA_FILEHANDLE "FILE*" + + +#define LUA_COLIBNAME "coroutine" +LUALIB_API int (luaopen_base) (lua_State *L); + +#define LUA_TABLIBNAME "table" +LUALIB_API int (luaopen_table) (lua_State *L); + +#define LUA_IOLIBNAME "io" +LUALIB_API int (luaopen_io) (lua_State *L); + +#define LUA_OSLIBNAME "os" +LUALIB_API int (luaopen_os) (lua_State *L); + +#define LUA_STRLIBNAME "string" +LUALIB_API int (luaopen_string) (lua_State *L); + +#define LUA_MATHLIBNAME "math" +LUALIB_API int (luaopen_math) (lua_State *L); + +#define LUA_DBLIBNAME "debug" +LUALIB_API int (luaopen_debug) (lua_State *L); + +#define LUA_LOADLIBNAME "package" +LUALIB_API int (luaopen_package) (lua_State *L); + + +/* open all previous libraries */ +LUALIB_API void (luaL_openlibs) (lua_State *L); + + + +#ifndef lua_assert +#define lua_assert(x) ((void)0) +#endif + + +#endif diff --git a/third-party/lua/lua.dll b/third-party/lua/lua.dll new file mode 100644 index 00000000..353c2194 Binary files /dev/null and b/third-party/lua/lua.dll differ diff --git a/third-party/lua/lua.lib b/third-party/lua/lua.lib new file mode 100644 index 00000000..34b3cb67 Binary files /dev/null and b/third-party/lua/lua.lib differ diff --git a/www/css/UnitMarker.css b/www/css/UnitMarker.css new file mode 100644 index 00000000..a312cd36 --- /dev/null +++ b/www/css/UnitMarker.css @@ -0,0 +1,59 @@ +.unitmarker-container-table { + height: 60px; + width: 60px; + left: -30px; + top: -30px; + border: 1px transparent solid; + position: absolute; +} + +.unitmarker-icon-img { + height: 60px; + width: 60px; + left: 0px; + top: 0px; + display: block; + opacity: 0.8; + position: absolute; +} + +.unitmarker-selection-img { + height: 60px; + width: 60px; + left: 0px; + top: 0px; + display: block; + position: absolute; + animation: spin 4s linear infinite; + opacity: 0; +} + +@keyframes spin { + 100% { + transform:rotate(360deg); + } +} + +.unitmarker-icon-img-blue { + filter: invert(37%) sepia(21%) saturate(7402%) hue-rotate(193deg) brightness(103%) contrast(104%) drop-shadow(1px 1px 0 black) drop-shadow(-1px -1px 0 black); +} + +.unitmarker-icon-img-hovered { + filter: invert(100%) sepia(3%) saturate(0%) hue-rotate(125deg) brightness(103%) contrast(103%) drop-shadow(1px 1px 0 black) drop-shadow(-1px -1px 0 black); +} + +.unitmarker-icon-img-selected { + filter: invert(100%) sepia(3%) saturate(0%) hue-rotate(125deg) brightness(103%) contrast(103%) drop-shadow(1px 1px 0 black) drop-shadow(-1px -1px 0 black); +} + +.unitmarker-name-div { + width: 100%; + left: 0px; + top: -20px; + position: absolute; + text-align: center; + font: 800 16px Arial; + white-space: nowrap; + -webkit-text-fill-color: white; + -webkit-text-stroke: 1px; +} \ No newline at end of file diff --git a/www/css/index.css b/www/css/index.css new file mode 100644 index 00000000..41fb4d5d --- /dev/null +++ b/www/css/index.css @@ -0,0 +1,84 @@ +body{ + margin-top: 0px; + margin-bottom: 0px; + margin-left: 0px; + margin-right: 0px; + background-color: #2d3e50; + font-family: "Lucida Console", "Courier New", monospace; +} + +#content-table { + height: 100%; + width: 100%; +} + +#top-panel { + height: 40px; +} + +#bottom-panel { + height: 100px +} + +#log { + background-color: #202831AA; + height: 100px; + width: 400px; + border: solid white 1px; + font-size: 12px; + overflow-y: scroll; + position: fixed; + z-index: 1000; + top: 50px; + right: 10px; +} + +.log-message { + margin: 2px; + color: white; + text-shadow: 1px 1px #000, -1px -1px #000, 1px -1px #000, -1px 1px #000; +} + +.error-message{ + margin: 2px; + color: rgb(255, 154, 154); + text-shadow: 1px 1px #000, -1px -1px #000, 1px -1px #000, -1px 1px #000; +} + +#left-panel { + background-color: #202831; + height: 100px; + width: 400px; + border: solid white 1px; + font-size: 12px; + position: fixed; + z-index: 1000; + left: 10px; + bottom: -80px; + transition: bottom 0.2s; +} + +.panel-table +{ + text-shadow: 1px 1px #000, -1px -1px #000, 1px -1px #000, -1px 1px #000; +} + +.panel-title +{ + font-size: 14px; + color: #d3e9ff; +} + +.panel-label +{ + font-size: 12px; + color: #d3e9ff; +} + +.panel-content +{ + font-size: 12px; + color: white; +} + + diff --git a/www/css/map.css b/www/css/map.css new file mode 100644 index 00000000..3a5597ff --- /dev/null +++ b/www/css/map.css @@ -0,0 +1,8 @@ +#map { + +} + +.leaflet-container.move-cursor-enabled { + cursor: crosshair; +} + diff --git a/www/img/banner.xcf b/www/img/banner.xcf new file mode 100644 index 00000000..e6031764 Binary files /dev/null and b/www/img/banner.xcf differ diff --git a/www/img/cursors/move.png b/www/img/cursors/move.png new file mode 100644 index 00000000..badc7148 Binary files /dev/null and b/www/img/cursors/move.png differ diff --git a/www/img/patch.png b/www/img/patch.png new file mode 100644 index 00000000..46b43691 Binary files /dev/null and b/www/img/patch.png differ diff --git a/www/img/selected.png b/www/img/selected.png new file mode 100644 index 00000000..c6f6fd70 Binary files /dev/null and b/www/img/selected.png differ diff --git a/www/img/selection.png b/www/img/selection.png new file mode 100644 index 00000000..2296791a Binary files /dev/null and b/www/img/selection.png differ diff --git a/www/img/units/AH-1W.png b/www/img/units/AH-1W.png new file mode 100644 index 00000000..92e33842 Binary files /dev/null and b/www/img/units/AH-1W.png differ diff --git a/www/img/units/FA-18C.png b/www/img/units/FA-18C.png new file mode 100644 index 00000000..8bf29977 Binary files /dev/null and b/www/img/units/FA-18C.png differ diff --git a/www/img/units/Hercules.png b/www/img/units/Hercules.png new file mode 100644 index 00000000..5a624178 Binary files /dev/null and b/www/img/units/Hercules.png differ diff --git a/www/img/units/Mi-24P.png b/www/img/units/Mi-24P.png new file mode 100644 index 00000000..43b752cd Binary files /dev/null and b/www/img/units/Mi-24P.png differ diff --git a/www/img/units/a-10.png b/www/img/units/a-10.png new file mode 100644 index 00000000..0fcad32a Binary files /dev/null and b/www/img/units/a-10.png differ diff --git a/www/img/units/a-10a.png b/www/img/units/a-10a.png new file mode 100644 index 00000000..73e429df Binary files /dev/null and b/www/img/units/a-10a.png differ diff --git a/www/img/units/a-4.png b/www/img/units/a-4.png new file mode 100644 index 00000000..1b9d3ca3 Binary files /dev/null and b/www/img/units/a-4.png differ diff --git a/www/img/units/a-400.png b/www/img/units/a-400.png new file mode 100644 index 00000000..c85d4086 Binary files /dev/null and b/www/img/units/a-400.png differ diff --git a/www/img/units/a-50.png b/www/img/units/a-50.png new file mode 100644 index 00000000..f8bcb713 Binary files /dev/null and b/www/img/units/a-50.png differ diff --git a/www/img/units/a-6.png b/www/img/units/a-6.png new file mode 100644 index 00000000..16a8d16b Binary files /dev/null and b/www/img/units/a-6.png differ diff --git a/www/img/units/ah-64.png b/www/img/units/ah-64.png new file mode 100644 index 00000000..9047f612 Binary files /dev/null and b/www/img/units/ah-64.png differ diff --git a/www/img/units/airliner2engine.png b/www/img/units/airliner2engine.png new file mode 100644 index 00000000..e14bd500 Binary files /dev/null and b/www/img/units/airliner2engine.png differ diff --git a/www/img/units/an-26.png b/www/img/units/an-26.png new file mode 100644 index 00000000..f7242652 Binary files /dev/null and b/www/img/units/an-26.png differ diff --git a/www/img/units/av8bna.png b/www/img/units/av8bna.png new file mode 100644 index 00000000..441f0963 Binary files /dev/null and b/www/img/units/av8bna.png differ diff --git a/www/img/units/b-1.png b/www/img/units/b-1.png new file mode 100644 index 00000000..ba8fe50c Binary files /dev/null and b/www/img/units/b-1.png differ diff --git a/www/img/units/b-17.png b/www/img/units/b-17.png new file mode 100644 index 00000000..2fb7632e Binary files /dev/null and b/www/img/units/b-17.png differ diff --git a/www/img/units/b-2.png b/www/img/units/b-2.png new file mode 100644 index 00000000..3521fcb6 Binary files /dev/null and b/www/img/units/b-2.png differ diff --git a/www/img/units/b-52.png b/www/img/units/b-52.png new file mode 100644 index 00000000..4816a9f0 Binary files /dev/null and b/www/img/units/b-52.png differ diff --git a/www/img/units/b707.png b/www/img/units/b707.png new file mode 100644 index 00000000..45bcd82f Binary files /dev/null and b/www/img/units/b707.png differ diff --git a/www/img/units/bf109.png b/www/img/units/bf109.png new file mode 100644 index 00000000..de594005 Binary files /dev/null and b/www/img/units/bf109.png differ diff --git a/www/img/units/c-101.png b/www/img/units/c-101.png new file mode 100644 index 00000000..0327a089 Binary files /dev/null and b/www/img/units/c-101.png differ diff --git a/www/img/units/c-130.png b/www/img/units/c-130.png new file mode 100644 index 00000000..f172fd1b Binary files /dev/null and b/www/img/units/c-130.png differ diff --git a/www/img/units/c-17.png b/www/img/units/c-17.png new file mode 100644 index 00000000..b865b1ac Binary files /dev/null and b/www/img/units/c-17.png differ diff --git a/www/img/units/c-5.png b/www/img/units/c-5.png new file mode 100644 index 00000000..2a6904c4 Binary files /dev/null and b/www/img/units/c-5.png differ diff --git a/www/img/units/ch-53.png b/www/img/units/ch-53.png new file mode 100644 index 00000000..fcf861f9 Binary files /dev/null and b/www/img/units/ch-53.png differ diff --git a/www/img/units/e-2.png b/www/img/units/e-2.png new file mode 100644 index 00000000..04f3bb2f Binary files /dev/null and b/www/img/units/e-2.png differ diff --git a/www/img/units/e-3.png b/www/img/units/e-3.png new file mode 100644 index 00000000..3b55c457 Binary files /dev/null and b/www/img/units/e-3.png differ diff --git a/www/img/units/eurofighter.png b/www/img/units/eurofighter.png new file mode 100644 index 00000000..7d07165a Binary files /dev/null and b/www/img/units/eurofighter.png differ diff --git a/www/img/units/f-111.png b/www/img/units/f-111.png new file mode 100644 index 00000000..c882eb68 Binary files /dev/null and b/www/img/units/f-111.png differ diff --git a/www/img/units/f-117.png b/www/img/units/f-117.png new file mode 100644 index 00000000..9cad03bc Binary files /dev/null and b/www/img/units/f-117.png differ diff --git a/www/img/units/f-14.png b/www/img/units/f-14.png new file mode 100644 index 00000000..65547eac Binary files /dev/null and b/www/img/units/f-14.png differ diff --git a/www/img/units/f-15.png b/www/img/units/f-15.png new file mode 100644 index 00000000..51671c84 Binary files /dev/null and b/www/img/units/f-15.png differ diff --git a/www/img/units/f-15e.png b/www/img/units/f-15e.png new file mode 100644 index 00000000..5697f985 Binary files /dev/null and b/www/img/units/f-15e.png differ diff --git a/www/img/units/f-16.png b/www/img/units/f-16.png new file mode 100644 index 00000000..96b6f13f Binary files /dev/null and b/www/img/units/f-16.png differ diff --git a/www/img/units/f-22.png b/www/img/units/f-22.png new file mode 100644 index 00000000..2274ef92 Binary files /dev/null and b/www/img/units/f-22.png differ diff --git a/www/img/units/f-35.png b/www/img/units/f-35.png new file mode 100644 index 00000000..ff42a180 Binary files /dev/null and b/www/img/units/f-35.png differ diff --git a/www/img/units/f-4.png b/www/img/units/f-4.png new file mode 100644 index 00000000..0449d2f2 Binary files /dev/null and b/www/img/units/f-4.png differ diff --git a/www/img/units/f-5.png b/www/img/units/f-5.png new file mode 100644 index 00000000..a0cc5307 Binary files /dev/null and b/www/img/units/f-5.png differ diff --git a/www/img/units/f-86.png b/www/img/units/f-86.png new file mode 100644 index 00000000..e18a699a Binary files /dev/null and b/www/img/units/f-86.png differ diff --git a/www/img/units/fw190.png b/www/img/units/fw190.png new file mode 100644 index 00000000..4ef9b910 Binary files /dev/null and b/www/img/units/fw190.png differ diff --git a/www/img/units/general1.png b/www/img/units/general1.png new file mode 100644 index 00000000..7a6670b3 Binary files /dev/null and b/www/img/units/general1.png differ diff --git a/www/img/units/gripen.png b/www/img/units/gripen.png new file mode 100644 index 00000000..92eb9791 Binary files /dev/null and b/www/img/units/gripen.png differ diff --git a/www/img/units/hawk.png b/www/img/units/hawk.png new file mode 100644 index 00000000..53c72788 Binary files /dev/null and b/www/img/units/hawk.png differ diff --git a/www/img/units/helicopter1.png b/www/img/units/helicopter1.png new file mode 100644 index 00000000..b69e2153 Binary files /dev/null and b/www/img/units/helicopter1.png differ diff --git a/www/img/units/il-76.png b/www/img/units/il-76.png new file mode 100644 index 00000000..f28d2ba2 Binary files /dev/null and b/www/img/units/il-76.png differ diff --git a/www/img/units/il-78m.png b/www/img/units/il-78m.png new file mode 100644 index 00000000..d7bb3ee5 Binary files /dev/null and b/www/img/units/il-78m.png differ diff --git a/www/img/units/j-10.png b/www/img/units/j-10.png new file mode 100644 index 00000000..91cfd1a9 Binary files /dev/null and b/www/img/units/j-10.png differ diff --git a/www/img/units/j-20.png b/www/img/units/j-20.png new file mode 100644 index 00000000..d26691b7 Binary files /dev/null and b/www/img/units/j-20.png differ diff --git a/www/img/units/j-7.png b/www/img/units/j-7.png new file mode 100644 index 00000000..5b559b28 Binary files /dev/null and b/www/img/units/j-7.png differ diff --git a/www/img/units/jf-17.png b/www/img/units/jf-17.png new file mode 100644 index 00000000..3cd5f85b Binary files /dev/null and b/www/img/units/jf-17.png differ diff --git a/www/img/units/ju-88.png b/www/img/units/ju-88.png new file mode 100644 index 00000000..89a4df8e Binary files /dev/null and b/www/img/units/ju-88.png differ diff --git a/www/img/units/ka-50.png b/www/img/units/ka-50.png new file mode 100644 index 00000000..a4fa93b4 Binary files /dev/null and b/www/img/units/ka-50.png differ diff --git a/www/img/units/kc-10.png b/www/img/units/kc-10.png new file mode 100644 index 00000000..e11dfa76 Binary files /dev/null and b/www/img/units/kc-10.png differ diff --git a/www/img/units/kc-130.png b/www/img/units/kc-130.png new file mode 100644 index 00000000..5a624178 Binary files /dev/null and b/www/img/units/kc-130.png differ diff --git a/www/img/units/kc-135.png b/www/img/units/kc-135.png new file mode 100644 index 00000000..30828dbe Binary files /dev/null and b/www/img/units/kc-135.png differ diff --git a/www/img/units/kc-135mprs.png b/www/img/units/kc-135mprs.png new file mode 100644 index 00000000..30828dbe Binary files /dev/null and b/www/img/units/kc-135mprs.png differ diff --git a/www/img/units/l-159.png b/www/img/units/l-159.png new file mode 100644 index 00000000..315182e3 Binary files /dev/null and b/www/img/units/l-159.png differ diff --git a/www/img/units/l-39.png b/www/img/units/l-39.png new file mode 100644 index 00000000..dec49d56 Binary files /dev/null and b/www/img/units/l-39.png differ diff --git a/www/img/units/l-39za.png b/www/img/units/l-39za.png new file mode 100644 index 00000000..38a429be Binary files /dev/null and b/www/img/units/l-39za.png differ diff --git a/www/img/units/m-2000C.png b/www/img/units/m-2000C.png new file mode 100644 index 00000000..b27d0491 Binary files /dev/null and b/www/img/units/m-2000C.png differ diff --git a/www/img/units/mi-24.png b/www/img/units/mi-24.png new file mode 100644 index 00000000..43b752cd Binary files /dev/null and b/www/img/units/mi-24.png differ diff --git a/www/img/units/mi-28.png b/www/img/units/mi-28.png new file mode 100644 index 00000000..287a31ca Binary files /dev/null and b/www/img/units/mi-28.png differ diff --git a/www/img/units/mi-8.png b/www/img/units/mi-8.png new file mode 100644 index 00000000..7692cace Binary files /dev/null and b/www/img/units/mi-8.png differ diff --git a/www/img/units/mig-15.png b/www/img/units/mig-15.png new file mode 100644 index 00000000..d94f6022 Binary files /dev/null and b/www/img/units/mig-15.png differ diff --git a/www/img/units/mig-21.png b/www/img/units/mig-21.png new file mode 100644 index 00000000..92b0fb8d Binary files /dev/null and b/www/img/units/mig-21.png differ diff --git a/www/img/units/mig-23.png b/www/img/units/mig-23.png new file mode 100644 index 00000000..eb8125cd Binary files /dev/null and b/www/img/units/mig-23.png differ diff --git a/www/img/units/mig-25.png b/www/img/units/mig-25.png new file mode 100644 index 00000000..cd596b7f Binary files /dev/null and b/www/img/units/mig-25.png differ diff --git a/www/img/units/mig-29.png b/www/img/units/mig-29.png new file mode 100644 index 00000000..448bf3c1 Binary files /dev/null and b/www/img/units/mig-29.png differ diff --git a/www/img/units/mig-31.png b/www/img/units/mig-31.png new file mode 100644 index 00000000..cd596b7f Binary files /dev/null and b/www/img/units/mig-31.png differ diff --git a/www/img/units/mq-9 reaper.png b/www/img/units/mq-9 reaper.png new file mode 100644 index 00000000..8ed2f8b4 Binary files /dev/null and b/www/img/units/mq-9 reaper.png differ diff --git a/www/img/units/multiengine.png b/www/img/units/multiengine.png new file mode 100644 index 00000000..6cecbd7b Binary files /dev/null and b/www/img/units/multiengine.png differ diff --git a/www/img/units/p-47.png b/www/img/units/p-47.png new file mode 100644 index 00000000..7b2384e5 Binary files /dev/null and b/www/img/units/p-47.png differ diff --git a/www/img/units/p-51.png b/www/img/units/p-51.png new file mode 100644 index 00000000..02e7faca Binary files /dev/null and b/www/img/units/p-51.png differ diff --git a/www/img/units/rafale.png b/www/img/units/rafale.png new file mode 100644 index 00000000..ab07de2c Binary files /dev/null and b/www/img/units/rafale.png differ diff --git a/www/img/units/rq-1 predator.png b/www/img/units/rq-1 predator.png new file mode 100644 index 00000000..a724a77e Binary files /dev/null and b/www/img/units/rq-1 predator.png differ diff --git a/www/img/units/rq-4.png b/www/img/units/rq-4.png new file mode 100644 index 00000000..a406087d Binary files /dev/null and b/www/img/units/rq-4.png differ diff --git a/www/img/units/s-3.png b/www/img/units/s-3.png new file mode 100644 index 00000000..60fc9875 Binary files /dev/null and b/www/img/units/s-3.png differ diff --git a/www/img/units/sa-342.png b/www/img/units/sa-342.png new file mode 100644 index 00000000..5a160665 Binary files /dev/null and b/www/img/units/sa-342.png differ diff --git a/www/img/units/spitfire.png b/www/img/units/spitfire.png new file mode 100644 index 00000000..adad911c Binary files /dev/null and b/www/img/units/spitfire.png differ diff --git a/www/img/units/su-17.png b/www/img/units/su-17.png new file mode 100644 index 00000000..75c557a6 Binary files /dev/null and b/www/img/units/su-17.png differ diff --git a/www/img/units/su-17m4.png b/www/img/units/su-17m4.png new file mode 100644 index 00000000..9202770f Binary files /dev/null and b/www/img/units/su-17m4.png differ diff --git a/www/img/units/su-24.png b/www/img/units/su-24.png new file mode 100644 index 00000000..bd5742e9 Binary files /dev/null and b/www/img/units/su-24.png differ diff --git a/www/img/units/su-25.png b/www/img/units/su-25.png new file mode 100644 index 00000000..652da251 Binary files /dev/null and b/www/img/units/su-25.png differ diff --git a/www/img/units/su-27.png b/www/img/units/su-27.png new file mode 100644 index 00000000..a28414b3 Binary files /dev/null and b/www/img/units/su-27.png differ diff --git a/www/img/units/su-30.png b/www/img/units/su-30.png new file mode 100644 index 00000000..98b2e717 Binary files /dev/null and b/www/img/units/su-30.png differ diff --git a/www/img/units/su-34.png b/www/img/units/su-34.png new file mode 100644 index 00000000..1117869a Binary files /dev/null and b/www/img/units/su-34.png differ diff --git a/www/img/units/su-57.png b/www/img/units/su-57.png new file mode 100644 index 00000000..2ee430f5 Binary files /dev/null and b/www/img/units/su-57.png differ diff --git a/www/img/units/tornado.png b/www/img/units/tornado.png new file mode 100644 index 00000000..9b71e435 Binary files /dev/null and b/www/img/units/tornado.png differ diff --git a/www/img/units/tu-160.png b/www/img/units/tu-160.png new file mode 100644 index 00000000..0ac29cfa Binary files /dev/null and b/www/img/units/tu-160.png differ diff --git a/www/img/units/tu-22.png b/www/img/units/tu-22.png new file mode 100644 index 00000000..ee8368b1 Binary files /dev/null and b/www/img/units/tu-22.png differ diff --git a/www/img/units/tu-95.png b/www/img/units/tu-95.png new file mode 100644 index 00000000..2c253174 Binary files /dev/null and b/www/img/units/tu-95.png differ diff --git a/www/img/units/u-28.png b/www/img/units/u-28.png new file mode 100644 index 00000000..cbc5cc4c Binary files /dev/null and b/www/img/units/u-28.png differ diff --git a/www/img/units/uh-1.png b/www/img/units/uh-1.png new file mode 100644 index 00000000..70e48f6b Binary files /dev/null and b/www/img/units/uh-1.png differ diff --git a/www/img/units/uh-60.png b/www/img/units/uh-60.png new file mode 100644 index 00000000..14d72ff9 Binary files /dev/null and b/www/img/units/uh-60.png differ diff --git a/www/img/units/undefined.png b/www/img/units/undefined.png new file mode 100644 index 00000000..f8e3e958 Binary files /dev/null and b/www/img/units/undefined.png differ diff --git a/www/img/units/viggen.png b/www/img/units/viggen.png new file mode 100644 index 00000000..80be4dc8 Binary files /dev/null and b/www/img/units/viggen.png differ diff --git a/www/img/units/yak-40.png b/www/img/units/yak-40.png new file mode 100644 index 00000000..e8995d73 Binary files /dev/null and b/www/img/units/yak-40.png differ diff --git a/www/img/units/yak-52.png b/www/img/units/yak-52.png new file mode 100644 index 00000000..412890e5 Binary files /dev/null and b/www/img/units/yak-52.png differ diff --git a/www/index.html b/www/index.html new file mode 100644 index 00000000..e1ce04fb --- /dev/null +++ b/www/index.html @@ -0,0 +1,41 @@ + + + + + + Olympus + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+
+ + \ No newline at end of file diff --git a/www/js/LeftPanel.js b/www/js/LeftPanel.js new file mode 100644 index 00000000..ba89391b --- /dev/null +++ b/www/js/LeftPanel.js @@ -0,0 +1,94 @@ +class LeftPanel +{ + constructor() + { + this._panel = document.getElementById("left-panel"); + } + + update(selectedUnits) + { + if (selectedUnits.length > 0) + { + this._panel.style.bottom = "15px"; + if (selectedUnits.length == 1) + { + this._showUnitData(selectedUnits[0]); + } + else + { + + } + } + else + { + this._showUnitData(); + this._panel.style.bottom = "-80px"; + } + } + + _showUnitData(selectedUnit) + { + if (selectedUnit !== undefined) + { + this._panel.innerHTML = ` + + + + + + + + + + + + + + + + + + + + + +
+ UNIT INFO +
+ Name: + + ${selectedUnit.unitName} + + Group: + + ${selectedUnit.groupName} +
+ Heading: + + ${Math.floor(rad2deg(selectedUnit.heading))+"°"} + + Speed: + + kts +
+ Position: + + ${ConvertDDToDMS(selectedUnit.latitude, false) + " " + ConvertDDToDMS(selectedUnit.longitude, true)} + +
+ `; + } + else + { + this._panel.innerHTML = ` + + + + +
+ UNIT INFO +
+ `; + } + } +} \ No newline at end of file diff --git a/www/js/Map.js b/www/js/Map.js new file mode 100644 index 00000000..09af6590 --- /dev/null +++ b/www/js/Map.js @@ -0,0 +1,84 @@ +class Map +{ + constructor() + { + this._state = "IDLE"; + + this._map = L.map('map').setView([37.23, -115.8], 12); + + L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}', { + attribution: 'Tiles © Esri — Source: Esri, i-cubed, USDA, USGS, AEX, GeoEye, Getmapping, Aerogrid, IGN, IGP, UPR-EGP, and the GIS User Community' + }).addTo(this._map); + + // Main update rate. 250ms is minimum time, equal to server update time. + setInterval(() => this.update(), 250); + + // Register event handles + this._map.on('contextmenu', (e) => this.onContextMenu(e)); + this._map.on('click', (e) => this.onClick(e)); + + this.setState("IDLE"); + } + + getMap() + { + return this._map + } + + // GET new data from the server + update() + { + // Request the updated unit data from the server + var xmlHttp = new XMLHttpRequest(); + xmlHttp.open( "GET", RESTaddress, true); + + xmlHttp.onload = function(e) { + var data = JSON.parse(xmlHttp.responseText); + + missionData.update(data); + unitsHandler.update(data); + leftPanel.update(unitsHandler.getSelectedUnits()); + }; + + xmlHttp.onerror = function () { + console.error("An error occurred during the XMLHttpRequest"); + }; + xmlHttp.send( null ); + } + + // State machine + setState(newState) + { + this._state = newState; + if (this._state === "IDLE") + { + L.DomUtil.removeClass(this._map._container, 'move-cursor-enabled'); + } + else if (this._state === "UNIT_SELECTED") + { + L.DomUtil.addClass(this._map._container, 'move-cursor-enabled'); + } + } + + // Event handlers + onContextMenu(e) + { + unitsHandler.deselectAllUnits(); + } + + onClick(e) + { + if (this._state === "IDLE") + { + + } + else if (this._state === "UNIT_SELECTED") + { + if (!e.originalEvent.ctrlKey) + { + unitsHandler.clearDestinations(); + } + unitsHandler.addDestination(e.latlng) + } + } +} \ No newline at end of file diff --git a/www/js/MissionData.js b/www/js/MissionData.js new file mode 100644 index 00000000..fa952147 --- /dev/null +++ b/www/js/MissionData.js @@ -0,0 +1,26 @@ +class MissionData +{ + constructor() + { + this.bullseye = undefined; + this._bullseyeMarker = undefined; + } + + update(data) + { + this.bullseye = data.missionData.bullseye; + this._drawBullseye(); + } + + _drawBullseye() + { + if (this._bullseyeMarker === undefined) + { + this._bullseyeMarker = L.marker([this.bullseye.lat, this.bullseye.lng]).addTo(map.getMap()); + } + else + { + this._bullseyeMarker .setLatLng(new L.LatLng(this.bullseye.lat, this.bullseye.lng)); + } + } +} \ No newline at end of file diff --git a/www/js/Unit.js b/www/js/Unit.js new file mode 100644 index 00000000..cf6cc7c9 --- /dev/null +++ b/www/js/Unit.js @@ -0,0 +1,121 @@ +class Unit +{ + constructor(ID) { + this.ID = ID; + this.marker = new L.Marker.UnitMarker([0, 0], {riseOnHover: true}); + this.marker.addTo(map.getMap()).on('click', () => this.onClick()); + + this._selected = false; + + this.unitName = undefined; + this.groupName = undefined; + this.name = undefined; + this.latitude = undefined; + this.longitude = undefined; + this.altitude = undefined; + this.heading = undefined; + this.coalitionID = undefined; + this.country = undefined; + this.activePath = undefined; + + this._pathMarkers = []; + } + + update(response) + { + this.name = response["name"]; + this.unitName = response["unitName"]; + this.groupName = response["groupName"]; + this.latitude = response["latitude"]; + this.longitude = response["longitude"]; + this.altitude = response["altitude"]; + this.heading = response["heading"]; + this.coalitionID = response["coalitionID"] + if ("activePath" in response) + this.activePath = response["activePath"] + + this.drawMarker(); + this.drawPath(); + } + + setSelected(selected) + { + this._selected = selected; + this.marker.setSelected(selected); + unitsHandler.onUnitSelection(); + } + + getSelected() + { + return this._selected; + } + + addDestination(latlng) + { + var xy = latlng2xy(latlng.lat, latlng.lng) + + var xhr = new XMLHttpRequest(); + xhr.open("PUT", RESTaddress); + + xhr.setRequestHeader("Content-Type", "application/json"); + + xhr.onreadystatechange = () => { + if (xhr.readyState === 4) { + console.log(this.unitName + " add destination to (" + latlng.lat + ", " + latlng.lng + ")") + } + }; + + var command = undefined; + if (this.activePath != undefined) + { + var newPath = this.activePath; + newPath[(Object.keys(newPath).length + 1).toString()] = latlng; + command = {"ID": this.ID, "unitName": this.unitName, "path": newPath} + } + else + { + command = {"ID": this.ID, "unitName": this.unitName, "path": {"1": latlng}} + } + + var data = {"setPath": command} + + xhr.send(JSON.stringify(data)); + } + + clearDestinations() + { + this.activePath = undefined; + } + + onClick(e) + { + // TODO if ctrl is pressed, don't deselect the other units + unitsHandler.deselectAllUnits(); + this.setSelected(true); + } + + drawMarker() + { + var zIndex = this.marker.getZIndex(); + var newLatLng = new L.LatLng(this.latitude, this.longitude); + this.marker.setLatLng(newLatLng); + this.marker.setUnitName(this.unitName); + this.marker.setAngle(this.heading); + this.marker.setZIndex(zIndex); + } + + drawPath() + { + for (let WP in this.activePath) + { + var destination = this.activePath[WP]; + if (parseInt(WP) - 1 >= this._pathMarkers.length) + { + var marker = L.marker([destination.lat, destination.lng]).addTo(map.getMap()); + this._pathMarkers.push(marker); + } + this._pathMarkers[parseInt(WP) - 1].setLatLng([destination.lat, destination.lng]); + } + this._pathMarkers + } +} diff --git a/www/js/UnitMarker.js b/www/js/UnitMarker.js new file mode 100644 index 00000000..2cd7507c --- /dev/null +++ b/www/js/UnitMarker.js @@ -0,0 +1,114 @@ +L.Marker.UnitMarker = L.Marker.extend( + { + // Set the unit name and unit icon + setUnitName: function(unitName) + { + // TODO: move in constructor and call only once (does not work in addInitHook for some reason) + this._icon.style.outline = "transparent"; // Removes the rectangular outline + + if (this.unitName !== unitName) + { + // Set the unit icon + var img = this._icon.querySelector("#icon-img"); + if (img!== undefined) + { + if (unitName in unitIcons) img.src = unitIcons[unitName]; + else img.src = "img/units/undefined.png"; + + // Set image class, TODO: make fuction to change coalition + img.classList.add("unitmarker-icon-img-blue"); + } + + // Set the unit name in the marker + var nameDiv = this._icon.querySelector("#name"); + if (nameDiv!== undefined) nameDiv.innerHTML = unitName; + } + this.unitName = unitName; + }, + + // Rotates the marker to show heading + setAngle: function(angle) + { + if (this._angle !== angle){ + var img = this._icon.querySelector("#icon-img"); + if (img !== undefined) img.style.transform = "rotate(" + angle + "rad)"; + } + this._angle = angle; + }, + + setHovered: function(hovered) + { + var img = this._icon.querySelector("#icon-img"); + if (img!== undefined) + { + if (hovered) img.classList.add("unitmarker-icon-img-hovered"); + else + { + if (img.classList.contains("unitmarker-icon-img-hovered")) img.classList.remove("unitmarker-icon-img-hovered"); + } + } + }, + + setSelected: function(selected) + { + var selectedImg = this._icon.querySelector("#selection-img"); + if (selectedImg!== undefined) + { + if (selected) selectedImg.style.opacity = "1"; + else selectedImg.style.opacity = "0"; + } + + var img = this._icon.querySelector("#icon-img"); + if (img !== undefined) + { + if (selected) + { + img.classList.add("unitmarker-icon-img-selected"); + } + else + { + if (img.classList.contains("unitmarker-icon-img-selected")) img.classList.remove("unitmarker-icon-img-selected"); + } + } + }, + + getZIndex: function() + { + return this._icon.style.zIndex; + }, + + setZIndex: function(zIndex) + { + this._icon.style.zIndex = zIndex; + } + } +) + +L.Marker.UnitMarker.addInitHook(function() +{ + var icon = new L.DivIcon({html: iconHtml, className: 'DCSUnit-marker-icon'}); // Set the unit marker, className must be set to avoid white square + this.setIcon(icon); + + this.on('mouseover',function(e) { + e.target.setHovered(true); + }); + + this.on('mouseout',function(e) { + e.target.setHovered(false); + }); +}); + +var unitIcons = +{ + "A-4E-C": "img/units/a-4.png" +} + +var iconHtml = ` + + + +
+ + +
+
` \ No newline at end of file diff --git a/www/js/UnitsHandler.js b/www/js/UnitsHandler.js new file mode 100644 index 00000000..8ed32874 --- /dev/null +++ b/www/js/UnitsHandler.js @@ -0,0 +1,79 @@ +class UnitsHandler +{ + constructor() + { + this._units = {}; + } + + createUnit(ID) + { + this._units[ID] = new Unit(ID) + } + + removeUnit(ID) + { + + } + + deselectAllUnits() + { + for (let ID in this._units) + { + this._units[ID].setSelected(false); + } + } + + update(data) + { + for (let ID in data["units"]) + { + // Create the unit if missing from the local array, then update the data. Drawing is handled by leaflet. + if (!(ID in this._units)) this.createUnit(parseInt(ID)); + this._units[ID].update(data["units"][ID]); + } + } + + onUnitSelection() + { + if (this.getSelectedUnits().length > 0) map.setState("UNIT_SELECTED"); + else map.setState("IDLE"); + } + + getSelectedUnits() + { + var selectedUnits = []; + for (let ID in this._units) + { + if (this._units[ID].getSelected()) + { + selectedUnits.push(this._units[ID]); + } + } + return selectedUnits; + } + + addDestination(latlng) + { + for (let ID in this._units) + { + if (this._units[ID].getSelected()) + { + this._units[ID].addDestination(latlng); + } + } + + // After moving we are generally done and want to deselect the unit + this.deselectAllUnits(); + } + + clearDestinations(latlng) + { + for (let ID in this._units) + { + if (this._units[ID].getSelected()) + { + this._units[ID].clearDestinations(); + } + } + } +} \ No newline at end of file diff --git a/www/js/Utils.js b/www/js/Utils.js new file mode 100644 index 00000000..76fcf07b --- /dev/null +++ b/www/js/Utils.js @@ -0,0 +1,97 @@ +function distance(lat1, lon1, lat2, lon2) +{ + const R = 6371e3; // metres + const φ1 = deg2rad(lat1); // φ, λ in radians + const φ2 = deg2rad(lat2); + const Δφ = deg2rad(lat2-lat1); + const Δλ = deg2rad(lon2-lon1); + + const a = Math.sin(Δφ/2) * Math.sin(Δφ/2) + Math.cos(φ1) * Math.cos(φ2) * Math.sin(Δλ/2) * Math.sin(Δλ/2); + const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); + + const d = R * c; // in metres + + return d; +} + +function bearing(lat1, lon1, lat2, lon2) +{ + const φ1 = deg2rad(lat1); // φ, λ in radians + const φ2 = deg2rad(lat2); + const λ1 = deg2rad(lon1); // φ, λ in radians + const λ2 = deg2rad(lon2); + const y = Math.sin(λ2-λ1) * Math.cos(φ2); + const x = Math.cos(φ1)*Math.sin(φ2) - Math.sin(φ1)*Math.cos(φ2)*Math.cos(λ2-λ1); + const θ = Math.atan2(y, x); + const brng = (rad2deg(θ) + 360) % 360; // in degrees + + return brng; +} + +function latlng2xy(lat, lon) +{ + const latBulls = missionData.bullseye.lat; + const lonBulls = missionData.bullseye.lng; + const d = distance(latBulls, lonBulls, lat, lon); + const brng = bearing(latBulls, lonBulls, lat, lon); + const x = d * Math.cos(deg2rad(brng)); + const y = d * Math.sin(deg2rad(brng)); + + xy = {}; + xy.x = x; + xy.y = y; + + return xy; +} + +function xy2latlng(x, y) +{ + const xBulls = missionData.bullseye.x; + const yBulls = missionData.bullseye.y; + const latBulls = missionData.bullseye.lat; + const lonBulls = missionData.bullseye.lng; + + const R = 6371e3; // metres + const φ1 = deg2rad(latBulls); // φ, λ in radians + const λ1 = deg2rad(lonBulls); // φ, λ in radians + + const d = Math.sqrt(Math.pow(x - xBulls, 2) + Math.pow(y - yBulls, 2)); + const brng = -rad2deg(Math.atan2(y - yBulls, x - xBulls)); + + const φ2 = Math.asin(Math.sin(φ1)*Math.cos(d/R) + Math.cos(φ1)*Math.sin(d/R)*Math.cos(brng)); + const λ2 = λ1 + Math.atan2(Math.sin(brng)*Math.sin(d/R)*Math.cos(φ1), Math.cos(d/R)-Math.sin(φ1)*Math.sin(φ2)); + + latlng = {}; + latlng.lat = rad2deg(φ2); + latlng.lng = rad2deg(λ2); + + return latlng; +} + +const zeroPad = (num, places) => String(num).padStart(places, '0') + +function ConvertDDToDMS(D, lng) +{ + var dir = D < 0 ? (lng ? "W" : "S") : lng ? "E" : "N"; + var deg = 0 | (D < 0 ? (D = -D) : D); + var min = 0 | (((D += 1e-9) % 1) * 60); + var sec = (0 | (((D * 60) % 1) * 6000)) / 100; + var dec = Math.round((sec - Math.floor(sec)) * 100); + var sec = Math.floor(sec); + if (lng) + return dir + zeroPad(deg, 3) + "°" + zeroPad(min, 2) + "'" + zeroPad(sec, 2) + "." + zeroPad(dec, 2) + "\""; + else + return dir + zeroPad(deg, 2) + "°" + zeroPad(min, 2) + "'" + zeroPad(sec, 2) + "." + zeroPad(dec, 2) + "\""; +} + +function deg2rad(deg) +{ + var pi = Math.PI; + return deg * (pi/180); +} + +function rad2deg(rad) +{ + var pi = Math.PI; + return rad / (pi/180); +} \ No newline at end of file diff --git a/www/js/index.js b/www/js/index.js new file mode 100644 index 00000000..d7b7f247 --- /dev/null +++ b/www/js/index.js @@ -0,0 +1,49 @@ +var missionData; +var unitsHandler; +var leftPanel; +var map; +var RESTaddress = "http://localhost:30000/restdemo"; + +function setup() +{ + resize(); + missionData = new MissionData(); + leftPanel = new LeftPanel(); + unitsHandler = new UnitsHandler(); + map = new Map(); +} + +function resize() +{ + var topPanelHeight = document.getElementById("top-panel").offsetHeight; + document.getElementById("map").style.height = `${window.innerHeight - topPanelHeight - 10}px`; +} + +window.onload = setup; +window.onresize = resize; + +window.console = { + log: function(str){ + if (str !== this.lastMessage) + { + var node = document.createElement("div"); + node.classList.add("log-message"); + node.appendChild(document.createTextNode("> " + str)); + document.getElementById("log").appendChild(node); + this.lastMessage = str + } + }, + + error: function(str){ + if (str !== this.lastMessage) + { + var node = document.createElement("div"); + node.classList.add("error-message"); + node.appendChild(document.createTextNode("> *** " + str + "***")); + document.getElementById("log").appendChild(node); + this.lastMessage = str + } + }, + + lastMessage: "none" + } \ No newline at end of file diff --git a/www/server.bat b/www/server.bat new file mode 100644 index 00000000..19091d6b --- /dev/null +++ b/www/server.bat @@ -0,0 +1 @@ +python -m http.server \ No newline at end of file