Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
private static readonly Lazy<nint> _$NAME$Offset = new(() => Schema.GetOffset($HASH$), LazyThreadSafetyMode.None);

public string $NAME$ {
get {
var ptr = _Handle + Schema.GetOffset($HASH$);
var ptr = _Handle + _$NAME$Offset.Value;
return Schema.GetString(ptr);
}
set => Schema.SetFixedString(_Handle, $HASH$, value, $ELEMENT_COUNT$);
set => Schema.SetFixedString(_Handle, _$NAME$Offset.Value, value, $ELEMENT_COUNT$);
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
private static readonly Lazy<nint> _$NAME$Offset = new(() => Schema.GetOffset($HASH$), LazyThreadSafetyMode.None);

public $INTERFACE_TYPE$? $NAME$ {
get {
var ptr = _Handle.Read<nint>(Schema.GetOffset($HASH$));
var ptr = _Handle.Read<nint>(_$NAME$Offset.Value);
return ptr.IsValidPtr() ? new $IMPL_TYPE$(ptr) : null;
}
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
private static readonly Lazy<nint> _$NAME$Offset = new(() => Schema.GetOffset($HASH$), LazyThreadSafetyMode.None);

public $INTERFACE_TYPE$ $NAME$ {
get => new $IMPL_TYPE$(_Handle + Schema.GetOffset($HASH$));
get => new $IMPL_TYPE$(_Handle + _$NAME$Offset.Value);
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
private static readonly Lazy<nint> _$NAME$Offset = new(() => Schema.GetOffset($HASH$), LazyThreadSafetyMode.None);

public string $NAME$ {
get {
var ptr = _Handle.Read<nint>(Schema.GetOffset($HASH$));
var ptr = _Handle.Read<nint>(_$NAME$Offset.Value);
return Schema.GetString(ptr);
}
set => Schema.SetString(_Handle, $HASH$, value);
set => Schema.SetString(_Handle, _$NAME$Offset.Value, value);
}
2 changes: 2 additions & 0 deletions generator/schema_generator/templates/class_template.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
#pragma warning disable CS0108
#nullable enable

using System;
using System.Threading;
using SwiftlyS2.Core.Schemas;
using SwiftlyS2.Shared.Schemas;
using SwiftlyS2.Shared.SchemaDefinitions;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
private static readonly Lazy<nint> _$NAME$Offset = new(() => Schema.GetOffset($HASH$), LazyThreadSafetyMode.None);

public ref $IMPL_TYPE$ $NAME$ {
get => ref _Handle.$REF_METHOD$<$IMPL_TYPE$>(Schema.GetOffset($HASH$));
get => ref _Handle.$REF_METHOD$<$IMPL_TYPE$>(_$NAME$Offset.Value);
}
72 changes: 55 additions & 17 deletions managed/src/SwiftlyS2.Core/Extensions/PtrExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,77 +5,115 @@

namespace SwiftlyS2.Core.Extensions;

internal static class PtrExtensions {
internal static class PtrExtensions
{

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static T Read<T>(this nint ptr) where T : unmanaged {
public static T Read<T>( this nint ptr ) where T : unmanaged
{
unsafe { return Unsafe.Read<T>((void*)ptr); }
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static T Read<T>(this nint ptr, int offset) where T : unmanaged
public static T Read<T>( this nint ptr, int offset ) where T : unmanaged
{
unsafe { return Unsafe.Read<T>((void*)(ptr + offset)); }
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static T Read<T>( this nint ptr, nint offset ) where T : unmanaged
{
unsafe { return Unsafe.Read<T>((void*)(ptr + offset)); }
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ref T AsRef<T>(this nint ptr) where T : unmanaged {
public static ref T AsRef<T>( this nint ptr ) where T : unmanaged
{
unsafe { return ref Unsafe.AsRef<T>((void*)ptr); }
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ref T AsRef<T>(this nint ptr, int offset) where T : unmanaged {
public static ref T AsRef<T>( this nint ptr, int offset ) where T : unmanaged
{
unsafe { return ref Unsafe.AsRef<T>((void*)(ptr + offset)); }
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ref T Deref<T>(this nint ptr) where T : unmanaged {
public static ref T AsRef<T>( this nint ptr, nint offset ) where T : unmanaged
{
unsafe { return ref Unsafe.AsRef<T>((void*)(ptr + offset)); }
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ref T Deref<T>( this nint ptr ) where T : unmanaged
{
return ref ptr.Read<nint>().AsRef<T>();
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ref T Deref<T>(this nint ptr, int offset) where T : unmanaged {
public static ref T Deref<T>( this nint ptr, int offset ) where T : unmanaged
{
return ref ptr.Read<nint>(offset).AsRef<T>();
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ref T Deref<T>( this nint ptr, nint offset ) where T : unmanaged
{
return ref ptr.Read<nint>(offset).AsRef<T>();
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Write<T>(this nint ptr, T value) where T : unmanaged {
public static void Write<T>( this nint ptr, T value ) where T : unmanaged
{
unsafe { Unsafe.Write((void*)ptr, value); }
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Write<T>(this nint ptr, int offset, T value) where T : unmanaged
public static void Write<T>( this nint ptr, int offset, T value ) where T : unmanaged
{
unsafe { Unsafe.Write((void*)(ptr + offset), value); }
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void CopyFrom(this nint ptr, byte[] source)
public static void Write<T>( this nint ptr, nint offset, T value ) where T : unmanaged
{
unsafe {
fixed (byte* sourcePtr = source) {
Unsafe.CopyBlockUnaligned((void*)ptr, sourcePtr, (uint)source.Length); }
unsafe { Unsafe.Write((void*)(ptr + offset), value); }
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void CopyFrom( this nint ptr, byte[] source )
{
unsafe
{
fixed (byte* sourcePtr = source)
{
Unsafe.CopyBlockUnaligned((void*)ptr, sourcePtr, (uint)source.Length);
}
}
}


[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void CopyFrom(this nint ptr, nint source, int size) {
public static void CopyFrom( this nint ptr, nint source, int size )
{
unsafe { Unsafe.CopyBlockUnaligned((void*)ptr, (void*)source, (uint)size); }
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void CopyFrom(this nint ptr, int offset, nint source, int size) {
public static void CopyFrom( this nint ptr, int offset, nint source, int size )
{
unsafe { Unsafe.CopyBlockUnaligned((void*)(ptr + offset), (void*)source, (uint)size); }
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool IsValidPtr(this nint ptr) {
public static bool IsValidPtr( this nint ptr )
{
return ptr != 0 && ptr != IntPtr.MaxValue;
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static T AsHandle<T>(this nint ptr) where T : INativeHandle, ISchemaClass<T> {
public static T AsHandle<T>( this nint ptr ) where T : INativeHandle, ISchemaClass<T>
{
return T.From(ptr);
}
}
47 changes: 25 additions & 22 deletions managed/src/SwiftlyS2.Core/Modules/Schemas/Schema.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@

namespace SwiftlyS2.Core.Schemas;

internal static class Schema {
internal static class Schema
{
private static readonly HashSet<ulong> dangerousFields = new() {
0x509D90A88DFCB984, // CMaterialAttributeAnimTag.m_flValue
0xCB1D2D708DFCB984, // CNmConstFloatNode__CDefinition.m_flValue
Expand Down Expand Up @@ -46,53 +47,55 @@ internal static class Schema {

private static readonly bool isFollowingServerGuidelines = NativeServerHelpers.IsFollowingServerGuidelines();

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int GetOffset(ulong hash) {
if (isFollowingServerGuidelines && dangerousFields.Contains(hash)) {
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static nint GetOffset( ulong hash )
{
if (isFollowingServerGuidelines && dangerousFields.Contains(hash))
{
throw new InvalidOperationException($"Cannot get or set 0x{hash:X16} while \"FollowCS2ServerGuidelines\" is enabled.\n\tTo use this operation, disable the option in core.jsonc.");
}
return NativeSchema.GetOffset(hash);
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Update(nint handle, ulong hash) {
if (isFollowingServerGuidelines && dangerousFields.Contains(hash)) {
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Update( nint handle, ulong hash )
{
if (isFollowingServerGuidelines && dangerousFields.Contains(hash))
{
throw new InvalidOperationException($"Cannot get or set 0x{hash:X16} while \"FollowCS2ServerGuidelines\" is enabled.\n\tTo use this operation, disable the option in core.jsonc.");
}
NativeSchema.SetStateChanged(handle, hash);
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void SetString(nint handle, ulong hash, string value) {
if (isFollowingServerGuidelines && dangerousFields.Contains(hash)) {
throw new InvalidOperationException($"Cannot get or set 0x{hash:X16} while \"FollowCS2ServerGuidelines\" is enabled.\n\tTo use this operation, disable the option in core.jsonc.");
}
(handle + GetOffset(hash)).Write(StringPool.Allocate(value));
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void SetString( nint handle, nint offset, string value )
{
handle.Write(offset, StringPool.Allocate(value));
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void SetFixedString(nint handle, ulong hash, string value, int maxSize) {
if (isFollowingServerGuidelines && dangerousFields.Contains(hash)) {
throw new InvalidOperationException($"Cannot get or set 0x{hash:X16} while \"FollowCS2ServerGuidelines\" is enabled.\n\tTo use this operation, disable the option in core.jsonc.");
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void SetFixedString( nint handle, nint offset, string value, int maxSize )
{
var pool = ArrayPool<byte>.Shared;
var size = Encoding.UTF8.GetByteCount(value);
if (size + 1 > maxSize) {
if (size + 1 > maxSize)
{
throw new ArgumentException("Value is too long. Max size is " + maxSize);
}
var bytes = pool.Rent(size + 1);
Encoding.UTF8.GetBytes(value, bytes);
bytes[size] = 0;
Unsafe.CopyBlockUnaligned(
ref (handle + GetOffset(hash)).AsRef<byte>(),
ref handle.AsRef<byte>(offset),
ref bytes[0],
(uint)(size + 1)
);
pool.Return(bytes);
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static string GetString(nint handle) {
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static string GetString( nint handle )
{
return Marshal.PtrToStringUTF8(handle) ?? string.Empty;
}

Expand Down
2 changes: 1 addition & 1 deletion managed/src/SwiftlyS2.Core/Modules/Schemas/SchemaField.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ namespace SwiftlyS2.Core.Schemas;

internal abstract class SchemaField : NativeHandle, ISchemaField {

public int FieldOffset { get; set; }
public nint FieldOffset { get; set; }

private ulong _hash { get; set; } = 0;

Expand Down
10 changes: 8 additions & 2 deletions managed/src/SwiftlyS2.Generated/Schemas/Classes/AABB_tImpl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
#pragma warning disable CS0108
#nullable enable

using System;
using System.Threading;
using SwiftlyS2.Core.Schemas;
using SwiftlyS2.Shared.Schemas;
using SwiftlyS2.Shared.SchemaDefinitions;
Expand All @@ -15,11 +17,15 @@ internal partial class AABB_tImpl : SchemaClass, AABB_t {
public AABB_tImpl(nint handle) : base(handle) {
}

private static readonly Lazy<nint> _MinBoundsOffset = new(() => Schema.GetOffset(0xC0D32A84114799FE), LazyThreadSafetyMode.None);

public ref Vector MinBounds {
get => ref _Handle.AsRef<Vector>(Schema.GetOffset(0xC0D32A84114799FE));
get => ref _Handle.AsRef<Vector>(_MinBoundsOffset.Value);
}
private static readonly Lazy<nint> _MaxBoundsOffset = new(() => Schema.GetOffset(0xC0D32A84C0B4CE60), LazyThreadSafetyMode.None);

public ref Vector MaxBounds {
get => ref _Handle.AsRef<Vector>(Schema.GetOffset(0xC0D32A84C0B4CE60));
get => ref _Handle.AsRef<Vector>(_MaxBoundsOffset.Value);
}

public void MinBoundsUpdated() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
#pragma warning disable CS0108
#nullable enable

using System;
using System.Threading;
using SwiftlyS2.Core.Schemas;
using SwiftlyS2.Shared.Schemas;
using SwiftlyS2.Shared.SchemaDefinitions;
Expand All @@ -15,21 +17,29 @@ internal partial class ActiveModelConfig_tImpl : SchemaClass, ActiveModelConfig_
public ActiveModelConfig_tImpl(nint handle) : base(handle) {
}

private static readonly Lazy<nint> _HandleOffset = new(() => Schema.GetOffset(0x554D81919D208453), LazyThreadSafetyMode.None);

public ModelConfigHandle_t Handle {
get => new ModelConfigHandle_tImpl(_Handle + Schema.GetOffset(0x554D81919D208453));
get => new ModelConfigHandle_tImpl(_Handle + _HandleOffset.Value);
}
private static readonly Lazy<nint> _NameOffset = new(() => Schema.GetOffset(0x554D8191CAE8A266), LazyThreadSafetyMode.None);

public string Name {
get {
var ptr = _Handle.Read<nint>(Schema.GetOffset(0x554D8191CAE8A266));
var ptr = _Handle.Read<nint>(_NameOffset.Value);
return Schema.GetString(ptr);
}
set => Schema.SetString(_Handle, 0x554D8191CAE8A266, value);
set => Schema.SetString(_Handle, _NameOffset.Value, value);
}
private static readonly Lazy<nint> _AssociatedEntitiesOffset = new(() => Schema.GetOffset(0x554D8191D6EB4F18), LazyThreadSafetyMode.None);

public ref CUtlVector<CHandle<CBaseModelEntity>> AssociatedEntities {
get => ref _Handle.AsRef<CUtlVector<CHandle<CBaseModelEntity>>>(Schema.GetOffset(0x554D8191D6EB4F18));
get => ref _Handle.AsRef<CUtlVector<CHandle<CBaseModelEntity>>>(_AssociatedEntitiesOffset.Value);
}
private static readonly Lazy<nint> _AssociatedEntityNamesOffset = new(() => Schema.GetOffset(0x554D8191EB3B241C), LazyThreadSafetyMode.None);

public ref CUtlVector<SchemaUntypedField> AssociatedEntityNames {
get => ref _Handle.AsRef<CUtlVector<SchemaUntypedField>>(Schema.GetOffset(0x554D8191EB3B241C));
get => ref _Handle.AsRef<CUtlVector<SchemaUntypedField>>(_AssociatedEntityNamesOffset.Value);
}

public void HandleUpdated() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
#pragma warning disable CS0108
#nullable enable

using System;
using System.Threading;
using SwiftlyS2.Core.Schemas;
using SwiftlyS2.Shared.Schemas;
using SwiftlyS2.Shared.SchemaDefinitions;
Expand All @@ -15,11 +17,15 @@ internal partial class AggregateInstanceStreamOnDiskData_tImpl : SchemaClass, Ag
public AggregateInstanceStreamOnDiskData_tImpl(nint handle) : base(handle) {
}

private static readonly Lazy<nint> _DecodedSizeOffset = new(() => Schema.GetOffset(0x8EDB1298803205A0), LazyThreadSafetyMode.None);

public ref uint DecodedSize {
get => ref _Handle.AsRef<uint>(Schema.GetOffset(0x8EDB1298803205A0));
get => ref _Handle.AsRef<uint>(_DecodedSizeOffset.Value);
}
private static readonly Lazy<nint> _BufferDataOffset = new(() => Schema.GetOffset(0x8EDB1298ED884C43), LazyThreadSafetyMode.None);

public ref CUtlBinaryBlock BufferData {
get => ref _Handle.AsRef<CUtlBinaryBlock>(Schema.GetOffset(0x8EDB1298ED884C43));
get => ref _Handle.AsRef<CUtlBinaryBlock>(_BufferDataOffset.Value);
}


Expand Down
Loading
Loading