Skip to content

Session/agent 0d19c700 7fb5 44d4 ab75 2b8ab9741f18#6

Merged
Undertaker-afk merged 2 commits into
mainfrom
session/agent_0d19c700-7fb5-44d4-ab75-2b8ab9741f18
Apr 13, 2026
Merged

Session/agent 0d19c700 7fb5 44d4 ab75 2b8ab9741f18#6
Undertaker-afk merged 2 commits into
mainfrom
session/agent_0d19c700-7fb5-44d4-ab75-2b8ab9741f18

Conversation

@Undertaker-afk

@Undertaker-afk Undertaker-afk commented Apr 13, 2026

Copy link
Copy Markdown
Owner

Summary by Sourcery

Modernize skin changer and inventory helper code for safer C++ usage and minor API fixes.

Bug Fixes:

  • Fix incorrect knife definition lookup when redirecting viewmodel models.
  • Correct virtual function calls by ensuring this pointers are cast to void* when invoking vtable entries.
  • Replace strncpy with safer strncpy_s when copying custom item names.
  • Ensure global HMODULE handle is initialized before use by moving its declaration and assignment.

Enhancements:

  • Replace Windows-specific SEH (__try/__except) with standard C++ try/catch around external function calls in the skin changer.
  • Generalize CallVFunc helper to take a compile-time vtable index and support perfect forwarding of arguments with proper type decay.
  • Tighten character case-conversion logic in item search to avoid undefined behavior from char signedness and narrowing casts.
  • Expose skinchanger function pointer members by adding a public section in the SkinChanger class.
  • Normalize Windows header inclusion to <windows.h> for consistency.
  • Clarify WndProc declaration order before window subclassing in the DirectX hook.

Summary by CodeRabbit

  • Bug Fixes

    • Improved search functionality with corrected text normalization
    • Enhanced error handling for better stability
  • Chores

    • Internal code quality improvements and refactoring

kilo-code-bot Bot added 2 commits April 13, 2026 11:25
- convert structured exception handling blocks (__try/__except) to C++ try/catch in SkinChanger for robustness
- replace plain strncpy with strncpy_s for safe name copying
- fix lowercasing logic in item search with explicit casts for correctness
- expose internal function pointers (s_fn_create_econ_item, s_fn_set_dynamic_attr, s_fn_get_econ_item_system) as public
- move g_h_module to file scope and declare extern WndProc before subclassing window procedure
- sdk/inventory.hpp: generalize CallVFunc to support multiple Args and proper forwarding; adjust Windows include and add type_traits/utility
Copilot AI review requested due to automatic review settings April 13, 2026 13:42
@sourcery-ai

sourcery-ai Bot commented Apr 13, 2026

Copy link
Copy Markdown

Reviewer's Guide

Refactors the skinchanger and inventory interaction code for safer, more standard-compliant C++ usage (replacing SEH with C++ exceptions, tightening casts and string handling), introduces a more robust vtable call helper, and performs a few naming and initialization cleanups.

Class diagram for updated cs2::CallVFunc helper

classDiagram
    class cs2 {
        +CallVFunc~T, Index, Args...~(thisptr : void*, args : Args...) T
    }

    %% Template details
    class CallVFuncTemplate {
        <<template>>
        +T
        +Index : size_t
        +Args...
        +Fn = T(__thiscall*)(void*, remove_reference_t<Args>...)
    }

    cs2 ..> CallVFuncTemplate : uses
Loading

Class diagram for SkinChanger static API and fields

classDiagram
    class SkinChanger {
        <<static>>
        -s_initialized : bool
        -s_client_base : uintptr_t
        +s_fn_create_econ_item : uintptr_t
        +s_fn_set_dynamic_attr : uintptr_t
        +s_fn_get_econ_item_system : uintptr_t
        +s_fn_inventory_manager : uintptr_t
        +s_fn_set_model : uintptr_t
        +s_fn_set_mesh_group_mask : uintptr_t

        +Shutdown() void
        +CreateAndEquipItem(inventory : uintptr_t, manager : uintptr_t, team : int, slot : int, def_index : int, paint_kit_id : int, seed : int, wear : float, stattrak : int, custom_name : std::string) bool
        +ApplyGloves(inventory : uintptr_t, pawn : uintptr_t, view_model : uintptr_t) void
        +OnFrameStageNotify(stage : int) void
        +OnSetModel(entity : void*, model_path : const char*&) void
    }
Loading

File-Level Changes

Change Details Files
Replace Windows SEH (__try/__except) blocks with standard C++ try/catch around engine/inventory function pointers and mesh/model operations.
  • Wrap calls to s_fn_inventory_manager, s_fn_create_econ_item, s_fn_set_dynamic_attr and s_fn_set_mesh_group_mask in C++ try/catch blocks returning safe defaults on failure.
  • Update mesh/model-related calls in OnFrameStageNotify and ApplyGloves to use try/catch instead of __try/__except.
  • Keep the same error-handling semantics (swallowing all exceptions and returning 0/null/doing nothing) while removing compiler-specific SEH constructs.
src/features/skinchanger/skinchanger.cpp
Tighten pointer and vtable call usage for inventory-related functions to be more explicit and type-correct.
  • Explicitly cast uintptr_t manager/inventory to void* when passing as the this pointer to vtable functions (GetLocalInventory, EquipItemInLoadout, SO cache SOCreated call).
src/features/skinchanger/skinchanger.cpp
Modernize and generalize the CallVFunc helper to use a template index parameter and perfect forwarding.
  • Change CallVFunc to take template parameters <T, size_t Index, typename... Args> and a void* thisptr with Args&&... for arguments.
  • Define Fn as T(__thiscall*)(void*, std::remove_reference_t...) to avoid forwarding references in the function pointer type and use std::forward when invoking.
src/sdk/inventory.hpp
Make string case-normalization in item search explicitly safe in terms of char signedness and return type.
  • Cast query chars to unsigned char before std::tolower, and back to char when storing in lower_query.
  • Adjust lambdas in std::transform to cast unsigned char to char after std::tolower when building lower_name.
src/features/skinchanger/items.cpp
Harden custom name copying and fix a knife config field name usage.
  • Replace std::strncpy with strncpy_s when copying skin.custom_name into the C_EconItemView buffer, passing the buffer size explicitly.
  • Use s_knife.def_index instead of s_knife.defIndex when looking up the custom knife item definition in OnSetModel.
src/features/skinchanger/skinchanger.cpp
Clean up DLL/global initialization and window procedure declaration ordering.
  • Introduce a global g_h_module at the top of dllmain.cpp and remove the later redundant definition.
  • Add an extern declaration for WndProc before calling SetWindowLongPtr in HookedPresent to satisfy the compiler and make the dependency explicit.
src/dllmain.cpp
Expose SkinChanger function pointers publicly while keeping other members private.
  • Insert a public: section before the static function pointer members (s_fn_create_econ_item, s_fn_set_dynamic_attr, s_fn_get_econ_item_system) so they are accessible externally.
src/features/skinchanger/skinchanger.hpp

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@Undertaker-afk Undertaker-afk merged commit 2b83863 into main Apr 13, 2026
2 of 7 checks passed
@coderabbitai

coderabbitai Bot commented Apr 13, 2026

Copy link
Copy Markdown

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 0e18232c-d4c2-4c54-8a95-61f42f59e19c

📥 Commits

Reviewing files that changed from the base of the PR and between 1d0c3b1 and cadaf10.

📒 Files selected for processing (5)
  • src/dllmain.cpp
  • src/features/skinchanger/items.cpp
  • src/features/skinchanger/skinchanger.cpp
  • src/features/skinchanger/skinchanger.hpp
  • src/sdk/inventory.hpp

📝 Walkthrough

Walkthrough

The pull request refactors exception handling from Windows SEH to C++ try-catch, updates the CallVFunc template signature to use compile-time virtual function indices, adjusts type conversions and casts for consistency, modifies access specifiers for static function pointers, and consolidates module handle management.

Changes

Cohort / File(s) Summary
Exception Handling & Type Casting
src/dllmain.cpp, src/features/skinchanger/skinchanger.cpp
Introduced global static module handle consolidation in dllmain.cpp with forward declarations. In skinchanger.cpp, replaced Windows SEH __try/__except blocks with standard C++ try/catch, updated function pointer casts to use reinterpret_cast<void*>, and switched from std::strncpy to strncpy_s.
Case Normalization
src/features/skinchanger/items.cpp
Added explicit char casts to std::tolower results in both ItemDatabase::Search overloads for case-insensitive string handling.
API Template Refactor
src/sdk/inventory.hpp
Refactored CallVFunc template to move virtual function slot index from runtime parameter to compile-time template argument; updated parameter typing with explicit Args&&... and std::forward perfect forwarding; added <type_traits> and <utility> includes.
Access Control Update
src/features/skinchanger/skinchanger.hpp
Inserted explicit public: access specifier to expose static function-pointer members (s_fn_create_econ_item, s_fn_set_dynamic_attr, s_fn_get_econ_item_system, and related functions) as publicly accessible.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 With whiskers twitched in glee
Exception handlers refactored free,
Templates compile with indices tight,
Access controls set just right!
A rabbit's hop through code so neat.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch session/agent_0d19c700-7fb5-44d4-ab75-2b8ab9741f18

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 2 issues, and left some high level feedback:

  • Replacing __try/__except with C++ try/catch(...) changes what kinds of faults are actually caught (e.g., access violations are no longer handled unless compiled with /EHa), so if these wrappers are meant to guard against unsafe external calls you may want to keep SEH or explicitly document/ensure the exception model used.
  • The new CallVFunc signature requires the vtable index as a template parameter (Index) instead of a runtime size_t index; if there are existing call sites still passing an index at runtime they will now fail to compile or need refactoring, so it’s worth double-checking or adding a small helper/wrapper to ease the transition.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- Replacing `__try/__except` with C++ `try/catch(...)` changes what kinds of faults are actually caught (e.g., access violations are no longer handled unless compiled with `/EHa`), so if these wrappers are meant to guard against unsafe external calls you may want to keep SEH or explicitly document/ensure the exception model used.
- The new `CallVFunc` signature requires the vtable index as a template parameter (`Index`) instead of a runtime `size_t index`; if there are existing call sites still passing an index at runtime they will now fail to compile or need refactoring, so it’s worth double-checking or adding a small helper/wrapper to ease the transition.

## Individual Comments

### Comment 1
<location path="src/features/skinchanger/skinchanger.cpp" line_range="140-141" />
<code_context>
     using Fn = uintptr_t(__fastcall*)();
-    __try { return ((Fn)SkinChanger::s_fn_inventory_manager)(); }
-    __except (EXCEPTION_EXECUTE_HANDLER) { return 0; }
+    try { return ((Fn)SkinChanger::s_fn_inventory_manager)(); }
+    catch (...) { return 0; }
 }

</code_context>
<issue_to_address>
**issue (bug_risk):** Using C++ try/catch instead of SEH __try/__except may no longer guard against access violations.

Previously this used `__try/__except`, which can handle SEH exceptions (e.g., access violations) when calling engine/game function pointers. Standard C++ `try`/`catch (...)` will not catch SEH unless the code is compiled with `/EHa`, so access violations may now crash the process instead of being handled. Either keep SEH for this boundary call or ensure `/EHa` is required and documented.
</issue_to_address>

### Comment 2
<location path="src/features/skinchanger/skinchanger.cpp" line_range="170-171" />
<code_context>
     using Fn = CEconItem_t*(__cdecl*)();
-    __try { return ((Fn)SkinChanger::s_fn_create_econ_item)(); }
-    __except (EXCEPTION_EXECUTE_HANDLER) { return nullptr; }
+    try { return ((Fn)SkinChanger::s_fn_create_econ_item)(); }
+    catch (...) { return nullptr; }
 }

</code_context>
<issue_to_address>
**issue (bug_risk):** Same SEH vs C++ exception handling concern for econ item creation and attribute setting.

This function (and `SetDynamicAttributeValue`, `ApplyGloves`, `SetModel`, `SetMeshGroupMask`) now uses `try`/`catch (...)` instead of `__try/__except`. If these engine function pointers can raise SEH faults (e.g., due to engine changes or invalid state), C++ exceptions will not catch them and the process may crash. To maintain the previous fault-tolerance, either keep SEH around these calls or document and enforce that only C++ exceptions can be thrown here (via build config/contracts).
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment on lines +140 to +141
try { return ((Fn)SkinChanger::s_fn_inventory_manager)(); }
catch (...) { return 0; }

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (bug_risk): Using C++ try/catch instead of SEH __try/__except may no longer guard against access violations.

Previously this used __try/__except, which can handle SEH exceptions (e.g., access violations) when calling engine/game function pointers. Standard C++ try/catch (...) will not catch SEH unless the code is compiled with /EHa, so access violations may now crash the process instead of being handled. Either keep SEH for this boundary call or ensure /EHa is required and documented.

Comment on lines +170 to +171
try { return ((Fn)SkinChanger::s_fn_create_econ_item)(); }
catch (...) { return nullptr; }

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (bug_risk): Same SEH vs C++ exception handling concern for econ item creation and attribute setting.

This function (and SetDynamicAttributeValue, ApplyGloves, SetModel, SetMeshGroupMask) now uses try/catch (...) instead of __try/__except. If these engine function pointers can raise SEH faults (e.g., due to engine changes or invalid state), C++ exceptions will not catch them and the process may crash. To maintain the previous fault-tolerance, either keep SEH around these calls or document and enforce that only C++ exceptions can be thrown here (via build config/contracts).

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request refactors several components, including the CallVFunc template, exception handling mechanisms, and string processing logic. Key feedback includes concerns regarding the replacement of Structured Exception Handling (SEH) with standard C++ exceptions, which may not catch hardware exceptions like access violations in this context. Additionally, the CallVFunc refactor incorrectly strips reference qualifiers, potentially leading to stack corruption, and the inline extern declaration of WndProc should be moved to improve code maintainability.

Comment on lines +140 to +141
try { return ((Fn)SkinChanger::s_fn_inventory_manager)(); }
catch (...) { return 0; }

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Replacing Structured Exception Handling (__try/__except) with standard C++ exceptions (try/catch) is dangerous in this context. Standard C++ exceptions do not catch hardware exceptions like Access Violations (EXCEPTION_ACCESS_VIOLATION) on Windows unless the code is compiled with the /EHa flag. Since this code interacts with game memory via potentially unstable pointers, using try/catch (...) will likely fail to prevent crashes that the original SEH code would have handled. This pattern is repeated throughout this file (e.g., lines 170, 177, 362, 490, 502, 542).

Comment thread src/sdk/inventory.hpp
Comment on lines +13 to +14
using Fn = T(__thiscall*)(void*, std::remove_reference_t<Args>...);
return (*reinterpret_cast<Fn**>(thisptr))[Index](thisptr, std::forward<Args>(args)...);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The use of std::remove_reference_t<Args>... in the function pointer signature strips reference qualifiers. If a virtual function expects a reference (e.g., const Vector&), the Fn type will incorrectly be defined as taking the object by value, leading to stack corruption or incorrect behavior. Using Args... directly in the function pointer signature is more appropriate as it preserves the value category (lvalue/rvalue) of the arguments passed to the template.

    using Fn = T(__thiscall*)(void*, Args...);
    return (*reinterpret_cast<Fn**>(thisptr))[Index](thisptr, std::forward<Args>(args)...);

Comment thread src/dllmain.cpp

// Subclass window
// Subclass window - declare WndProc first
extern LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Declaring an extern function inside a function body is generally discouraged as it obscures dependencies and can make the code harder to maintain. It is better to declare WndProc at the top of the file or in a shared header file.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR appears focused on improving low-level SDK/helpers used by the skin changer (vtable calling helpers, Windows/UI glue code) and tightening up a few string/character handling details.

Changes:

  • Refactors CallVFunc to use a compile-time vtable index and perfect-forwarded args.
  • Adjusts SkinChanger header visibility for scanned function pointers and updates several engine-call guard patterns in skinchanger.cpp.
  • Improves safety/typing in a few utility spots (e.g., strncpy_s, std::tolower casting) and tweaks Win32 WndProc wiring.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
src/sdk/inventory.hpp Updates vfunc-calling helper to be index-at-compile-time and adds needed headers.
src/features/skinchanger/skinchanger.hpp Changes access control to expose scanned function pointers via a new public: block.
src/features/skinchanger/skinchanger.cpp Replaces several SEH guards with C++ try/catch, adjusts some call casts, uses strncpy_s, and updates knife config field naming.
src/features/skinchanger/items.cpp Ensures tolower results are safely converted back to char.
src/dllmain.cpp Moves g_h_module global and adds an in-function WndProc forward declaration before subclassing.
Comments suppressed due to low confidence (1)

src/features/skinchanger/skinchanger.hpp:125

  • Adding a second public: section here makes the scanned function pointer addresses (s_fn_*) part of the public API, which exposes internal hooking/offset details to any includer. Since these are only used by helper functions in skinchanger.cpp, consider keeping them private and moving those helpers into SkinChanger as private static methods (or using friend declarations) to preserve encapsulation.
    static uintptr_t s_client_base;
    
public:
    static uintptr_t s_fn_create_econ_item;
    static uintptr_t s_fn_set_dynamic_attr;
    static uintptr_t s_fn_get_econ_item_system;
    static uintptr_t s_fn_inventory_manager;
    static uintptr_t s_fn_update_subclass;
    static uintptr_t s_fn_set_mesh_group_mask;
    static uintptr_t s_fn_set_model;
    static uintptr_t s_force_viewmodel_fn;

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +140 to +141
try { return ((Fn)SkinChanger::s_fn_inventory_manager)(); }
catch (...) { return 0; }

Copilot AI Apr 13, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Replacing SEH (__try/__except) with C++ try/catch here will not catch access violations or other structured exceptions under the current build flags (CMakeLists.txt does not enable /EHa or an SEH-to-C++ translator). These calls are invoking scanned function pointers, so a bad address will still crash the process. Please restore __try/__except for these guard calls, or explicitly enable SEH translation (/EHa or _set_se_translator) and justify the behavior change.

Suggested change
try { return ((Fn)SkinChanger::s_fn_inventory_manager)(); }
catch (...) { return 0; }
__try {
return ((Fn)SkinChanger::s_fn_inventory_manager)();
}
__except (EXCEPTION_EXECUTE_HANDLER) {
return 0;
}

Copilot uses AI. Check for mistakes.
Comment on lines 167 to +171
static CEconItem_t* CreateEconItem() {
if (!SkinChanger::s_fn_create_econ_item) return nullptr;
using Fn = CEconItem_t*(__cdecl*)();
__try { return ((Fn)SkinChanger::s_fn_create_econ_item)(); }
__except (EXCEPTION_EXECUTE_HANDLER) { return nullptr; }
try { return ((Fn)SkinChanger::s_fn_create_econ_item)(); }
catch (...) { return nullptr; }

Copilot AI Apr 13, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same issue as above: C++ catch(...) will not intercept SEH faults from calling a potentially-invalid scanned function pointer, so this no longer provides crash protection. Prefer keeping the original __try/__except guard (or add /EHa / SEH translator if you intend to rely on catch(...)).

Copilot uses AI. Check for mistakes.
Comment on lines 174 to +178
static void SetDynamicAttributeValue(CEconItem_t* item, uint16_t attr_index, float value) {
if (!SkinChanger::s_fn_set_dynamic_attr || !item) return;
using Fn = void(__fastcall*)(CEconItem_t*, uint16_t, float);
__try { ((Fn)SkinChanger::s_fn_set_dynamic_attr)(item, attr_index, value); }
__except (EXCEPTION_EXECUTE_HANDLER) {}
try { ((Fn)SkinChanger::s_fn_set_dynamic_attr)(item, attr_index, value); }
catch (...) {}

Copilot AI Apr 13, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same issue as above: this try/catch won’t catch structured exceptions (e.g., access violations) thrown by the engine call, so the guard is ineffective with the current exception model. Consider reverting to __try/__except for this boundary call, or introduce explicit SEH translation in the build/runtime.

Copilot uses AI. Check for mistakes.
Comment on lines +362 to +363
try { ((Fn)s_fn_set_mesh_group_mask)(view_model, 1); }
catch (...) {}

Copilot AI Apr 13, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

C++ catch(...) here won’t catch access violations from the engine call unless you compile with /EHa or install an SEH-to-C++ translator. This code previously used SEH to prevent crashes; consider reverting to __try/__except around this external call boundary.

Suggested change
try { ((Fn)s_fn_set_mesh_group_mask)(view_model, 1); }
catch (...) {}
__try {
((Fn)s_fn_set_mesh_group_mask)(view_model, 1);
} __except (EXCEPTION_EXECUTE_HANDLER) {
}

Copilot uses AI. Check for mistakes.
Comment on lines 489 to 496
using SetModelFn = void(__fastcall*)(uintptr_t, const char*);
__try {
try {
((SetModelFn)s_fn_set_model)(entity, def->model_path.c_str());
if (view_model)
((SetModelFn)s_fn_set_model)(view_model, def->model_path.c_str());
}
__except (EXCEPTION_EXECUTE_HANDLER) {}
catch (...) {}
}

Copilot AI Apr 13, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The try/catch guard around this scanned function pointer call will not catch SEH exceptions (e.g., AV) with the current build configuration, so it won’t prevent hard crashes. Please restore __try/__except (or add /EHa / SEH translation) for these engine boundary calls.

Copilot uses AI. Check for mistakes.
Comment on lines 499 to +507
// MeshGroupMask
if (s_fn_set_mesh_group_mask) {
using Fn = void(__fastcall*)(uintptr_t, uint32_t);
__try {
try {
((Fn)s_fn_set_mesh_group_mask)(entity, 2);
if (view_model)
((Fn)s_fn_set_mesh_group_mask)(view_model, 2);
}
__except (EXCEPTION_EXECUTE_HANDLER) {}
catch (...) {}

Copilot AI Apr 13, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above: catch(...) won’t intercept structured exceptions from this engine call without /EHa or an SEH translator, so the crash-guard behavior has effectively been removed. Consider reverting to __try/__except around this call site.

Copilot uses AI. Check for mistakes.
Comment on lines 536 to +550
if (s_fn_set_mesh_group_mask) {
using Fn = void(__fastcall*)(uintptr_t, uint32_t);
bool legacy = false;
if (const DumpedPaintKit* pk = ItemDatabase::FindPaintKit(skin.paint_kit_id))
legacy = pk->is_legacy;
uint32_t mask = legacy ? 2 : 1;
__try {
try {
((Fn)s_fn_set_mesh_group_mask)(entity, mask);
if (view_model) {
uint32_t vm_weapon = *reinterpret_cast<uint32_t*>(view_model + 0x38);
if (vm_weapon == static_cast<uint32_t>(i))
((Fn)s_fn_set_mesh_group_mask)(view_model, mask);
}
}
__except (EXCEPTION_EXECUTE_HANDLER) {}
catch (...) {}

Copilot AI Apr 13, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same issue: this try/catch does not protect against access violations from calling into engine code/function pointers under /EHsc. If the intent is crash hardening, prefer SEH (__try/__except) at this boundary or add explicit SEH translation support.

Copilot uses AI. Check for mistakes.
Comment thread src/dllmain.cpp
Comment on lines +80 to 83
// Subclass window - declare WndProc first
extern LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
g_original_wnd_proc = reinterpret_cast<WNDPROC>(
SetWindowLongPtr(g_hwnd, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(WndProc)));

Copilot AI Apr 13, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This forward declaration uses extern (external linkage), but the actual WndProc definition below is static (internal linkage). That linkage mismatch is a compile error in C++. Fix by forward-declaring it as static (ideally at file scope above HookedPresent), or remove the extern and move a correct prototype before first use.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants