diff --git a/CMakeLists.txt b/CMakeLists.txt
index b45a38798..dac69a2c8 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -26,13 +26,15 @@ option(SOURCEPP_USE_VCRYPTPP "Build vcryptpp library" ${SOURC
option(SOURCEPP_USE_VPKPP "Build vpkpp library" ${SOURCEPP_LIBS_START_ENABLED})
option(SOURCEPP_USE_VTFPP "Build vtfpp library" ${SOURCEPP_LIBS_START_ENABLED})
-option(SOURCEPP_BUILD_BENCHMARKS "Build benchmarks for supported libraries" OFF)
-option(SOURCEPP_BUILD_C_WRAPPERS "Build C wrappers for supported libraries" OFF)
-option(SOURCEPP_BUILD_WITH_OPENCL "Build with support for GPU compute" OFF)
-option(SOURCEPP_BUILD_WITH_TBB "Build with support for std::execution" OFF)
-option(SOURCEPP_BUILD_WITH_THREADS "Build with support for threading" ON)
-option(SOURCEPP_BUILD_TESTS "Build tests for supported libraries" OFF)
-option(SOURCEPP_BUILD_WIN7_COMPAT "Build with Windows 7 compatibility" OFF)
+option(SOURCEPP_BUILD_BENCHMARKS "Build benchmarks for supported libraries" OFF)
+option(SOURCEPP_BUILD_C_WRAPPERS "Build C wrappers for supported libraries" OFF)
+option(SOURCEPP_BUILD_CSHARP_WRAPPERS "Build C# wrappers for supported libraries" OFF)
+option(SOURCEPP_BUILD_PYTHON_WRAPPERS "Build Python wrappers for supported libraries" OFF)
+option(SOURCEPP_BUILD_WITH_OPENCL "Build with support for GPU compute" OFF)
+option(SOURCEPP_BUILD_WITH_TBB "Build with support for std::execution" OFF)
+option(SOURCEPP_BUILD_WITH_THREADS "Build with support for threading" ON)
+option(SOURCEPP_BUILD_TESTS "Build tests for supported libraries" OFF)
+option(SOURCEPP_BUILD_WIN7_COMPAT "Build with Windows 7 compatibility" OFF)
option(SOURCEPP_LINK_STATIC_MSVC_RUNTIME "Link to static MSVC runtime library" OFF)
@@ -53,6 +55,9 @@ if(SOURCEPP_USE_VPKPP)
set(SOURCEPP_USE_KVPP ON CACHE INTERNAL "" FORCE)
endif()
+if(SOURCEPP_BUILD_CSHARP_WRAPPERS)
+ set(SOURCEPP_BUILD_C_WRAPPERS ON CACHE INTERNAL "" FORCE)
+endif()
if(MSVC)
# MSVC does not rely on tbb for std::execution policies, so we can force this on
set(SOURCEPP_BUILD_WITH_TBB ON CACHE INTERNAL "" FORCE)
@@ -73,6 +78,7 @@ endif()
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
include(AddPrettyParser)
include(AddSourcePPLibrary)
+include(FetchContent)
include(IncludeSubdirectory)
include(PrintOptions)
include(TargetOptimize)
@@ -92,10 +98,24 @@ if(SOURCEPP_BUILD_C_WRAPPERS)
endif()
+# Python bindings, part 1
+if(SOURCEPP_BUILD_PYTHON_WRAPPERS)
+ set(SOURCEPP_PYTHON_NAME "${PROJECT_NAME}_python")
+ find_package(Python REQUIRED COMPONENTS Interpreter Development.Module)
+ FetchContent_Declare(
+ pybind11
+ GIT_REPOSITORY "https://github.com/pybind/pybind11.git"
+ GIT_TAG "v2.13.6")
+ FetchContent_MakeAvailable(pybind11)
+ set(${SOURCEPP_PYTHON_NAME}_SOURCES "")
+ set(${SOURCEPP_PYTHON_NAME}_DEFINES "")
+ list(APPEND ${SOURCEPP_PYTHON_NAME}_DEPS pybind11::headers)
+endif()
+
+
# Tests, part 1
if(SOURCEPP_BUILD_TESTS)
set(SOURCEPP_TEST_NAME "${PROJECT_NAME}_test")
- include(FetchContent)
FetchContent_Declare(
googletest
GIT_REPOSITORY "https://github.com/google/googletest.git"
@@ -138,16 +158,16 @@ endif()
# Add libraries
-add_sourcepp_library(bsppp NO_TEST ) # sourcepp::bsppp
-add_sourcepp_library(dmxpp ) # sourcepp::dmxpp
-add_sourcepp_library(gamepp ) # sourcepp::gamepp
-add_sourcepp_library(kvpp BENCH) # sourcepp::kvpp
-add_sourcepp_library(mdlpp ) # sourcepp::mdlpp
-add_sourcepp_library(steampp C ) # sourcepp::steampp
-add_sourcepp_library(toolpp ) # sourcepp::toolpp
-add_sourcepp_library(vcryptpp C CSHARP ) # sourcepp::vcryptpp
-add_sourcepp_library(vpkpp C CSHARP NO_TEST ) # sourcepp::vpkpp
-add_sourcepp_library(vtfpp BENCH) # sourcepp::vtfpp
+add_sourcepp_library(bsppp NO_TEST ) # sourcepp::bsppp
+add_sourcepp_library(dmxpp ) # sourcepp::dmxpp
+add_sourcepp_library(gamepp PYTHON ) # sourcepp::gamepp
+add_sourcepp_library(kvpp BENCH) # sourcepp::kvpp
+add_sourcepp_library(mdlpp ) # sourcepp::mdlpp
+add_sourcepp_library(steampp C PYTHON ) # sourcepp::steampp
+add_sourcepp_library(toolpp ) # sourcepp::toolpp
+add_sourcepp_library(vcryptpp C CSHARP PYTHON ) # sourcepp::vcryptpp
+add_sourcepp_library(vpkpp C CSHARP NO_TEST ) # sourcepp::vpkpp
+add_sourcepp_library(vtfpp BENCH) # sourcepp::vtfpp
# Tests, part 2
@@ -160,9 +180,18 @@ if(SOURCEPP_BUILD_TESTS)
endif()
+# Python bindings, part 2
+if(SOURCEPP_BUILD_PYTHON_WRAPPERS)
+ python_add_library(${SOURCEPP_PYTHON_NAME} MODULE "${CMAKE_CURRENT_SOURCE_DIR}/lang/python/src/sourcepp.cpp" ${${SOURCEPP_PYTHON_NAME}_SOURCES} WITH_SOABI)
+ set_target_properties(${SOURCEPP_PYTHON_NAME} PROPERTIES PREFIX "_" LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/lang/python/dist/sourcepp")
+ target_compile_definitions(${SOURCEPP_PYTHON_NAME} PRIVATE ${${SOURCEPP_PYTHON_NAME}_DEFINES})
+ target_link_libraries(${SOURCEPP_PYTHON_NAME} PRIVATE ${${SOURCEPP_PYTHON_NAME}_DEPS})
+endif()
+
+
# Print options
print_options(OPTIONS
USE_BSPPP USE_DMXPP USE_GAMEPP USE_KVPP USE_MDLPP USE_STEAMPP USE_TOOLPP USE_VCRYPTPP USE_VPKPP USE_VTFPP
- BUILD_BENCHMARKS BUILD_C_WRAPPERS BUILD_WITH_OPENCL BUILD_WITH_TBB BUILD_WITH_THREADS BUILD_TESTS BUILD_WIN7_COMPAT
+ BUILD_BENCHMARKS BUILD_C_WRAPPERS BUILD_PYTHON_WRAPPERS BUILD_WITH_OPENCL BUILD_WITH_TBB BUILD_WITH_THREADS BUILD_TESTS BUILD_WIN7_COMPAT
LINK_STATIC_MSVC_RUNTIME
VPKPP_SUPPORT_VPK_V54)
diff --git a/README.md b/README.md
index de78d5c50..40722cef3 100644
--- a/README.md
+++ b/README.md
@@ -42,7 +42,7 @@ Several modern C++20 libraries for sanely parsing Valve formats, rolled into one
Get Source engine instance window title/position/size |
✅ |
❌ |
- |
+ Python |
@@ -84,7 +84,7 @@ Several modern C++20 libraries for sanely parsing Valve formats, rolled into one
| Find Steam install folder |
✅ |
- |
- C |
+ C Python |
@@ -119,7 +119,7 @@ Several modern C++20 libraries for sanely parsing Valve formats, rolled into one
| VICE encrypted files |
✅ |
✅ |
- C C# |
+ C C# Python |
diff --git a/cmake/AddSourcePPLibrary.cmake b/cmake/AddSourcePPLibrary.cmake
index 18a760ed6..581dfd071 100644
--- a/cmake/AddSourcePPLibrary.cmake
+++ b/cmake/AddSourcePPLibrary.cmake
@@ -1,7 +1,9 @@
function(add_sourcepp_library TARGET)
- cmake_parse_arguments(PARSE_ARGV 1 OPTIONS "C;CSHARP;NO_TEST;BENCH" "" "")
+ cmake_parse_arguments(PARSE_ARGV 1 OPTIONS "C;CSHARP;PYTHON;NO_TEST;BENCH" "" "")
string(TOUPPER ${TARGET} TARGET_UPPER)
if(SOURCEPP_USE_${TARGET_UPPER})
+ set(PROPAGATE_VARS "")
+
# Add C++
include("${CMAKE_CURRENT_SOURCE_DIR}/src/${TARGET}/_${TARGET}.cmake")
@@ -11,23 +13,31 @@ function(add_sourcepp_library TARGET)
endif()
# Add C#
- if(OPTIONS_CSHARP)
+ if(SOURCEPP_BUILD_CSHARP_WRAPPERS AND OPTIONS_CSHARP)
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/lang/csharp/src/sourcepp/Buffer.cs.in" "${CMAKE_CURRENT_SOURCE_DIR}/lang/csharp/src/${TARGET}/Buffer.cs")
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/lang/csharp/src/sourcepp/String.cs.in" "${CMAKE_CURRENT_SOURCE_DIR}/lang/csharp/src/${TARGET}/String.cs")
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/lang/csharp/src/sourcepp/TARGET.csproj.in" "${CMAKE_CURRENT_SOURCE_DIR}/lang/csharp/src/${TARGET}/${TARGET}.csproj")
+ add_custom_target(${TARGET}_csharp DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/lang/csharp/src/${TARGET}/${TARGET}.csproj")
+ add_dependencies(${TARGET}_csharp ${TARGET}c)
endif()
- set(PROPAGATE_VARS "")
+ # Add Python
+ if(SOURCEPP_BUILD_PYTHON_WRAPPERS AND OPTIONS_PYTHON)
+ list(APPEND ${SOURCEPP_PYTHON_NAME}_DEPS sourcepp::${TARGET})
+ list(APPEND ${SOURCEPP_PYTHON_NAME}_DEFINES ${TARGET_UPPER})
+ list(APPEND ${SOURCEPP_PYTHON_NAME}_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/lang/python/src/${TARGET}.h")
+ list(APPEND PROPAGATE_VARS ${SOURCEPP_PYTHON_NAME}_DEPS ${SOURCEPP_PYTHON_NAME}_DEFINES ${SOURCEPP_PYTHON_NAME}_SOURCES)
+ endif()
# Add tests
- if(NOT OPTIONS_NO_TEST AND SOURCEPP_BUILD_TESTS)
+ if(SOURCEPP_BUILD_TESTS AND NOT OPTIONS_NO_TEST)
list(APPEND ${SOURCEPP_TEST_NAME}_DEPS sourcepp::${TARGET})
list(APPEND ${SOURCEPP_TEST_NAME}_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/test/${TARGET}.cpp")
list(APPEND PROPAGATE_VARS ${SOURCEPP_TEST_NAME}_DEPS ${SOURCEPP_TEST_NAME}_SOURCES)
endif()
# Add benchmarks
- if(OPTIONS_BENCH AND SOURCEPP_BUILD_BENCHMARKS)
+ if(SOURCEPP_BUILD_BENCHMARKS AND OPTIONS_BENCH)
add_executable(${TARGET}_bench "${CMAKE_CURRENT_SOURCE_DIR}/bench/${TARGET}.cpp")
target_link_libraries(${TARGET}_bench PUBLIC ${SOURCEPP_BENCH_NAME} sourcepp::${TARGET})
include("${CMAKE_CURRENT_SOURCE_DIR}/bench/${TARGET}.cmake")
diff --git a/docs/index.md b/docs/index.md
index 8d4ff20e3..ef612a425 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -40,7 +40,7 @@ Several modern C++20 libraries for sanely parsing Valve formats, rolled into one
| Get Source engine instance window title/position/size |
✅ |
❌ |
- |
+ Python |
| Run commands in a Source engine instance remotely |
@@ -76,7 +76,7 @@ Several modern C++20 libraries for sanely parsing Valve formats, rolled into one
Find Steam install folder |
✅ |
- |
- C |
+ C Python |
| Find installed Steam games |
@@ -107,7 +107,7 @@ Several modern C++20 libraries for sanely parsing Valve formats, rolled into one
VICE encrypted files |
✅ |
✅ |
- C C# |
+ C C# Python |
| VFONT encrypted fonts |
diff --git a/ext/bufferstream b/ext/bufferstream
index 689c50d56..72da37514 160000
--- a/ext/bufferstream
+++ b/ext/bufferstream
@@ -1 +1 @@
-Subproject commit 689c50d56a0eefb066209c281eac99599845edb6
+Subproject commit 72da375145d8d0cef590d9fe82e68c27f1d37481
diff --git a/ext/miniz b/ext/miniz
index 1ff82be7d..35528ad76 160000
--- a/ext/miniz
+++ b/ext/miniz
@@ -1 +1 @@
-Subproject commit 1ff82be7d67f5c2f8b5497f538eea247861e0717
+Subproject commit 35528ad769143b9ed38a95a22d460b963e39f278
diff --git a/include/sourcepp/math/Integer.h b/include/sourcepp/math/Integer.h
index d245fc014..7de6f416e 100644
--- a/include/sourcepp/math/Integer.h
+++ b/include/sourcepp/math/Integer.h
@@ -15,122 +15,10 @@ using std::uint16_t;
using std::uint32_t;
using std::uint64_t;
-/// 3-byte wide unsigned integer
-struct uint24_t {
- uint24_t() = default;
-
- template
- constexpr uint24_t(T value) // NOLINT(*-explicit-constructor)
- : bytes{
- static_cast((value >> 16) & 0xff),
- static_cast((value >> 8) & 0xff),
- static_cast( value & 0xff),
- } {}
-
- template
- [[nodiscard]] constexpr operator T() const { // NOLINT(*-explicit-constructor)
- return static_cast((bytes[0] << 16) | (bytes[1] << 8) | bytes[2]);
- }
-
- template
- constexpr uint24_t& operator=(T value) {
- *this = {value};
- return *this;
- }
-
- template
- [[nodiscard]] constexpr uint24_t operator+(T value) const {
- return {uint32_t{*this} + value};
- }
-
- template
- constexpr void operator+=(T value) const {
- *this = {uint32_t{*this} + value};
- }
-
- constexpr uint24_t operator++() {
- return *this = {uint32_t{*this} + 1};
- }
-
- constexpr uint24_t operator++(int) {
- uint24_t out{*this};
- *this = {uint32_t{*this} + 1};
- return out;
- }
-
- template
- [[nodiscard]] constexpr uint24_t operator-(T value) const {
- return {uint32_t{*this} - value};
- }
-
- template
- constexpr void operator-=(T value) const {
- return *this = {uint32_t{*this} - value};
- }
-
- constexpr uint24_t operator--() {
- return *this = {uint32_t{*this} - 1};
- }
-
- constexpr uint24_t operator--(int) {
- uint24_t out{*this};
- *this = {uint32_t{*this} - 1};
- return out;
- }
-
- template
- [[nodiscard]] constexpr uint24_t operator*(T value) const {
- return {uint32_t{*this} * value};
- }
-
- template
- constexpr void operator*=(T value) const {
- *this = {uint32_t{*this} * value};
- }
-
- template
- [[nodiscard]] constexpr uint24_t operator/(T value) const {
- return {uint32_t{*this} / value};
- }
-
- template
- constexpr void operator/=(T value) const {
- *this = {uint32_t{*this} / value};
- }
-
- template
- [[nodiscard]] constexpr uint24_t operator%(T value) const {
- return {uint32_t{*this} % value};
- }
-
- template
- constexpr void operator%=(T value) const {
- *this = {uint32_t{*this} % value};
- }
-
- template
- [[nodiscard]] constexpr bool operator==(T value) const {
- return uint32_t{*this} == value;
- }
-
- template
- [[nodiscard]] constexpr auto operator<=>(T value) const {
- return uint32_t{*this} <=> value;
- }
-
- [[nodiscard]] constexpr operator bool() const { // NOLINT(*-explicit-constructor)
- return static_cast(uint32_t{*this});
- }
-
- uint8_t bytes[3];
-};
-static_assert(sizeof(uint24_t) == 3, "uint24_t is not 3 bytes wide!");
-static_assert(std::is_trivially_copyable_v, "uint24_t is not a POD type!");
-
namespace sourcepp::math {
template
-concept Arithmetic = std::is_arithmetic_v || std::same_as;
+concept Arithmetic = std::is_arithmetic_v;
template
[[nodiscard]] constexpr T remap(T value, T l1, T h1, T l2, T h2) {
diff --git a/include/sourcepp/math/Vector.h b/include/sourcepp/math/Vector.h
index b50ad76fd..d4395b81f 100644
--- a/include/sourcepp/math/Vector.h
+++ b/include/sourcepp/math/Vector.h
@@ -28,7 +28,7 @@ struct Vec {
using value_type = P;
- [[nodiscard]] consteval uint8_t size() const {
+ [[nodiscard]] constexpr uint8_t size() const {
return S;
}
@@ -252,7 +252,6 @@ using Vec2i = Vec2i32;
using Vec2ui8 = Vec2;
using Vec2ui16 = Vec2;
-using Vec2ui24 = Vec2;
using Vec2ui32 = Vec2;
using Vec2ui64 = Vec2;
using Vec2ui = Vec2ui32;
@@ -272,7 +271,6 @@ using Vec3i = Vec3i32;
using Vec3ui8 = Vec3;
using Vec3ui16 = Vec3;
-using Vec3ui24 = Vec3;
using Vec3ui32 = Vec3;
using Vec3ui64 = Vec3;
using Vec3ui = Vec3ui32;
@@ -292,7 +290,6 @@ using Vec4i = Vec4i32;
using Vec4ui8 = Vec4;
using Vec4ui16 = Vec4;
-using Vec4ui24 = Vec4;
using Vec4ui32 = Vec4;
using Vec4ui64 = Vec4;
using Vec4ui = Vec4ui32;
diff --git a/lang/python/.gitignore b/lang/python/.gitignore
new file mode 100644
index 000000000..0c986d628
--- /dev/null
+++ b/lang/python/.gitignore
@@ -0,0 +1,4 @@
+# Build Files
+__pycache__/
+dist/sourcepp/*
+!dist/sourcepp/__init__.py
diff --git a/lang/python/dist/sourcepp/__init__.py b/lang/python/dist/sourcepp/__init__.py
new file mode 100644
index 000000000..d8f3097c9
--- /dev/null
+++ b/lang/python/dist/sourcepp/__init__.py
@@ -0,0 +1,5 @@
+from __future__ import annotations
+
+from ._sourcepp_python import __author__, __doc__, __version__, gamepp, sourcepp, steampp, vcryptpp
+
+__all__ = ['__author__', '__doc__', '__version__', 'gamepp', 'sourcepp', 'steampp', 'vcryptpp']
diff --git a/lang/python/src/gamepp.h b/lang/python/src/gamepp.h
new file mode 100644
index 000000000..239e0804c
--- /dev/null
+++ b/lang/python/src/gamepp.h
@@ -0,0 +1,29 @@
+#pragma once
+
+#include
+#include
+
+namespace py = pybind11;
+
+#include
+
+namespace gamepp {
+
+void register_python(py::module_& m) {
+ using namespace gamepp;
+ auto gamepp = m.def_submodule("gamepp");
+
+ py::class_(gamepp, "GameInstance")
+ .def_static("find", &GameInstance::find, py::arg("window_name_override") = "")
+ .def_property_readonly("window_title", &GameInstance::getWindowTitle)
+ .def_property_readonly("window_pos", &GameInstance::getWindowPos)
+ .def_property_readonly("window_size", &GameInstance::getWindowSize)
+ .def("command", &GameInstance::command)
+ .def("input_begin", &GameInstance::inputBegin)
+ .def("input_end", &GameInstance::inputEnd)
+ .def("input_once", &GameInstance::inputOnce)
+ .def("input_hold", &GameInstance::inputHold)
+ .def("wait", &GameInstance::wait);
+}
+
+} // namespace gamepp
diff --git a/lang/python/src/sourcepp.cpp b/lang/python/src/sourcepp.cpp
new file mode 100644
index 000000000..353151646
--- /dev/null
+++ b/lang/python/src/sourcepp.cpp
@@ -0,0 +1,40 @@
+#include "sourcepp.h"
+
+#ifdef GAMEPP
+#include "gamepp.h"
+#endif
+
+#ifdef STEAMPP
+#include "steampp.h"
+#endif
+
+#ifdef VCRYPTPP
+#include "vcryptpp.h"
+#endif
+
+PYBIND11_MODULE(_sourcepp_python, m) {
+ m.doc() = "SourcePP: A Python wrapper around several modern C++20 libraries for sanely parsing Valve's formats.";
+
+ m.attr("__author__") = "craftablescience";
+ m.attr("__version__") = "dev";
+
+ sourcepp::register_python(m);
+
+#ifdef GAMEPP
+ gamepp::register_python(m);
+#else
+ m.def_submodule("gamepp");
+#endif
+
+#ifdef STEAMPP
+ steampp::register_python(m);
+#else
+ m.def_submodule("steampp");
+#endif
+
+#ifdef VCRYPTPP
+ vcryptpp::register_python(m);
+#else
+ m.def_submodule("vcryptpp");
+#endif
+}
diff --git a/lang/python/src/sourcepp.h b/lang/python/src/sourcepp.h
new file mode 100644
index 000000000..eeec1b764
--- /dev/null
+++ b/lang/python/src/sourcepp.h
@@ -0,0 +1,85 @@
+#pragma once
+
+#include
+
+#include
+#include
+#include
+
+namespace py = pybind11;
+
+#include
+
+namespace sourcepp {
+
+void register_python(py::module_& m) {
+ using namespace sourcepp;
+ auto sourcepp = m.def_submodule("sourcepp");
+
+ {
+ auto math = sourcepp.def_submodule("math");
+ using namespace math;
+
+ const auto registerVecType = [&math](std::string_view name) {
+ py::class_(math, name.data(), pybind11::buffer_protocol())
+ .def_buffer([](V& v) -> py::buffer_info {
+ return {v.values.data(), static_cast(v.values.size())};
+ })
+ .def("__len__", &V::size)
+ .def("__setitem__", [](V& self, uint8_t index, V::value_type val) { self[index] = val; })
+ .def("__getitem__", [](V& self, uint8_t index) { return self[index]; })
+ .def_static("zero", &V::zero)
+ .def("is_zero", &V::isZero);
+ };
+
+ registerVecType.operator()("Vec2i8");
+ registerVecType.operator()("Vec2i16");
+ registerVecType.operator()("Vec2i32");
+ registerVecType.operator()("Vec2i64");
+ //registerVecType.operator()("Vec2i");
+
+ registerVecType.operator()("Vec2ui8");
+ registerVecType.operator()("Vec2ui16");
+ registerVecType.operator()("Vec2ui32");
+ registerVecType.operator()("Vec2ui64");
+ //registerVecType.operator()("Vec2ui");
+
+ registerVecType.operator()("Vec2f32");
+ registerVecType.operator()("Vec2f64");
+ //registerVecType.operator()("Vec2f");
+
+ registerVecType.operator()("Vec3i8");
+ registerVecType.operator()("Vec3i16");
+ registerVecType.operator()("Vec3i32");
+ registerVecType.operator()("Vec3i64");
+ //registerVecType.operator()("Vec3i");
+
+ registerVecType.operator()("Vec3ui8");
+ registerVecType.operator()("Vec3ui16");
+ registerVecType.operator()("Vec3ui32");
+ registerVecType.operator()("Vec3ui64");
+ //registerVecType.operator()("Vec3ui");
+
+ registerVecType.operator()("Vec3f32");
+ registerVecType.operator()("Vec3f64");
+ //registerVecType.operator()("Vec3f");
+
+ registerVecType.operator()("Vec4i8");
+ registerVecType.operator()("Vec4i16");
+ registerVecType.operator()("Vec4i32");
+ registerVecType.operator()("Vec4i64");
+ //registerVecType.operator()("Vec4i");
+
+ registerVecType.operator()("Vec4ui8");
+ registerVecType.operator()("Vec4ui16");
+ registerVecType.operator()("Vec4ui32");
+ registerVecType.operator()("Vec4ui64");
+ //registerVecType.operator()("Vec4ui");
+
+ registerVecType.operator()("Vec4f32");
+ registerVecType.operator()("Vec4f64");
+ //registerVecType.operator()("Vec4f");
+ }
+}
+
+} // namespace sourcepp
diff --git a/lang/python/src/steampp.h b/lang/python/src/steampp.h
new file mode 100644
index 000000000..24e1f8043
--- /dev/null
+++ b/lang/python/src/steampp.h
@@ -0,0 +1,34 @@
+#pragma once
+
+#include
+#include
+
+namespace py = pybind11;
+
+#include
+
+namespace steampp {
+
+void register_python(py::module_& m) {
+ using namespace steampp;
+ auto steampp = m.def_submodule("steampp");
+
+ py::class_(steampp, "Steam")
+ .def(py::init<>())
+ .def_property_readonly("install_dir", &Steam::getInstallDir)
+ .def_property_readonly("library_dirs", &Steam::getLibraryDirs)
+ .def_property_readonly("sourcemod_dir", &Steam::getSourceModDir)
+ .def_property_readonly("installed_apps", &Steam::getInstalledApps)
+ .def("is_app_installed", &Steam::isAppInstalled)
+ .def("get_app_name", &Steam::getAppName)
+ .def("get_app_install_dir", &Steam::getAppInstallDir)
+ .def("get_app_icon_path", &Steam::getAppIconPath)
+ .def("get_app_logo_path", &Steam::getAppLogoPath)
+ .def("get_app_box_art_path", &Steam::getAppBoxArtPath)
+ .def("get_app_store_art_path", &Steam::getAppStoreArtPath)
+ .def("is_app_using_source_engine", &Steam::isAppUsingSourceEngine)
+ .def("is_app_using_source_2_engine", &Steam::isAppUsingSource2Engine)
+ .def_property_readonly("valid", &Steam::operator bool);
+}
+
+} // namespace steampp
diff --git a/lang/python/src/vcryptpp.h b/lang/python/src/vcryptpp.h
new file mode 100644
index 000000000..fc5fa33b7
--- /dev/null
+++ b/lang/python/src/vcryptpp.h
@@ -0,0 +1,93 @@
+#pragma once
+
+#include
+#include
+
+namespace py = pybind11;
+
+#include
+
+namespace vcryptpp {
+
+void register_python(py::module_& m) {
+ using namespace vcryptpp;
+ auto vcryptpp = m.def_submodule("vcryptpp");
+
+ {
+ auto VFONT = vcryptpp.def_submodule("VFONT");
+ using namespace VFONT;
+
+ VFONT.attr("IDENTIFIER") = IDENTIFIER;
+
+ VFONT.attr("MAGIC") = MAGIC;
+
+ VFONT.def("decrypt_bytes", [](const py::bytes& data) -> py::bytes {
+ const std::string_view dataView{data};
+ const auto d = decrypt({reinterpret_cast(dataView.data()), dataView.size()});
+ return {reinterpret_cast(d.data()), d.size()};
+ }, py::arg("data"));
+ }
+
+ {
+ auto VICE = vcryptpp.def_submodule("VICE");
+ using namespace VICE;
+
+ {
+ auto KnownCodes = VICE.def_submodule("KnownCodes");
+ using namespace KnownCodes;
+
+ KnownCodes.attr("DEFAULT") = DEFAULT;
+ KnownCodes.attr("CONTAGION_WEAPONS") = CONTAGION_WEAPONS;
+ KnownCodes.attr("CONTAGION_SCRIPTS") = CONTAGION_SCRIPTS;
+ KnownCodes.attr("COUNTER_STRIKE_SOURCE") = COUNTER_STRIKE_SOURCE;
+ KnownCodes.attr("COUNTER_STRIKE_GLOBAL_OFFENSIVE") = COUNTER_STRIKE_GLOBAL_OFFENSIVE;
+ KnownCodes.attr("COUNTER_STRIKE_2") = COUNTER_STRIKE_2;
+ KnownCodes.attr("COUNTER_STRIKE_PROMOD") = COUNTER_STRIKE_PROMOD;
+ KnownCodes.attr("DAY_OF_DEFEAT_SOURCE") = DAY_OF_DEFEAT_SOURCE;
+ KnownCodes.attr("DYSTOPIA_1_2") = DYSTOPIA_1_2;
+ KnownCodes.attr("DYSTOPIA_1_3") = DYSTOPIA_1_3;
+ KnownCodes.attr("GOLDEN_EYE_SOURCE") = GOLDEN_EYE_SOURCE;
+ KnownCodes.attr("HALF_LIFE_2_CTF") = HALF_LIFE_2_CTF;
+ KnownCodes.attr("HALF_LIFE_2_DM") = HALF_LIFE_2_DM;
+ KnownCodes.attr("INSURGENCY") = INSURGENCY;
+ KnownCodes.attr("LEFT_4_DEAD_2") = LEFT_4_DEAD_2;
+ KnownCodes.attr("NO_MORE_ROOM_IN_HELL") = NO_MORE_ROOM_IN_HELL;
+ KnownCodes.attr("NUCLEAR_DAWN") = NUCLEAR_DAWN;
+ KnownCodes.attr("TACTICAL_INTERVENTION") = TACTICAL_INTERVENTION;
+ KnownCodes.attr("TEAM_FORTRESS_2") = TEAM_FORTRESS_2;
+ KnownCodes.attr("TEAM_FORTRESS_2_ITEMS") = TEAM_FORTRESS_2_ITEMS;
+ KnownCodes.attr("THE_SHIP") = THE_SHIP;
+ KnownCodes.attr("ZOMBIE_PANIC_SOURCE") = ZOMBIE_PANIC_SOURCE;
+
+ KnownCodes.attr("EKV_GPU_DEFAULT") = EKV_GPU_DEFAULT;
+ KnownCodes.attr("EKV_GPU_ALIEN_SWARM") = EKV_GPU_ALIEN_SWARM;
+ KnownCodes.attr("EKV_GPU_LEFT_4_DEAD_1") = EKV_GPU_LEFT_4_DEAD_1;
+ KnownCodes.attr("EKV_GPU_LEFT_4_DEAD_2") = EKV_GPU_LEFT_4_DEAD_2;
+ KnownCodes.attr("EKV_GPU_PORTAL_2") = EKV_GPU_PORTAL_2;
+ }
+
+ VICE.def("decrypt_bytes", [](const py::bytes& data, std::string_view code = KnownCodes::DEFAULT) -> py::bytes {
+ const std::string_view dataView{data};
+ const auto d = decrypt({reinterpret_cast(dataView.data()), dataView.size()}, code);
+ return {reinterpret_cast(d.data()), d.size()};
+ }, py::arg("data"), py::arg("code") = KnownCodes::DEFAULT);
+
+ VICE.def("decrypt_str", [](std::string_view data, std::string_view code = KnownCodes::DEFAULT) -> std::string {
+ const auto d = decrypt({reinterpret_cast(data.data()), data.size()}, code);
+ return {reinterpret_cast(d.data()), d.size()};
+ }, py::arg("data"), py::arg("code") = KnownCodes::DEFAULT);
+
+ VICE.def("encrypt_bytes", [](const py::bytes& data, std::string_view code = KnownCodes::DEFAULT) -> py::bytes {
+ const std::string_view dataView{data};
+ const auto e = encrypt({reinterpret_cast(dataView.data()), dataView.size()}, code);
+ return {reinterpret_cast(e.data()), e.size()};
+ }, py::arg("data"), py::arg("code") = KnownCodes::DEFAULT);
+
+ VICE.def("encrypt_str", [](std::string_view data, std::string_view code = KnownCodes::DEFAULT) -> std::string {
+ const auto e = decrypt({reinterpret_cast(data.data()), data.size()}, code);
+ return {reinterpret_cast(e.data()), e.size()};
+ }, py::arg("data"), py::arg("code") = KnownCodes::DEFAULT);
+ }
+}
+
+} // namespace vcryptpp
diff --git a/src/gamepp/gamepp.cpp b/src/gamepp/gamepp.cpp
index b44892da9..d07b4aef5 100644
--- a/src/gamepp/gamepp.cpp
+++ b/src/gamepp/gamepp.cpp
@@ -13,7 +13,7 @@ using namespace sourcepp;
#include
std::optional GameInstance::find(std::string_view windowNameOverride) {
- GameInstance instance;
+ GameInstance instance{};
if (!windowNameOverride.empty()) {
instance.hwnd = FindWindowA(windowNameOverride.data(), nullptr);
@@ -34,7 +34,7 @@ std::optional GameInstance::find(std::string_view windowNameOverri
std::string GameInstance::getWindowTitle() const {
// This should be large enough
std::string title(512, '\0');
- if (auto size = GetWindowTextA(reinterpret_cast(this->hwnd), title.data(), title.length())) {
+ if (auto size = GetWindowTextA(reinterpret_cast(this->hwnd), title.data(), static_cast(title.length()))) {
title.resize(size);
return title;
}
diff --git a/src/toolpp/FGD.cpp b/src/toolpp/FGD.cpp
index f9f955ca8..102692bfc 100644
--- a/src/toolpp/FGD.cpp
+++ b/src/toolpp/FGD.cpp
@@ -11,6 +11,7 @@
#include
using namespace sourcepp;
+using namespace std::string_view_literals;
using namespace toolpp;
namespace {
@@ -467,11 +468,11 @@ void writeOptionalKeyValueStrings(BufferStream& writer, std::initializer_listwriter
- .write("@include \"", 10)
+ .write("@include \""sv, false)
.write(fgdPath, false)
- .write("\"\n\n", 3);
+ .write("\"\n\n"sv, false);
return *this;
}
FGDWriter& FGDWriter::version(int version) {
this->writer
- .write("@version(", 9)
+ .write("@version("sv, false)
.write(std::to_string(version), false)
- .write(")\n\n", 3);
+ .write(")\n\n"sv, false);
return *this;
}
FGDWriter& FGDWriter::mapSize(math::Vec2i mapSize) {
this->writer
- .write("@mapsize(", 9)
+ .write("@mapsize("sv, false)
.write(std::to_string(mapSize[0]), false)
- .write(", ", 2)
+ .write(", "sv, false)
.write(std::to_string(mapSize[1]), false)
- .write(")\n\n", 3);
+ .write(")\n\n"sv, false);
return *this;
}
FGDWriter& FGDWriter::materialExclusionDirs(const std::vector& dirs) {
- this->writer.write("@MaterialExclusion\n[\n", 21);
+ this->writer.write("@MaterialExclusion\n[\n"sv, false);
for (const auto& dir : dirs) {
this->writer << '\t' << '\"';
this->writer.write(dir, false);
this->writer << '\"' << '\n';
}
- this->writer.write("]\n\n", 3);
+ this->writer.write("]\n\n"sv, false);
return *this;
}
FGDWriter::AutoVisGroupWriter FGDWriter::beginAutoVisGroup(const std::string& parentName) {
this->writer
- .write("@AutoVisGroup = \"", 17)
+ .write("@AutoVisGroup = \""sv, false)
.write(parentName, false)
- .write("\"\n[\n", 4);
+ .write("\"\n[\n"sv, false);
return AutoVisGroupWriter{*this};
}
FGDWriter::AutoVisGroupWriter& FGDWriter::AutoVisGroupWriter::visGroup(const std::string& name, const std::vector& entities) {
this->parent.writer
- .write("\t\"", 2)
+ .write("\t\""sv, false)
.write(name, false)
- .write("\"\n\t[\n", 5);
+ .write("\"\n\t[\n"sv, false);
for (const auto& entity : entities) {
this->parent.writer
- .write("\t\t\"", 3)
+ .write("\t\t\""sv, false)
.write(entity, false)
- .write("\"\n", 2);
+ .write("\"\n"sv, false);
}
- this->parent.writer.write("\t]\n", 3);
+ this->parent.writer.write("\t]\n"sv, false);
return *this;
}
FGDWriter& FGDWriter::AutoVisGroupWriter::endAutoVisGroup() const {
- this->parent.writer.write("]\n\n", 3);
+ this->parent.writer.write("]\n\n"sv, false);
return this->parent;
}
@@ -684,20 +685,20 @@ FGDWriter::EntityWriter FGDWriter::beginEntity(const std::string& classType, con
}
}
this->writer
- .write("= ", 2)
+ .write("= "sv, false)
.write(name, false)
- .write(" :", 2);
+ .write(" :"sv, false);
// Put the description on the same line if it's short
if (description.size() < 32) {
this->writer
- .write(" \"", 2)
+ .write(" \""sv, false)
.write(description, false);
} else {
this->writer
- .write("\n\t\"", 3)
+ .write("\n\t\""sv, false)
.write(description, false);
}
- this->writer.write("\"\n[\n", 4);
+ this->writer.write("\"\n[\n"sv, false);
return EntityWriter{*this};
}
@@ -709,10 +710,10 @@ FGDWriter::EntityWriter& FGDWriter::EntityWriter::keyValue(const std::string& na
.write(valueType, false)
.write(')');
if (readOnly) {
- this->parent.writer.write(" readonly", 9);
+ this->parent.writer.write(" readonly"sv, false);
}
if (report) {
- this->parent.writer.write(" report", 7);
+ this->parent.writer.write(" report"sv, false);
}
::writeOptionalKeyValueStrings(this->parent.writer, {displayName, valueDefault, description});
this->parent.writer << '\n';
@@ -723,30 +724,30 @@ FGDWriter::EntityWriter::KeyValueChoicesWriter FGDWriter::EntityWriter::beginKey
this->parent.writer
.write('\t')
.write(name, false)
- .write("(choices)", 9);
+ .write("(choices)"sv, false);
if (readOnly) {
- this->parent.writer.write(" readonly", 9);
+ this->parent.writer.write(" readonly"sv, false);
}
if (report) {
- this->parent.writer.write(" report", 7);
+ this->parent.writer.write(" report"sv, false);
}
::writeOptionalKeyValueStrings(this->parent.writer, {displayName, valueDefault, description});
- this->parent.writer.write(" =\n\t[\n", 6);
+ this->parent.writer.write(" =\n\t[\n"sv, false);
return KeyValueChoicesWriter{*this};
}
FGDWriter::EntityWriter::KeyValueChoicesWriter& FGDWriter::EntityWriter::KeyValueChoicesWriter::choice(const std::string& value, const std::string& displayName) {
this->parent.parent.writer
- .write("\t\t\"", 3)
+ .write("\t\t\""sv, false)
.write(value, false)
- .write("\" : \"", 5)
+ .write("\" : \""sv, false)
.write(displayName, false)
- .write("\"\n", 2);
+ .write("\"\n"sv, false);
return *this;
}
FGDWriter::EntityWriter& FGDWriter::EntityWriter::KeyValueChoicesWriter::endKeyValueChoices() const {
- this->parent.parent.writer.write("\t]\n", 3);
+ this->parent.parent.writer.write("\t]\n"sv, false);
return this->parent;
}
@@ -754,29 +755,29 @@ FGDWriter::EntityWriter::KeyValueFlagsWriter FGDWriter::EntityWriter::beginKeyVa
this->parent.writer
.write('\t')
.write(name, false)
- .write("(flags)", 7);
+ .write("(flags)"sv, false);
if (readOnly) {
- this->parent.writer.write(" readonly", 9);
+ this->parent.writer.write(" readonly"sv, false);
}
if (report) {
- this->parent.writer.write(" report", 7);
+ this->parent.writer.write(" report"sv, false);
}
::writeOptionalKeyValueStrings(this->parent.writer, {displayName, description});
- this->parent.writer.write(" =\n\t[\n", 6);
+ this->parent.writer.write(" =\n\t[\n"sv, false);
return KeyValueFlagsWriter{*this};
}
FGDWriter::EntityWriter::KeyValueFlagsWriter& FGDWriter::EntityWriter::KeyValueFlagsWriter::flag(uint64_t value, const std::string& displayName, bool enabledByDefault, const std::string& description) {
this->parent.parent.writer
- .write("\t\t", 2)
+ .write("\t\t"sv, false)
.write(std::to_string(value), false)
- .write(" : \"", 4)
+ .write(" : \""sv, false)
.write(displayName, false)
- .write("\" : ", 4)
+ .write("\" : "sv, false)
.write(std::to_string(enabledByDefault), false);
if (!description.empty()) {
this->parent.parent.writer
- .write(" : \"", 4)
+ .write(" : \""sv, false)
.write(description, false)
.write('\"');
}
@@ -785,21 +786,21 @@ FGDWriter::EntityWriter::KeyValueFlagsWriter& FGDWriter::EntityWriter::KeyValueF
}
FGDWriter::EntityWriter& FGDWriter::EntityWriter::KeyValueFlagsWriter::endKeyValueFlags() const {
- this->parent.parent.writer.write("\t]\n", 3);
+ this->parent.parent.writer.write("\t]\n"sv, false);
return this->parent;
}
FGDWriter::EntityWriter& FGDWriter::EntityWriter::input(const std::string& name, const std::string& valueType, const std::string& description) {
this->parent.writer
.write('\t')
- .write("input ", 6)
+ .write("input "sv, false)
.write(name, false)
.write('(')
.write(valueType, false)
.write(')');
if (!description.empty()) {
this->parent.writer
- .write(" : \"", 4)
+ .write(" : \""sv, false)
.write(description, false)
.write('\"');
}
@@ -810,14 +811,14 @@ FGDWriter::EntityWriter& FGDWriter::EntityWriter::input(const std::string& name,
FGDWriter::EntityWriter& FGDWriter::EntityWriter::output(const std::string& name, const std::string& valueType, const std::string& description) {
this->parent.writer
.write('\t')
- .write("output ", 7)
+ .write("output "sv, false)
.write(name, false)
.write('(')
.write(valueType, false)
.write(')');
if (!description.empty()) {
this->parent.writer
- .write(" : \"", 4)
+ .write(" : \""sv, false)
.write(description, false)
.write('\"');
}
@@ -826,7 +827,7 @@ FGDWriter::EntityWriter& FGDWriter::EntityWriter::output(const std::string& name
}
FGDWriter& FGDWriter::EntityWriter::endEntity() const {
- this->parent.writer.write("]\n\n", 3);
+ this->parent.writer.write("]\n\n"sv, false);
return this->parent;
}
diff --git a/src/vtfpp/VTF.cpp b/src/vtfpp/VTF.cpp
index f7402f339..6d63c1880 100644
--- a/src/vtfpp/VTF.cpp
+++ b/src/vtfpp/VTF.cpp
@@ -1192,7 +1192,9 @@ std::vector VTF::bake() const {
}
writer
- .write(0) // padding
+ .write(0) // padding
+ .write(0) // padding
+ .write(0) // padding
.write(this->getResources().size() + hasAuxCompression)
.write(0); // padding