From 8e142e14217cadfbb6b2ae7b5fff98e46bc1bd00 Mon Sep 17 00:00:00 2001
From: Leonid Pospelov <pospelovlm@yandex.ru>
Date: Fri, 10 Nov 2023 20:02:53 +0600
Subject: [PATCH 1/2] internal: build gamemode instead of downloading prebuilt

---
 skymp5-functions-lib/CMakeLists.txt           | 25 +++++----
 skymp5-functions-lib/download-and-build.cmake | 56 +++++++++++++++++++
 skymp5-functions-lib/download.cmake           | 13 -----
 .../cpp/server_guest_lib/MpActor.cpp          |  5 +-
 4 files changed, 74 insertions(+), 25 deletions(-)
 create mode 100644 skymp5-functions-lib/download-and-build.cmake
 delete mode 100644 skymp5-functions-lib/download.cmake

diff --git a/skymp5-functions-lib/CMakeLists.txt b/skymp5-functions-lib/CMakeLists.txt
index a7f0f7730f..47624eeffa 100644
--- a/skymp5-functions-lib/CMakeLists.txt
+++ b/skymp5-functions-lib/CMakeLists.txt
@@ -1,28 +1,31 @@
 project(skymp5-functions-lib)
 
-set(GAMEMODE_REPO Pospelove/skymp5-gamemode)
-set(GAMEMODE_REVISION master)
+set(GAMEMODE_REPO_OWNER Pospelove)
+set(GAMEMODE_REPO_NAME skymp5-gamemode)
+set(GAMEMODE_REPO ${GAMEMODE_REPO_OWNER}/${GAMEMODE_REPO_NAME})
+set(GAMEMODE_BRANCH master)
 
 if(BUILD_GAMEMODE)
   if(NOT GITHUB_TOKEN)
     message(FATAL_ERROR "GITHUB_TOKEN is not set. Please set it to your GitHub personal access token.")
   endif()
-  # The URL to the raw gamemode.js file.
-  set(GAMEMODE_JS_URL "https://raw.githubusercontent.com/${GAMEMODE_REPO}/${GAMEMODE_REVISION}/build/gamemode.js")
-
-  # The destination where the file will be saved.
-  set(GAMEMODE_JS_DEST "${CMAKE_BINARY_DIR}/dist/server/gamemode.js")
+  
+  set(GAMEMODE_ZIP_URL "https://github.com/${GAMEMODE_REPO}/archive/refs/heads/${GAMEMODE_BRANCH}.zip")
+  set(GAMEMODE_ZIP_DEST "${CMAKE_BINARY_DIR}/gamemode.zip")
+  set(GAMEMODE_ZIP_EXTRACT_DIR "${CMAKE_BINARY_DIR}/gamemode-zip")
+  set(GAMEMODE_JS_DEST_DIR "${CMAKE_BINARY_DIR}/dist/server")
 
   # Pass variables to the download script.
-  set(SCRIPT_PATH "${CMAKE_CURRENT_LIST_DIR}/download.cmake")
-  configure_file(${SCRIPT_PATH} ${CMAKE_BINARY_DIR}/download.cmake)
+  set(SCRIPT_PATH "${CMAKE_CURRENT_LIST_DIR}/download-and-build.cmake")
+  configure_file(${SCRIPT_PATH} ${CMAKE_BINARY_DIR}/download-and-build.cmake)
 
   add_custom_target(skymp5-functions-lib ALL
     SOURCES ${sources}
     COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_BINARY_DIR}/dist/server
+    COMMAND ${CMAKE_COMMAND} -E remove_directory ${CMAKE_CURRENT_BINARY_DIR}/${GAMEMODE_REPO_NAME}-${GAMEMODE_BRANCH}
     COMMAND ${CMAKE_COMMAND} -E env DOWNLOAD_NO_PROGRESS=1
-            ${CMAKE_COMMAND} -P ${CMAKE_BINARY_DIR}/download.cmake
-    COMMENT "Downloading gamemode.js file..."
+            ${CMAKE_COMMAND} -P ${CMAKE_BINARY_DIR}/download-and-build.cmake
+    COMMENT "Downloading & building gamemode repo..."
   )
 else()
   add_custom_target(skymp5-functions-lib ALL
diff --git a/skymp5-functions-lib/download-and-build.cmake b/skymp5-functions-lib/download-and-build.cmake
new file mode 100644
index 0000000000..d60f813c66
--- /dev/null
+++ b/skymp5-functions-lib/download-and-build.cmake
@@ -0,0 +1,56 @@
+include(${CMAKE_SOURCE_DIR}/cmake/yarn.cmake)
+
+message(STATUS "Downloading gamemode sources")
+
+file(DOWNLOAD ${GAMEMODE_ZIP_URL} ${GAMEMODE_ZIP_DEST}
+     STATUS status
+     LOG log
+     TLS_VERIFY ON
+     HTTPHEADER "Authorization: token ${GITHUB_TOKEN}"
+     )
+list(GET status 0 status_code)
+list(GET status 1 status_string)
+if(NOT status_code EQUAL 0)
+    message(FATAL_ERROR "error: downloading gamemode sources failed: ${status_string}")
+endif()
+
+message(STATUS "Downloaded gamemode sources")
+
+message(STATUS "Extracting gamemode sources")
+
+# Execute the CMake command to extract the zip file
+execute_process(
+    COMMAND ${CMAKE_COMMAND} -E tar xvf ${GAMEMODE_ZIP_DEST}
+    RESULT_VARIABLE TAR_RESULT
+    OUTPUT_QUIET # stop telling gamemode filenames in console
+)
+
+if(NOT TAR_RESULT EQUAL "0")
+    message(FATAL_ERROR "Failed to extract gamemode zip file")
+endif()
+
+message(STATUS "Extracted gamemode sources")
+
+message(STATUS "Installing yarn dependencies for gamemode")
+
+yarn_execute_command(
+    WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/skymp5-functions-lib/${GAMEMODE_REPO_NAME}-${GAMEMODE_BRANCH}
+    COMMAND install
+)
+
+message(STATUS "Installed yarn dependencies for gamemode")
+
+message(STATUS "Building gamemode.js")
+
+yarn_execute_command(
+    WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/skymp5-functions-lib/${GAMEMODE_REPO_NAME}-${GAMEMODE_BRANCH}
+    COMMAND build
+)
+
+message(STATUS "Built gamemode.js")
+
+message(STATUS "Installing gamemode.js")
+
+file(COPY ${CMAKE_BINARY_DIR}/skymp5-functions-lib/${GAMEMODE_REPO_NAME}-${GAMEMODE_BRANCH}/build/gamemode.js DESTINATION "${GAMEMODE_JS_DEST_DIR}")
+
+message(STATUS "Installed gamemode.js")
diff --git a/skymp5-functions-lib/download.cmake b/skymp5-functions-lib/download.cmake
deleted file mode 100644
index 0b5c8c87cd..0000000000
--- a/skymp5-functions-lib/download.cmake
+++ /dev/null
@@ -1,13 +0,0 @@
-message(STATUS "Downloading gamemode.js")
-file(DOWNLOAD ${GAMEMODE_JS_URL} ${GAMEMODE_JS_DEST}
-     STATUS status
-     LOG log
-     TLS_VERIFY ON
-     HTTPHEADER "Authorization: token ${GITHUB_TOKEN}"
-     )
-list(GET status 0 status_code)
-list(GET status 1 status_string)
-if(NOT status_code EQUAL 0)
-    message(FATAL_ERROR "error: downloading gamemode.js failed: ${status_string}")
-endif()
-message(STATUS "Downloaded gamemode.js")
diff --git a/skymp5-server/cpp/server_guest_lib/MpActor.cpp b/skymp5-server/cpp/server_guest_lib/MpActor.cpp
index 271d527eac..f7255a7cc6 100644
--- a/skymp5-server/cpp/server_guest_lib/MpActor.cpp
+++ b/skymp5-server/cpp/server_guest_lib/MpActor.cpp
@@ -796,7 +796,10 @@ LocationalData MpActor::GetSpawnPoint() const
   auto formId = GetFormId();
 
   if (!IsCreatedAsPlayer()) {
-    return GetEditorLocationalData();
+    // FF do not have espm record, so they don't have editor location
+    if (formId < 0xff000000) {
+      return GetEditorLocationalData();
+    }
   }
   return ChangeForm().spawnPoint;
 }

From e446df70c687b2bd97cdd8efa85599b0bcd0432b Mon Sep 17 00:00:00 2001
From: Leonid Pospelov <pospelovlm@yandex.ru>
Date: Fri, 10 Nov 2023 20:04:20 +0600
Subject: [PATCH 2/2] revert unintended change

---
 skymp5-server/cpp/server_guest_lib/MpActor.cpp | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/skymp5-server/cpp/server_guest_lib/MpActor.cpp b/skymp5-server/cpp/server_guest_lib/MpActor.cpp
index f7255a7cc6..271d527eac 100644
--- a/skymp5-server/cpp/server_guest_lib/MpActor.cpp
+++ b/skymp5-server/cpp/server_guest_lib/MpActor.cpp
@@ -796,10 +796,7 @@ LocationalData MpActor::GetSpawnPoint() const
   auto formId = GetFormId();
 
   if (!IsCreatedAsPlayer()) {
-    // FF do not have espm record, so they don't have editor location
-    if (formId < 0xff000000) {
-      return GetEditorLocationalData();
-    }
+    return GetEditorLocationalData();
   }
   return ChangeForm().spawnPoint;
 }