Skip to content

Commit eb1e8c5

Browse files
authored
Fix compatibility with older demos (#159)
Closes #157, #158
1 parent 2eb2f30 commit eb1e8c5

File tree

7 files changed

+99
-3
lines changed

7 files changed

+99
-3
lines changed

RELEASE_NOTES.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
### 0.40.1 (2025-12-20)
2+
3+
- Fix compatibility with older CS2 demos after recent game updates
4+
15
### 0.39.1 (2025-12-16)
26

37
- Update to latest Deadlock schema

src/DemoFile.Game.Cs/CsDecoderSet.cs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,30 @@ public override bool TryCreateFallbackDecoder(
5454
};
5555
return true;
5656
}
57+
if (field.VarName == "m_vecNetworkableLoadout")
58+
{
59+
var dummyLoadout = new NetworkedVector<CSNetworkableLoadout>();
60+
var innerDecoder = decoderSet.GetDecoder<CSNetworkableLoadout>(field.FieldSerializerKey!.Value);
61+
decoder = (object @this, ReadOnlySpan<int> path, ref BitBuffer buffer) =>
62+
{
63+
//@this = CCSPlayerController_InventoryServices
64+
65+
if (path.Length == 1)
66+
{
67+
var newSize = (int)buffer.ReadUVarInt32();
68+
dummyLoadout.Resize(newSize);
69+
}
70+
else
71+
{
72+
Debug.Assert(path.Length > 2);
73+
var index = path[1];
74+
dummyLoadout.EnsureSize(index + 1);
75+
var element = dummyLoadout[index] ??= new CSNetworkableLoadout();
76+
innerDecoder(element, path[2..], ref buffer);
77+
}
78+
};
79+
return true;
80+
}
5781

5882
if (FallbackDecoder.TryCreate(field.VarName, field.VarType, field.FieldEncodingInfo, decoderSet, out var engineFallbackDecoder))
5983
{
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
using DemoFile.Sdk;
2+
3+
namespace DemoFile.Game.Cs;
4+
5+
public class CSNetworkableLoadout
6+
{
7+
public CEconItemView Item { get; private set; } = new();
8+
9+
public UInt16 Team { get; private set; }
10+
11+
public UInt16 Slot { get; private set; }
12+
13+
internal static SendNodeDecoder<CSNetworkableLoadout> CreateFieldDecoder(SerializableField field, DecoderSet decoderSet)
14+
{
15+
if (field.SendNode.Length >= 1 && field.SendNode.Span[0] == "m_Item")
16+
{
17+
var innerDecoder = CEconItemView.CreateFieldDecoder(field with {SendNode = field.SendNode[1..]}, decoderSet);
18+
return (CSNetworkableLoadout @this, ReadOnlySpan<int> path, ref BitBuffer buffer) =>
19+
{
20+
innerDecoder(@this.Item, path, ref buffer);
21+
};
22+
}
23+
if (field.VarName == "m_unTeam")
24+
{
25+
var decoder = FieldDecode.CreateDecoder_UInt16(field.FieldEncodingInfo);
26+
return (CSNetworkableLoadout @this, ReadOnlySpan<int> path, ref BitBuffer buffer) =>
27+
{
28+
@this.Team = decoder(ref buffer);
29+
};
30+
}
31+
if (field.VarName == "m_unSlot")
32+
{
33+
var decoder = FieldDecode.CreateDecoder_UInt16(field.FieldEncodingInfo);
34+
return (CSNetworkableLoadout @this, ReadOnlySpan<int> path, ref BitBuffer buffer) =>
35+
{
36+
@this.Slot = decoder(ref buffer);
37+
};
38+
}
39+
if (decoderSet.TryCreateFallbackDecoder(field, decoderSet, out var fallback))
40+
{
41+
return (CSNetworkableLoadout @this, ReadOnlySpan<int> path, ref BitBuffer buffer) =>
42+
{
43+
#if DEBUG
44+
var _field = field;
45+
#endif
46+
fallback(@this, path, ref buffer);
47+
};
48+
}
49+
throw new NotSupportedException($"Unrecognised serializer field: {field}");
50+
}
51+
}

src/DemoFile.Game.Cs/Sdk/Schema.cs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28587,6 +28587,18 @@ public override bool TryGetDecoderByName(string className, [DynamicallyAccessedM
2858728587
};
2858828588
return true;
2858928589
}
28590+
case "CSNetworkableLoadout_t":
28591+
{
28592+
var innerDecoder = GetDecoder<CSNetworkableLoadout>(new SerializerKey(className, 0));
28593+
classType = typeof(CSNetworkableLoadout);
28594+
decoder = (object instance, ReadOnlySpan<int> path, ref BitBuffer buffer) =>
28595+
{
28596+
Debug.Assert(instance is CSNetworkableLoadout);
28597+
var @this = Unsafe.As<CSNetworkableLoadout>(instance);
28598+
innerDecoder(@this, path, ref buffer);
28599+
};
28600+
return true;
28601+
}
2859028602
case "CBaseViewModel":
2859128603
{
2859228604
var innerDecoder = GetDecoder<CBaseViewModel>(new SerializerKey(className, 0));
@@ -33448,6 +33460,10 @@ protected override SendNodeDecoderFactory<T> GetFactory<T>()
3344833460
{
3344933461
return (SendNodeDecoderFactory<T>)(object)new SendNodeDecoderFactory<CSmokeGrenadeProjectile>(CSmokeGrenadeProjectile.CreateFieldDecoder);
3345033462
}
33463+
if (typeof(T) == typeof(CSNetworkableLoadout))
33464+
{
33465+
return (SendNodeDecoderFactory<T>)(object)new SendNodeDecoderFactory<CSNetworkableLoadout>(CSNetworkableLoadout.CreateFieldDecoder);
33466+
}
3345133467
if (typeof(T) == typeof(CSoundAreaEntityBase))
3345233468
{
3345333469
return (SendNodeDecoderFactory<T>)(object)new SendNodeDecoderFactory<CSoundAreaEntityBase>(CSoundAreaEntityBase.CreateFieldDecoder);

src/DemoFile.SdkGen/GameSdkInfo.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ public GameSdkInfo(string gameName)
3535
"CCSObserver_ViewModelServices",
3636
"CCSPlayer_ViewModelServices",
3737
"CPlayer_ViewModelServices",
38+
"CSNetworkableLoadout_t"
3839
}.ToImmutableArray();
3940
}
4041
}

src/DemoFile/FallbackDecoder.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ public static bool TryCreate(
8383

8484
switch (fieldType.Name)
8585
{
86-
case "Vector":
86+
case "Vector" or "VectorWS":
8787
{
8888
var fieldDecoder = FieldDecode.CreateDecoder_Vector(encodingInfo);
8989
decoder = (Unit _, ReadOnlySpan<int> path, ref BitBuffer buffer) =>
@@ -131,7 +131,7 @@ public static bool TryCreate(
131131
fieldDecoder(ref buffer);
132132
return true;
133133
}
134-
case "uint8" or "int8" or "int16" or "uint16" or "int32" or "uint32" or "int64" or "uint64" or "CStrongHandle" or "CEntityHandle" or "CHandle" or "HSequence" or "CSPlayerBlockingUseAction_t" or "BloodType" or "CGameSceneNodeHandle" or "ShatterPanelMode" or "CSWeaponState_t" or "WorldGroupId_t":
134+
case "uint8" or "int8" or "int16" or "uint16" or "int32" or "uint32" or "int64" or "uint64" or "CStrongHandle" or "CEntityHandle" or "CHandle" or "HSequence" or "CSPlayerBlockingUseAction_t" or "BloodType" or "CGameSceneNodeHandle" or "ShatterPanelMode" or "CSWeaponState_t" or "WorldGroupId_t" or "attributeprovidertypes_t":
135135
{
136136
decoder = (Unit _, ReadOnlySpan<int> path, ref BitBuffer buffer) =>
137137
buffer.ReadUVarInt64();

version.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json",
3-
"version": "0.39.1",
3+
"version": "0.40.1",
44
"publicReleaseRefSpec": [
55
"^refs/heads/main",
66
"^refs/heads/v\\d+(?:\\.\\d+)?$"

0 commit comments

Comments
 (0)