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
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 50 additions & 2 deletions generator/schema_generator/generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,41 @@
"SchemaFixedString"
]

dangerous_fields = [
"m_bIsValveDS",
"m_bIsQuestEligible",
"m_iEntityLevel",
"m_iItemIDHigh",
"m_iItemIDLow",
"m_iAccountID",
"m_iEntityQuality",
"m_bInitialized",
"m_szCustomName",
"m_iAttributeDefinitionIndex",
"m_iRawValue32",
"m_iRawInitialValue32",
"m_flValue",
"m_flInitialValue",
"m_bSetBonus",
"m_nRefundableCurrency",
"m_OriginalOwnerXuidLow",
"m_OriginalOwnerXuidHigh",
"m_nFallbackPaintKit",
"m_nFallbackSeed",
"m_flFallbackWear",
"m_nFallbackStatTrak",
"m_iCompetitiveWins",
"m_iCompetitiveRanking",
"m_iCompetitiveRankType",
"m_iCompetitiveRankingPredicted_Win",
"m_iCompetitiveRankingPredicted_Loss",
"m_iCompetitiveRankingPredicted_Tie",
"m_nActiveCoinRank",
"m_nMusicID"
]

found_dangerous_fields = []

def render_template(template, params):
for param, value in params.items():
template = template.replace(f"${param}$", str(value))
Expand Down Expand Up @@ -89,6 +124,12 @@ def write_class(self):
names.append(field_info["NAME"])

field_info["REF_METHOD"] = "Deref" if field_info["KIND"] == "ptr" else "AsRef"
if field["name"] in dangerous_fields:
found_dangerous_fields.append({
"class": self.class_name,
"field": field["name"],
"hash": field_info["HASH"]
})

if field_info["IS_NETWORKED"] == "true":
updators.append(render_template(self.class_updator_template, field_info))
Expand Down Expand Up @@ -199,7 +240,7 @@ def write_enum(self):
for field in self.class_def["fields"]:
value = field["value"] if field["value"] != -1 else f"{type}.MaxValue"
value = value if value != -2 else f"{type}.MaxValue - 1"
fields.append(f" {field["name"]} = {value},")
fields.append(f" {field['name']} = {value},")

params = {
"ENUM_NAME": self.class_name,
Expand Down Expand Up @@ -229,4 +270,11 @@ def write_enum(self):
continue

writer = Writer(enum_def, all_class_names, all_enum_names)
writer.write_enum()
writer.write_enum()

if found_dangerous_fields:
print("\n")
print(" private static readonly HashSet<ulong> dangerousFields = new() {")
for item in found_dangerous_fields:
print(f" {item['hash']}, // {item['class']}.{item['field']}")
print(" };")
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
public $INTERFACE_TYPE$ $NAME$ {
public $INTERFACE_TYPE$ $NAME$ {
get => new $IMPL_TYPE$(_Handle, $HASH$, $ELEMENT_COUNT$, $ELEMENT_SIZE$, $ELEMENT_ALIGNMENT$);
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
public string $NAME$ {
public string $NAME$ {
get {
var ptr = _Handle + Schema.GetOffset($HASH$);
return Schema.GetString(ptr);
Expand Down
49 changes: 49 additions & 0 deletions managed/src/SwiftlyS2.Core/Modules/Schemas/Schema.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,73 @@
namespace SwiftlyS2.Core.Schemas;

internal static class Schema {
private static readonly HashSet<ulong> dangerousFields = new() {
0x509D90A88DFCB984, // CMaterialAttributeAnimTag.m_flValue
0xCB1D2D708DFCB984, // CNmConstFloatNode__CDefinition.m_flValue
0xB6A452E28DFCB984, // MaterialParamFloat_t.m_flValue
0x37D4D7108DFCB984, // CAudioEmphasisSample.m_flValue
0xF12966B68DFCB984, // NmPercent_t.m_flValue
0x5EC3BE448DFCB984, // CSeqPoseSetting.m_flValue
0xF4BEF78E8DFCB984, // ConstantInfo_t.m_flValue
0x6295CF65B14BF634, // CCSGameRules.m_bIsValveDS
0x6295CF65814483B8, // CCSGameRules.m_bIsQuestEligible
0xBB0F80FC8DAFCD73, // CEconItemAttribute.m_iAttributeDefinitionIndex
0xBB0F80FC8DFCB984, // CEconItemAttribute.m_flValue
0xBB0F80FCE2DBFFF2, // CEconItemAttribute.m_flInitialValue
0xBB0F80FC1021E694, // CEconItemAttribute.m_nRefundableCurrency
0xBB0F80FCA5E9EA96, // CEconItemAttribute.m_bSetBonus
0x28ECD7A1D82CC087, // CCSPlayerController.m_iCompetitiveRanking
0x28ECD7A192776C10, // CCSPlayerController.m_iCompetitiveWins
0x28ECD7A15803DF71, // CCSPlayerController.m_iCompetitiveRankType
0x28ECD7A1C32AD2BC, // CCSPlayerController.m_iCompetitiveRankingPredicted_Win
0x28ECD7A1BDCCE5ED, // CCSPlayerController.m_iCompetitiveRankingPredicted_Loss
0x28ECD7A138CA4C74, // CCSPlayerController.m_iCompetitiveRankingPredicted_Tie
0xE1A93F256A67D4C4, // CEconItemView.m_iEntityQuality
0xE1A93F2555EF3B5F, // CEconItemView.m_iEntityLevel
0xE1A93F25373EE446, // CEconItemView.m_iItemIDHigh
0xE1A93F250DF29C2C, // CEconItemView.m_iItemIDLow
0xE1A93F25C65DE986, // CEconItemView.m_iAccountID
0xE1A93F250710ABDD, // CEconItemView.m_bInitialized
0xE1A93F25AFD12EE8, // CEconItemView.m_szCustomName
0xCD91F6843C990CE3, // CEconEntity.m_OriginalOwnerXuidLow
0xCD91F6842628947F, // CEconEntity.m_OriginalOwnerXuidHigh
0xCD91F6840A12D48F, // CEconEntity.m_nFallbackPaintKit
0xCD91F684A1B165B2, // CEconEntity.m_nFallbackSeed
0xCD91F68486253266, // CEconEntity.m_flFallbackWear
0xCD91F68467ECC1E7, // CEconEntity.m_nFallbackStatTrak
};

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

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int 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)) {
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 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.");
}
var pool = ArrayPool<byte>.Shared;
var size = Encoding.UTF8.GetByteCount(value);
if (size + 1 > maxSize) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,16 @@ internal partial class CAnimAttachmentImpl : SchemaClass, CAnimAttachment {
public CAnimAttachmentImpl(nint handle) : base(handle) {
}

public ISchemaFixedArray<Quaternion> InfluenceRotations {
public ISchemaFixedArray<Quaternion> InfluenceRotations {
get => new SchemaFixedArray<Quaternion>(_Handle, 0xCF918186B393B857, 3, 16, 16);
}
public ISchemaFixedArray<Vector> InfluenceOffsets {
public ISchemaFixedArray<Vector> InfluenceOffsets {
get => new SchemaFixedArray<Vector>(_Handle, 0xCF918186E75BDA68, 3, 16, 16);
}
public ISchemaFixedArray<int> InfluenceIndices {
public ISchemaFixedArray<int> InfluenceIndices {
get => new SchemaFixedArray<int>(_Handle, 0xCF9181862FA09BA5, 3, 4, 4);
}
public ISchemaFixedArray<float> InfluenceWeights {
public ISchemaFixedArray<float> InfluenceWeights {
get => new SchemaFixedArray<float>(_Handle, 0xCF91818649916951, 3, 4, 4);
}
public ref byte NumInfluences {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,16 +29,16 @@ public string InfluenceNames {
}
set => Schema.SetString(_Handle, 0x5F09808FFD9B3CB8, value);
}
public ISchemaFixedArray<Quaternion> InfluenceRotations {
public ISchemaFixedArray<Quaternion> InfluenceRotations {
get => new SchemaFixedArray<Quaternion>(_Handle, 0x5F09808FD277168B, 3, 16, 16);
}
public ISchemaFixedArray<Vector> InfluenceOffsets {
public ISchemaFixedArray<Vector> InfluenceOffsets {
get => new SchemaFixedArray<Vector>(_Handle, 0x5F09808F767C44DC, 3, 12, 4);
}
public ISchemaFixedArray<float> InfluenceWeights {
public ISchemaFixedArray<float> InfluenceWeights {
get => new SchemaFixedArray<float>(_Handle, 0x5F09808F49916951, 3, 4, 4);
}
public ISchemaFixedArray<bool> InfluenceRootTransform {
public ISchemaFixedArray<bool> InfluenceRootTransform {
get => new SchemaFixedArray<bool>(_Handle, 0x5F09808F5763011C, 3, 1, 1);
}
public ref byte Influences {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,14 @@ internal partial class CBaseIssueImpl : SchemaClass, CBaseIssue {
public CBaseIssueImpl(nint handle) : base(handle) {
}

public string TypeString {
public string TypeString {
get {
var ptr = _Handle + Schema.GetOffset(0xE0727D1E2E3EE7A9);
return Schema.GetString(ptr);
}
set => Schema.SetFixedString(_Handle, 0xE0727D1E2E3EE7A9, value, 64);
}
public string DetailsString {
public string DetailsString {
get {
var ptr = _Handle + Schema.GetOffset(0xE0727D1ECCE4C9BF);
return Schema.GetString(ptr);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ public ref CUtlVector<CHandle<CBaseModelEntity>> ConfigEntitiesToPropagateMateri
public CNetworkViewOffsetVector ViewOffset {
get => new CNetworkViewOffsetVectorImpl(_Handle + Schema.GetOffset(0x517849F739DB834B));
}
public ISchemaFixedArray<uint> DisabledHitGroups {
public ISchemaFixedArray<uint> DisabledHitGroups {
get => new SchemaFixedArray<uint>(_Handle, 0x517849F7DDB01736, 1, 4, 4);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public ref bool IsHLTV {
public ref PlayerConnectedState Connected {
get => ref _Handle.AsRef<PlayerConnectedState>(Schema.GetOffset(0x3979FF6E97963D8B));
}
public string PlayerName {
public string PlayerName {
get {
var ptr = _Handle + Schema.GetOffset(0x3979FF6EDE61DD3B);
return Schema.GetString(ptr);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public ref int Clip1 {
public ref int Clip2 {
get => ref _Handle.AsRef<int>(Schema.GetOffset(0x4174B75ECD2504B0));
}
public ISchemaFixedArray<int> ReserveAmmo {
public ISchemaFixedArray<int> ReserveAmmo {
get => new SchemaFixedArray<int>(_Handle, 0x4174B75EB3FEBB0B, 2, 4, 4);
}
public CEntityIOOutput OnPlayerUse {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ public ref bool UseMixedResolutionRendering {
public ref bool OnlyRenderInEffecsGameOverlay {
get => ref _Handle.AsRef<bool>(Schema.GetOffset(0xA732A5750293C80E));
}
public string StencilTestID {
public string StencilTestID {
get {
var ptr = _Handle + Schema.GetOffset(0xA732A575115C996A);
return Schema.GetString(ptr);
Expand All @@ -176,7 +176,7 @@ public string StencilTestID {
public ref bool StencilTestExclude {
get => ref _Handle.AsRef<bool>(Schema.GetOffset(0xA732A57584BFB66B));
}
public string StencilWriteID {
public string StencilWriteID {
get {
var ptr = _Handle + Schema.GetOffset(0xA732A5758FB6505B);
return Schema.GetString(ptr);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public ref BeamType_t BeamType {
public ref uint BeamFlags {
get => ref _Handle.AsRef<uint>(Schema.GetOffset(0x4BCF3CE5BB875091));
}
public ISchemaFixedArray<CHandle<CBaseEntity>> AttachEntity {
public ISchemaFixedArray<CHandle<CBaseEntity>> AttachEntity {
get => new SchemaFixedArray<CHandle<CBaseEntity>>(_Handle, 0x4BCF3CE56BCDCAD1, 10, 4, 4);
}
public SchemaUntypedField AttachIndex {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public string MorphChannelName {
}
set => Schema.SetString(_Handle, 0x75939F0777272AE4, value);
}
public ISchemaFixedArray<float> Remap {
public ISchemaFixedArray<float> Remap {
get => new SchemaFixedArray<float>(_Handle, 0x75939F07BE3DB1A0, 4, 4, 4);
}

Expand Down
2 changes: 1 addition & 1 deletion managed/src/SwiftlyS2.Generated/Schemas/Classes/CC4Impl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public EntitySpottedState_t EntitySpottedState {
public ref int SpotRules {
get => ref _Handle.AsRef<int>(Schema.GetOffset(0x1D49B0B5776CCE44));
}
public ISchemaFixedArray<bool> PlayedArmingBeeps {
public ISchemaFixedArray<bool> PlayedArmingBeeps {
get => new SchemaFixedArray<bool>(_Handle, 0x1D49B0B525D5D369, 7, 1, 1);
}
public ref bool BombPlanted {
Expand Down
6 changes: 3 additions & 3 deletions managed/src/SwiftlyS2.Generated/Schemas/Classes/CCSBotImpl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public CCSBotImpl(nint handle) : base(handle) {
public ref Vector EyePosition {
get => ref _Handle.AsRef<Vector>(Schema.GetOffset(0x1CFE165D847A3605));
}
public string Name {
public string Name {
get {
var ptr = _Handle + Schema.GetOffset(0x1CFE165D4D8F5786);
return Schema.GetString(ptr);
Expand Down Expand Up @@ -145,7 +145,7 @@ public CountdownTimer WaitTimer {
public CountdownTimer UpdateTravelDistanceTimer {
get => new CountdownTimerImpl(_Handle + Schema.GetOffset(0x1CFE165D67E5EA78));
}
public ISchemaFixedArray<float> PlayerTravelDistance {
public ISchemaFixedArray<float> PlayerTravelDistance {
get => new SchemaFixedArray<float>(_Handle, 0x1CFE165DA4B8EEEF, 64, 4, 4);
}
public ref byte TravelDistancePhase {
Expand Down Expand Up @@ -413,7 +413,7 @@ public CountdownTimer StuckJumpTimer {
public GameTime_t NextCleanupCheckTimestamp {
get => new GameTime_tImpl(_Handle + Schema.GetOffset(0x1CFE165DB61EB6BC));
}
public ISchemaFixedArray<float> AvgVel {
public ISchemaFixedArray<float> AvgVel {
get => new SchemaFixedArray<float>(_Handle, 0x1CFE165D99077BFE, 10, 4, 4);
}
public ref int AvgVelIndex {
Expand Down
Loading