diff options
-rw-r--r-- | scripts/ci/windows/sbinit.config | 8 | ||||
-rw-r--r-- | source/core/CMakeLists.txt | 2 | ||||
-rw-r--r-- | source/core/StarMiniDump.hpp | 11 | ||||
-rw-r--r-- | source/core/StarMiniDump_windows.cpp | 28 | ||||
-rw-r--r-- | source/core/StarSignalHandler_windows.cpp | 39 | ||||
-rw-r--r-- | source/game/StarNetPackets.cpp | 19 | ||||
-rw-r--r-- | source/game/StarNetPackets.hpp | 13 | ||||
-rw-r--r-- | source/game/StarUniverseClient.cpp | 2 | ||||
-rw-r--r-- | source/game/StarWorldClient.cpp | 4 | ||||
-rw-r--r-- | source/game/StarWorldClient.hpp | 1 | ||||
-rw-r--r-- | source/game/StarWorldServer.cpp | 25 | ||||
-rw-r--r-- | source/game/StarWorldServer.hpp | 1 | ||||
-rw-r--r-- | source/game/scripting/StarWorldLuaBindings.cpp | 13 |
13 files changed, 126 insertions, 40 deletions
diff --git a/scripts/ci/windows/sbinit.config b/scripts/ci/windows/sbinit.config index a37768e..413d783 100644 --- a/scripts/ci/windows/sbinit.config +++ b/scripts/ci/windows/sbinit.config @@ -1,9 +1,9 @@ { "assetDirectories" : [ - "..\\assets\\", - "..\\mods\\" + "../assets/", + "../mods/" ], - "storageDirectory" : "..\\storage\\", - "logDirectory" : "..\\logs\\" + "storageDirectory" : "../storage/", + "logDirectory" : "../logs/" }
\ No newline at end of file diff --git a/source/core/CMakeLists.txt b/source/core/CMakeLists.txt index 63f86cf..b510b50 100644 --- a/source/core/CMakeLists.txt +++ b/source/core/CMakeLists.txt @@ -69,6 +69,7 @@ SET (star_core_HEADERS StarMatrix3.hpp StarMaybe.hpp StarMemory.hpp + StarMiniDump.hpp StarMultiArray.hpp StarMultiArrayInterpolator.hpp StarMultiTable.hpp @@ -216,6 +217,7 @@ ELSEIF (STAR_SYSTEM_FAMILY_WINDOWS) StarDynamicLib_windows.cpp StarFile_windows.cpp StarLockFile_windows.cpp + StarMiniDump_windows.cpp StarSignalHandler_windows.cpp StarString_windows.cpp StarThread_windows.cpp diff --git a/source/core/StarMiniDump.hpp b/source/core/StarMiniDump.hpp new file mode 100644 index 0000000..f911f14 --- /dev/null +++ b/source/core/StarMiniDump.hpp @@ -0,0 +1,11 @@ +#pragma once + +#ifdef STAR_SYSTEM_WINDOWS +#include <windows.h> +#endif + +namespace Star { +#ifdef STAR_SYSTEM_WINDOWS + DWORD WINAPI writeMiniDump(void* ExceptionInfo); +#endif +}
\ No newline at end of file diff --git a/source/core/StarMiniDump_windows.cpp b/source/core/StarMiniDump_windows.cpp new file mode 100644 index 0000000..368d67d --- /dev/null +++ b/source/core/StarMiniDump_windows.cpp @@ -0,0 +1,28 @@ +#include "StarMiniDump.hpp" +#include <windows.h> +#include "minidumpapiset.h" + +namespace Star { + DWORD WINAPI writeMiniDump(void* ExceptionInfo) { + auto hFile = CreateFileA("starbound.dmp", GENERIC_WRITE, FILE_SHARE_READ, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); + if (hFile == INVALID_HANDLE_VALUE) + return 0; + MINIDUMP_EXCEPTION_INFORMATION dumpExceptionInfo{}; + dumpExceptionInfo.ThreadId = GetCurrentThreadId(); + dumpExceptionInfo.ExceptionPointers = (PEXCEPTION_POINTERS)ExceptionInfo; + dumpExceptionInfo.ClientPointers = FALSE; + MiniDumpWriteDump( + GetCurrentProcess(), + GetCurrentProcessId(), + hFile, + MiniDumpNormal, + &dumpExceptionInfo, + NULL, + NULL); + CloseHandle(hFile); + if (dumpExceptionInfo.ExceptionPointers->ExceptionRecord->ExceptionCode == EXCEPTION_STACK_OVERFLOW) { + MessageBoxA(NULL, "Stack overflow encountered\nA minidump has been generated", NULL, MB_OK | MB_ICONERROR | MB_SETFOREGROUND); + } + return 0; + }; +}
\ No newline at end of file diff --git a/source/core/StarSignalHandler_windows.cpp b/source/core/StarSignalHandler_windows.cpp index 2fbde88..a3b4478 100644 --- a/source/core/StarSignalHandler_windows.cpp +++ b/source/core/StarSignalHandler_windows.cpp @@ -1,38 +1,15 @@ +#include "StarMiniDump.hpp" #include "StarSignalHandler.hpp" #include "StarFormat.hpp" #include "StarString.hpp" #include "StarLogging.hpp" #include <windows.h> -#include "minidumpapiset.h" namespace Star { String g_sehMessage; -static DWORD WINAPI writeMiniDump(void* ExceptionInfo) { - auto hFile = CreateFileA("starbound.dmp", GENERIC_WRITE, FILE_SHARE_READ, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); - if (hFile == INVALID_HANDLE_VALUE) - return 0; - MINIDUMP_EXCEPTION_INFORMATION dumpExceptionInfo{}; - dumpExceptionInfo.ThreadId = GetCurrentThreadId(); - dumpExceptionInfo.ExceptionPointers = (PEXCEPTION_POINTERS)ExceptionInfo; - dumpExceptionInfo.ClientPointers = FALSE; - MiniDumpWriteDump( - GetCurrentProcess(), - GetCurrentProcessId(), - hFile, - MiniDumpNormal, - &dumpExceptionInfo, - NULL, - NULL); - CloseHandle(hFile); - if (dumpExceptionInfo.ExceptionPointers->ExceptionRecord->ExceptionCode == EXCEPTION_STACK_OVERFLOW) { - MessageBoxA(NULL, "Fatal stack overflow encountered\nA minidump has been generated", NULL, MB_OK | MB_ICONERROR | MB_SETFOREGROUND); - } - return 0; -}; - struct SignalHandlerImpl { bool handlingFatal; bool handlingInterrupt; @@ -122,10 +99,14 @@ struct SignalHandlerImpl { } static LONG CALLBACK vectoredExceptionHandler(PEXCEPTION_POINTERS ExceptionInfo) { - HANDLE thread = NULL; LONG result = EXCEPTION_CONTINUE_SEARCH; if (ExceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_STACK_OVERFLOW) { - thread = CreateThread(NULL, 0, writeMiniDump, (void*)ExceptionInfo, 0, NULL); + if (HANDLE thread = CreateThread(NULL, 0, writeMiniDump, (void*)ExceptionInfo, 0, NULL)) { + WaitForSingleObject(thread, 10000); + CloseHandle(thread); + } + handleFatalError("Stack overflow detected", ExceptionInfo); + result = EXCEPTION_CONTINUE_EXECUTION; } if (ExceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_ACCESS_VIOLATION) { handleFatalError("Access violation detected", ExceptionInfo); @@ -144,7 +125,6 @@ struct SignalHandlerImpl { || (ExceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_FLT_OVERFLOW) || (ExceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_FLT_STACK_CHECK) || (ExceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_FLT_UNDERFLOW) - ) { handleFatalError("Floating point exception", ExceptionInfo); result = EXCEPTION_CONTINUE_EXECUTION; @@ -169,10 +149,7 @@ struct SignalHandlerImpl { handleFatalError("Error occurred", ExceptionInfo); result = EXCEPTION_CONTINUE_EXECUTION; } - if (thread != NULL) { - WaitForSingleObject(thread, 10000); - CloseHandle(thread); - } + return result; } diff --git a/source/game/StarNetPackets.cpp b/source/game/StarNetPackets.cpp index 953743c..cf0beca 100644 --- a/source/game/StarNetPackets.cpp +++ b/source/game/StarNetPackets.cpp @@ -77,7 +77,8 @@ EnumMap<PacketType> const PacketTypeNames{ {PacketType::SystemShipDestroy, "SystemShipDestroy"}, {PacketType::SystemObjectSpawn, "SystemObjectSpawn"}, // OpenStarbound packets - {PacketType::ReplaceTileList, "ReplaceTileList"} + {PacketType::ReplaceTileList, "ReplaceTileList"}, + {PacketType::UpdateWorldTemplate, "UpdateWorldTemplate"} }; EnumMap<NetCompressionMode> const NetCompressionModeNames { @@ -139,7 +140,6 @@ PacketPtr createPacket(PacketType type) { case PacketType::FindUniqueEntityResponse: return make_shared<FindUniqueEntityResponsePacket>(); case PacketType::Pong: return make_shared<PongPacket>(); case PacketType::ModifyTileList: return make_shared<ModifyTileListPacket>(); - case PacketType::ReplaceTileList: return make_shared<ReplaceTileListPacket>(); case PacketType::DamageTileGroup: return make_shared<DamageTileGroupPacket>(); case PacketType::CollectLiquid: return make_shared<CollectLiquidPacket>(); case PacketType::RequestDrop: return make_shared<RequestDropPacket>(); @@ -169,6 +169,9 @@ PacketPtr createPacket(PacketType type) { case PacketType::SystemShipCreate: return make_shared<SystemShipCreatePacket>(); case PacketType::SystemShipDestroy: return make_shared<SystemShipDestroyPacket>(); case PacketType::SystemObjectSpawn: return make_shared<SystemObjectSpawnPacket>(); + // OpenStarbound + case PacketType::ReplaceTileList: return make_shared<ReplaceTileListPacket>(); + case PacketType::UpdateWorldTemplate: return make_shared<UpdateWorldTemplatePacket>(); default: throw StarPacketException(strf("Unrecognized packet type {}", (unsigned int)type)); } @@ -1430,4 +1433,16 @@ void SystemObjectSpawnPacket::write(DataStream& ds) const { ds.write(parameters); } +UpdateWorldTemplatePacket::UpdateWorldTemplatePacket() {} + +UpdateWorldTemplatePacket::UpdateWorldTemplatePacket(Json templateData) : templateData(std::move(templateData)) {} + +void UpdateWorldTemplatePacket::read(DataStream& ds) { + ds.read(templateData); +} + +void UpdateWorldTemplatePacket::write(DataStream& ds) const { + ds.write(templateData); +} + } diff --git a/source/game/StarNetPackets.hpp b/source/game/StarNetPackets.hpp index 63a7ee8..5dbb822 100644 --- a/source/game/StarNetPackets.hpp +++ b/source/game/StarNetPackets.hpp @@ -116,7 +116,8 @@ enum class PacketType : uint8_t { SystemObjectSpawn, // OpenStarbound packets - ReplaceTileList + ReplaceTileList, + UpdateWorldTemplate }; extern EnumMap<PacketType> const PacketTypeNames; @@ -970,4 +971,14 @@ struct SystemObjectSpawnPacket : PacketBase<PacketType::SystemObjectSpawn> { Maybe<Vec2F> position; JsonObject parameters; }; + +struct UpdateWorldTemplatePacket : PacketBase<PacketType::UpdateWorldTemplate> { + UpdateWorldTemplatePacket(); + UpdateWorldTemplatePacket(Json templateData); + + void read(DataStream& ds) override; + void write(DataStream& ds) const override; + + Json templateData; +}; } diff --git a/source/game/StarUniverseClient.cpp b/source/game/StarUniverseClient.cpp index b41d19e..9a1f31b 100644 --- a/source/game/StarUniverseClient.cpp +++ b/source/game/StarUniverseClient.cpp @@ -423,7 +423,7 @@ void UniverseClient::warpPlayer(WarpAction const& warpAction, bool animate, Stri if (auto warpToWorld = warpAction.ptr<WarpToWorld>()) { if (warpToWorld->world.empty() || warpToWorld->world == playerWorld()) { if (auto pos = warpToWorld->target.ptr<SpawnTargetPosition>()) { - m_mainPlayer->moveTo(*pos); // Add a little space to up + m_mainPlayer->moveTo(*pos); return; } } diff --git a/source/game/StarWorldClient.cpp b/source/game/StarWorldClient.cpp index 51fe883..8db6a62 100644 --- a/source/game/StarWorldClient.cpp +++ b/source/game/StarWorldClient.cpp @@ -186,6 +186,10 @@ WorldTemplateConstPtr WorldClient::currentTemplate() const { return m_worldTemplate; } +void WorldClient::setTemplate(Json newTemplate) { + m_outgoingPackets.push_back(make_shared<UpdateWorldTemplatePacket>(newTemplate)); +} + SkyConstPtr WorldClient::currentSky() const { return m_sky; } diff --git a/source/game/StarWorldClient.hpp b/source/game/StarWorldClient.hpp index 5ce3997..6c1f89c 100644 --- a/source/game/StarWorldClient.hpp +++ b/source/game/StarWorldClient.hpp @@ -115,6 +115,7 @@ public: void removeEntity(EntityId entityId, bool andDie); WorldTemplateConstPtr currentTemplate() const; + void setTemplate(Json newTemplate); SkyConstPtr currentSky() const; void dimWorld(); diff --git a/source/game/StarWorldServer.cpp b/source/game/StarWorldServer.cpp index 3bc067a..a9dc1f0 100644 --- a/source/game/StarWorldServer.cpp +++ b/source/game/StarWorldServer.cpp @@ -340,7 +340,7 @@ List<EntityId> WorldServer::players() const { } void WorldServer::handleIncomingPackets(ConnectionId clientId, List<PacketPtr> const& packets) { - auto const& clientInfo = m_clientInfo.get(clientId); + shared_ptr<ClientInfo> clientInfo = m_clientInfo.get(clientId); auto& root = Root::singleton(); auto entityFactory = root.entityFactory(); auto itemDatabase = root.itemDatabase(); @@ -542,6 +542,14 @@ void WorldServer::handleIncomingPackets(ConnectionId clientId, List<PacketPtr> c for (auto const& pair : m_clientInfo) pair.second->outgoingPackets.append(make_shared<UpdateWorldPropertiesPacket>(updateWorldProperties->updatedProperties)); + } else if (auto updateWorldTemplate = as<UpdateWorldTemplatePacket>(packet)) { + if (!clientInfo->admin) + continue; // nuh-uh! + + auto newWorldTemplate = make_shared<WorldTemplate>(updateWorldTemplate->templateData); + setTemplate(newWorldTemplate); + // setTemplate re-adds all clients currently, update clientInfo + clientInfo = m_clientInfo.get(clientId); } else { throw WorldServerException::format("Improper packet type {} received by client", (int)packet->type()); } @@ -2587,4 +2595,19 @@ void WorldServer::setupForceRegions() { } } +void WorldServer::setTemplate(WorldTemplatePtr newTemplate) { + m_worldTemplate = std::move(newTemplate); + for (auto& client : clientIds()) { + auto& info = m_clientInfo.get(client); + bool local = info->local; + bool isAdmin = info->admin; + auto netRules = info->clientState.netCompatibilityRules(); + SpawnTarget spawnTarget; + if (auto player = clientPlayer(client)) + spawnTarget = SpawnTargetPosition(player->position() + player->feetOffset()); + removeClient(client); + addClient(client, spawnTarget, local, isAdmin, netRules); + } +} + } diff --git a/source/game/StarWorldServer.hpp b/source/game/StarWorldServer.hpp index 4a0e87a..3c60b40 100644 --- a/source/game/StarWorldServer.hpp +++ b/source/game/StarWorldServer.hpp @@ -217,6 +217,7 @@ public: EntityId loadUniqueEntity(String const& uniqueId); WorldTemplatePtr worldTemplate() const; + void setTemplate(WorldTemplatePtr newTemplate); SkyPtr sky() const; void modifyLiquid(Vec2I const& pos, LiquidId liquid, float quantity, bool additive = false); void setLiquid(Vec2I const& pos, LiquidId liquid, float level, float pressure); diff --git a/source/game/scripting/StarWorldLuaBindings.cpp b/source/game/scripting/StarWorldLuaBindings.cpp index b2c94a4..2d952ea 100644 --- a/source/game/scripting/StarWorldLuaBindings.cpp +++ b/source/game/scripting/StarWorldLuaBindings.cpp @@ -371,6 +371,12 @@ namespace LuaBindings { return playerIds; }); + callbacks.registerCallback("template", [clientWorld]() { + return clientWorld->currentTemplate()->store(); + }); + callbacks.registerCallback("setTemplate", [clientWorld](Json worldTemplate) { + clientWorld->setTemplate(worldTemplate); + }); } if (auto serverWorld = as<WorldServer>(world)) { @@ -455,6 +461,13 @@ namespace LuaBindings { }); return serverWorld->enqueuePlacement(std::move(distributions), id); }); + callbacks.registerCallback("template", [serverWorld]() { + return serverWorld->worldTemplate()->store(); + }); + callbacks.registerCallback("setTemplate", [serverWorld](Json worldTemplate) { + auto newTemplate = make_shared<WorldTemplate>(worldTemplate); + serverWorld->setTemplate(newTemplate); + }); } return callbacks; |