Skip to content

Commit

Permalink
Merge pull request #62 from Cre3per/compile-sdk
Browse files Browse the repository at this point in the history
Compile sdk
  • Loading branch information
es3n1n committed Sep 10, 2024
2 parents fcc2d98 + 30743e0 commit 209b85c
Show file tree
Hide file tree
Showing 14 changed files with 1,006 additions and 350 deletions.
28 changes: 27 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ source2gen-loader.exe

```sh
./scripts/run.sh "$HOME/.steam/steam/steamapps/cs2/"
cp -r ./sdk-static/* ./sdk
# view generated sdk
ls ./sdk
```
Expand All @@ -37,7 +38,32 @@ errors, bugs, and wrong output. Please only file issues if you want to work on
them. This note will be removed once we have thoroughly tested Source2Gen on
Linux.

## Getting Started
### Using the generated SDK

The sdk depends on a file/module called `source2gen.hpp`. This file has
to be provided by the user and expose all types listed in
[source2gen.hpp](sdk-static/include/source2sdk/source2gen.hpp). If you don't
intend to access any of these types, you can use the dummy file
[source2gen.hpp](sdk-static/include/source2sdk/source2gen.hpp).

## Limitations

### Disabled entities

Under the following conditions, entities are either entirely omitted, or emitted
as a comment and replaced with a dummy:

- Overlapping fields: Fields that share memory with another field
- Misaligned fields: Fields that cannot be placed at the correct in-class offset
because of their type's alignment requirements
- Misaligned types: Class types that would exceed their correct size because
padding bytes would have to be inserted to meet alignment requirements
- Fields with template types

Some of these disabled entities can be made to work by using compiler-specific
attributes.

## Getting Started with Development

These instructions will help you set up the project on your local machine for development and testing purposes.

Expand Down
42 changes: 23 additions & 19 deletions scripts/run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,19 @@ SCRIPT_DIRECTORY="$(dirname "$(readlink -f "$0")")"
PROJECT_ROOT="${SCRIPT_DIRECTORY}/../"
BINARY=""

find_second_bin_directory() {
local game_path="$1"

local found;found="$(find "${game_path}" -name libclient.so)"

if [ -z "${found}" ]; then
echo "Error: unable to find second bin directory" >&2
exit 1
else
dirname "${found}"
fi
}

if [ -z "${GAME_DIRECTORY}" ]; then
echo "usage: run.sh <path/to/game/directory>"
echo "eg : run.sh $HOME/.steam/steam/steamapps/cs2/"
Expand All @@ -28,23 +41,14 @@ done
if [ -z "${BINARY}" ]; then
echo "source2gen binary not found. set LD_PRELOAD_PATH and run source2gen by hand."
exit 1
else
FIRST_BIN_DIRECTORY="${GAME_DIRECTORY}/game/bin/linuxsteamrt64/"
SECOND_BIN_DIRECTORY=$(find_second_bin_directory "$GAME_DIRECTORY")
export LD_LIBRARY_PATH="${FIRST_BIN_DIRECTORY}:${SECOND_BIN_DIRECTORY}:${LD_LIBRARY_PATH:-}"
set -x
if [ -z "${DEBUGGER:-}" ]; then
"${BINARY}"
else
"${DEBUGGER}" -- "${BINARY}"
fi
fi

find_second_bin_directory() {
local game_path="$1"

local found;found="$(find "${game_path}" -name libclient.so)"

if [ -z "${found}" ]; then
echo "Error: unable to find second bin directory" >&2
exit 1
else
dirname "${found}"
fi
}

FIRST_BIN_DIRECTORY="${GAME_DIRECTORY}/game/bin/linuxsteamrt64/"
SECOND_BIN_DIRECTORY=$(find_second_bin_directory "$GAME_DIRECTORY")

set -x
LD_LIBRARY_PATH="${FIRST_BIN_DIRECTORY}:${SECOND_BIN_DIRECTORY}:${LD_LIBRARY_PATH:-}" "${BINARY}"
39 changes: 39 additions & 0 deletions sdk-static/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
cmake_minimum_required(VERSION 3.30)

set(CMAKE_EXPORT_COMPILE_COMMANDS On)

project(source2sdk
LANGUAGES CXX
)

file(GLOB_RECURSE source2sdk_headers "./**.hpp")

add_library(${PROJECT_NAME} INTERFACE)
target_include_directories(${PROJECT_NAME} INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/include)
set_target_properties(${PROJECT_NAME} PROPERTIES PUBLIC_HEADER "${source2sdk_headers}")

set_target_properties(${PROJECT_NAME} PROPERTIES LINKER_LANGUAGE CXX)

install(
DIRECTORY "${CMAKE_SOURCE_DIR}/include"
DESTINATION .
)

# Add a target that includes all headers of the generated library to check for compile-time errors

foreach(el ${source2sdk_headers})
string(APPEND generated_cpp_contents "#include \"${el}\"\n")
endforeach()

set(generated_cpp_file "${CMAKE_BINARY_DIR}/all_headers.cpp")

file(WRITE ${generated_cpp_file} ${generated_cpp_contents})

add_library(${PROJECT_NAME}-compile-test ${generated_cpp_file})
set_target_properties(${PROJECT_NAME}-compile-test PROPERTIES LINKER_LANGUAGE CXX)
target_link_libraries(${PROJECT_NAME}-compile-test ${PROJECT_NAME})

target_compile_options(${PROJECT_NAME}-compile-test PRIVATE
"-Wfatal-errors"
"-pedantic-errors"
)
51 changes: 51 additions & 0 deletions sdk-static/conanfile.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
from conan import ConanFile
from conan.tools.cmake import CMakeToolchain, CMake, cmake_layout, CMakeDeps


# TODO: We should set `version` and `name` to reflect what game this sdk is for
class source2sdkRecipe(ConanFile):
name = "source2sdk"
version = "0.0.0"
package_type = "library"

author = "source2gen"
url = "https://github.com/neverlosecc/source2gen"
description = "Source2 SDK"
topics = ("source2",)

settings = "os", "compiler", "build_type", "arch"
options = {"shared": [True, False], "fPIC": [True, False]}
default_options = {"shared": False, "fPIC": True}

exports_sources = "CMakeLists.txt", "include/*"

def config_options(self):
if self.settings.os == "Windows":
self.options.rm_safe("fPIC")

def configure(self):
if self.options.shared:
self.options.rm_safe("fPIC")

def layout(self):
cmake_layout(self)

def generate(self):
deps = CMakeDeps(self)
deps.generate()
tc = CMakeToolchain(self)
tc.generate()

def build(self):
cmake = CMake(self)
cmake.configure()
cmake.build()

def package(self):
cmake = CMake(self)
cmake.install()

def package_info(self):
self.cpp_info.bindirs = []
self.cpp_info.libdirs = []

149 changes: 149 additions & 0 deletions sdk-static/include/source2sdk/source2gen.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
#pragma once
#include <cstdint>
#include <string_view>

template <typename>
using CAnimValue = char[0x08];
using CAnimVariant = char[0x11];
// size is a guess
template <typename T>
using CAnimScriptParam = char[0x08];
using CBufferString = char[0x10];
using CColorGradient = char[0x18];
// size doesn't matter. only used as a pointer
template <typename>
using CCompressor = char[0x01];
using CEntityHandle = char[0x04];
using CEntityIndex = char[0x04];
using CGlobalSymbol = char[0x08];
using CKV3MemberNameWithStorage = char[0x38];
using CNetworkedQuantizedFloat = char[0x08];
using CParticleNamedValueRef = char[0x40];
using CPiecewiseCurve = char[0x40];
using CPlayerSlot = char[0x04];
using CPulseValueFullType = char[0x10];
using CResourceName = char[0xe0];
using CSplitScreenSlot = char[0x04];
using CTransform = char[0x20];
using CUtlBinaryBlock = char[0x18];
template <typename, typename>
using CUtlHashtable = char[0x20];
using CUtlStringTokenWithStorage = char[0x18];
using CUtlStringToken = char[0x04];
using CUtlString = char[0x08];
using CUtlSymbolLarge = char[0x08];
using CUtlSymbol = char[0x02];
template <typename>
using CAnimGraphParamOptionalRef = char[0x20];
template <typename>
using CAnimGraphParamRef = char[0x20];
template <int N>
using CBitVec = char[(N + 7) / 8];
template <typename>
using CEntityOutputTemplate = char[0x28];
template <typename>
using CHandle = char[0x04];
template <typename>
using C_NetworkUtlVectorBase = char[0x18];
template <typename>
using CNetworkUtlVectorBase = char[0x18];
// size unknown. only used in dynamic containers.
using CSoundEventName = char[0x01];
template <typename>
using CUtlLeanVector = char[0x10];
template <typename, class>
using CUtlOrderedMap = char[0x28];
// size doesn't matter. only used as a pointer
template <typename, class>
using CUtlPair = char[0x01];
template <typename>
using CUtlVector = char[0x18];
// size is a guess that fits both occurences of this type in CS2
template <typename Ty>
using CUtlVectorFixedGrowable = char[0x18 + ((sizeof(Ty) < 4) ? 4 : sizeof(Ty))];
template <typename Ty>
using CUtlLeanVectorFixedGrowable = char[0x10 + ((sizeof(Ty) < 4) ? 4 : sizeof(Ty))];
template <typename>
using C_UtlVectorEmbeddedNetworkVar = char[0x50];
template <typename>
using CUtlVectorEmbeddedNetworkVar = char[0x50];
using CUtlVectorSIMDPaddedVector = char[0x18];
template <typename>
using CSmartPtr = char[0x08];
template <typename>
using CResourceArray = char[0x08];
// size unknown
using CResourceString = char[0x08];
template <typename>
using CResourcePointer = char[0x08];
template <typename>
using CResourceNameTyped = char[0xe0];
template <typename>
using CStrongHandle = char[0x08];
template <typename>
using CStrongHandleCopyable = char[0x08];
// size doesn't matter. only used as a pointer
using CStrongHandleVoid = char[0x08];
template <typename>
using CVariantBase = char[0x10];
template <typename>
using CWeakHandle = char[0x18];
using CSmartPropAttributeVector = char[0x40];
using CSmartPropAttributeFloat = char[0x40];
using CSmartPropAttributeBool = char[0x40];
using CSmartPropAttributeColor = char[0x40];
using CSmartPropAttributeInt = char[0x40];
using CSmartPropAttributeModelName = char[0x40];
using CSmartPropAttributeMaterialGroup = char[0x40];
using CSmartPropAttributeVector2D = char[0x40];
using CSmartPropVariableComparison = char[0x20];
using CSmartPropAttributeAngles = char[0x40];
using CSmartPropAttributeStateName = char[0x40];
using CSmartPropAttributeVariableValue = char[0x40];
using Color = char[0x04];
using DegreeEuler = char[0x0c];
using FourVectors = char[0x30];
using HSCRIPT = char[0x08];
using KeyValues3 = char[0x10];
// size doesn't matter. only used as a pointer
using KeyValues = char[0x01];
using QAngle = char[0x0c];
using QuaternionStorage = char[0x10];
using Quaternion = char[0x10];
using RadianEuler = char[0x0c];
using RenderInputLayoutField_t = char[0x04];
// we don't have a field size for this type. uses the fallback of 1.
using RenderPrimitiveType_t = char[0x01];
using RotationVector = char[0x0c];
template <typename>
using SphereBase_t = char[0x10];
using Vector2D = char[0x08];
using Vector4D = char[0x10];
using VectorAligned = char[0x10];
using Vector = char[0x0c];
using WorldGroupId_t = char[0x04];
using float32 = char[0x04];
using fltx4 = char[0x10];
using matrix3x4_t = char[0x30];
using matrix3x4a_t = char[0x30];

// intentionally left undefined. if you want to access static fields, add your own sdk.
namespace interfaces {
struct SchemaStaticFieldData_t {
void* m_pInstance{};
};

struct CSchemaClassInfo {
auto GetStaticFields() -> SchemaStaticFieldData_t**;
};

struct CSchemaSystemTypeScope {
auto FindDeclaredClass(std::string_view) -> CSchemaClassInfo*;
};

struct schema_t {
auto FindTypeScopeForModule(std::string_view) -> CSchemaSystemTypeScope*;
};

extern schema_t* g_schema;
} // namespace interfaces
5 changes: 4 additions & 1 deletion source2gen/include/sdk/interfaces/common/CUtlTSHash.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,13 @@
// See end of file for extended copyright information.
#pragma once
#include "sdk/interfaces/common/CThreadSpinMutex.h"
#include "sdk/interfaces/common/CThreadSpinRWLock.h"
#include "sdk/interfaces/common/CUtlMemory.h"
#include "sdk/interfaces/common/CUtlMemoryPoolBase.h"
#include <climits>
#include <cstdint>
#include <type_traits>
#include <vector>

#if defined(CS2) || defined(DOTA2) || defined(DEADLOCK)
constexpr auto kUtlTsHashVersion = 2;
Expand Down Expand Up @@ -273,7 +276,7 @@ inline std::vector<T> CUtlTSHashV2<T, Keytype, BucketCount, HashFuncs>::merge_wi
std::vector<T> merged_list = allocated_list;

for (const auto& item : un_allocated_list) {
if (std::find_if(allocated_list.begin(), allocated_list.end(), [&](const T& elem) { return pred(elem, item); }) == allocated_list.end()) {
if (std::ranges::find_if(allocated_list, [&](const T& elem) { return pred(elem, item); }) == allocated_list.end()) {
merged_list.push_back(item);
}
}
Expand Down
Loading

0 comments on commit 209b85c

Please sign in to comment.