mirror of
https://github.com/roflmuffin/CounterStrikeSharp.git
synced 2025-12-07 08:26:34 -08:00
Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cef9758c12 | ||
|
|
0dc35818dd | ||
|
|
a0f9d30753 | ||
|
|
d6fe9e10e1 |
@@ -77,6 +77,7 @@ SET(SOURCE_FILES
|
||||
src/core/managers/server_manager.cpp
|
||||
src/core/managers/server_manager.h
|
||||
src/scripting/natives/natives_server.cpp
|
||||
libraries/nlohmann/json.hpp
|
||||
)
|
||||
|
||||
set(PROTO_DIRS -I${CMAKE_CURRENT_SOURCE_DIR}/libraries/GameTracking-CS2/Protobufs)
|
||||
|
||||
1920
configs/schema_classes.txt
Normal file
1920
configs/schema_classes.txt
Normal file
File diff suppressed because it is too large
Load Diff
305
configs/schema_enums.txt
Normal file
305
configs/schema_enums.txt
Normal file
@@ -0,0 +1,305 @@
|
||||
ActionType_t
|
||||
AimMatrixBlendMode
|
||||
AmmoFlags_t
|
||||
AmmoPosition_t
|
||||
AnimLoopMode_t
|
||||
AnimNodeNetworkMode
|
||||
AnimParamButton_t
|
||||
AnimParamNetworkSetting
|
||||
AnimParamType_t
|
||||
AnimPoseControl
|
||||
AnimScriptType
|
||||
AnimVRFinger_t
|
||||
AnimVRHandMotionRange_t
|
||||
AnimVRHand_t
|
||||
AnimValueSource
|
||||
AnimVectorSource
|
||||
AnimVrBoneTransformSource_t
|
||||
AnimVrFingerSplay_t
|
||||
AnimationProcessingType_t
|
||||
AnimationSnapshotType_t
|
||||
AnimationType_t
|
||||
BBoxVolumeType_t
|
||||
BaseExplosionTypes_t
|
||||
BeamClipStyle_t
|
||||
BeamType_t
|
||||
BeginDeathLifeStateTransition_t
|
||||
BinaryNodeChildOption
|
||||
BinaryNodeTiming
|
||||
Blend2DMode
|
||||
BlendKeyType
|
||||
BloomBlendMode_t
|
||||
BlurFilterType_t
|
||||
BoneMaskBlendSpace
|
||||
BoneTransformSpace_t
|
||||
BrushSolidities_e
|
||||
CAnimationGraphVisualizerPrimitiveType
|
||||
CLogicBranchList__LogicBranchListenerLastState_t
|
||||
CRR_Response__ResponseEnum_t
|
||||
CSPlayerBlockingUseAction_t
|
||||
CSPlayerState
|
||||
CSWeaponCategory
|
||||
CSWeaponMode
|
||||
CSWeaponSilencerType
|
||||
CSWeaponState_t
|
||||
CSWeaponType
|
||||
CanPlaySequence_t
|
||||
ChatIgnoreType_t
|
||||
ChickenActivity
|
||||
ChoiceBlendMethod
|
||||
ChoiceChangeMethod
|
||||
ChoiceMethod
|
||||
Class_T
|
||||
ClosestPointTestType_t
|
||||
CommandEntitySpecType_t
|
||||
CommandExecMode_t
|
||||
CompMatPropertyMutatorConditionType_t
|
||||
CompMatPropertyMutatorType_t
|
||||
CompositeMaterialInputContainerSourceType_t
|
||||
CompositeMaterialInputLooseVariableType_t
|
||||
CompositeMaterialInputTextureType_t
|
||||
CompositeMaterialMatchFilterType_t
|
||||
CompositeMaterialVarSystemVar_t
|
||||
DamageTypes_t
|
||||
DampingSpeedFunction
|
||||
DebugOverlayBits_t
|
||||
Detail2Combo_t
|
||||
DetailCombo_t
|
||||
DisableShadows_t
|
||||
Disposition_t
|
||||
DoorState_t
|
||||
EDemoBoneSelectionMode
|
||||
EGrenadeThrowState
|
||||
EInButtonState
|
||||
EKillTypes_t
|
||||
ELayoutNodeType
|
||||
EOverrideBlockLOS_t
|
||||
EStyleNodeType
|
||||
EntFinderMethod_t
|
||||
EntityDisolveType_t
|
||||
EntityDormancyType_t
|
||||
EntityIOTargetType_t
|
||||
EntitySubclassScope_t
|
||||
Explosions
|
||||
FacingMode
|
||||
FieldNetworkOption
|
||||
FixAngleSet_t
|
||||
FlexOpCode_t
|
||||
FootFallTagFoot_t
|
||||
FootLockSubVisualization
|
||||
FootPinningTimingSource
|
||||
FootstepLandedFootSoundType_t
|
||||
ForcedCrouchState_t
|
||||
FuncDoorSpawnPos_t
|
||||
FuseVariableAccess_t
|
||||
FuseVariableType_t
|
||||
GameAnimEventIndex_t
|
||||
GrenadeType_t
|
||||
HierarchyType_t
|
||||
HitGroup_t
|
||||
HitboxLerpType_t
|
||||
HorizJustification_e
|
||||
Hull_t
|
||||
IChoreoServices__ChoreoState_t
|
||||
IChoreoServices__ScriptState_t
|
||||
IKChannelMode
|
||||
IKSolverType
|
||||
IKTargetCoordinateSystem
|
||||
IKTargetSource
|
||||
IkEndEffectorType
|
||||
IkTargetType
|
||||
InheritableBoolType_t
|
||||
InputBitMask_t
|
||||
InputLayoutVariation_t
|
||||
ItemFlagTypes_t
|
||||
JiggleBoneSimSpace
|
||||
JointAxis_t
|
||||
JointMotion_t
|
||||
JumpCorrectionMethod
|
||||
LatchDirtyPermission_t
|
||||
LayoutPositionType_e
|
||||
LessonPanelLayoutFileTypes_t
|
||||
LifeState_t
|
||||
MaterialProxyType_t
|
||||
Materials
|
||||
MatterialAttributeTagType_t
|
||||
MedalRank_t
|
||||
MeshDrawPrimitiveFlags_t
|
||||
MissingParentInheritBehavior_t
|
||||
ModelBoneFlexComponent_t
|
||||
ModelConfigAttachmentType_t
|
||||
ModelSkeletonData_t__BoneFlags_t
|
||||
ModifyDamageReturn_t
|
||||
MoodType_t
|
||||
MorphBundleType_t
|
||||
MorphFlexControllerRemapType_t
|
||||
MoveCollide_t
|
||||
MoveLinearAuthoredPos_t
|
||||
MoveMountingAmount_t
|
||||
MoveType_t
|
||||
NavAttributeEnum
|
||||
NavDirType
|
||||
ObjectTypeFlags_t
|
||||
ObserverInterpState_t
|
||||
ObserverMode_t
|
||||
OnFrame
|
||||
PFNoiseModifier_t
|
||||
PFNoiseTurbulence_t
|
||||
PFNoiseType_t
|
||||
PFuncVisualizationType_t
|
||||
ParticleAlphaReferenceType_t
|
||||
ParticleAttachment_t
|
||||
ParticleCollisionMode_t
|
||||
ParticleColorBlendMode_t
|
||||
ParticleColorBlendType_t
|
||||
ParticleControlPointAxis_t
|
||||
ParticleDepthFeatheringMode_t
|
||||
ParticleDetailLevel_t
|
||||
ParticleDirectionNoiseType_t
|
||||
ParticleEndcapMode_t
|
||||
ParticleFalloffFunction_t
|
||||
ParticleFloatBiasType_t
|
||||
ParticleFloatInputMode_t
|
||||
ParticleFloatMapType_t
|
||||
ParticleFloatRandomMode_t
|
||||
ParticleFloatType_t
|
||||
ParticleFogType_t
|
||||
ParticleHitboxBiasType_t
|
||||
ParticleHitboxDataSelection_t
|
||||
ParticleImpulseType_t
|
||||
ParticleLightBehaviorChoiceList_t
|
||||
ParticleLightFogLightingMode_t
|
||||
ParticleLightTypeChoiceList_t
|
||||
ParticleLightUnitChoiceList_t
|
||||
ParticleLightingQuality_t
|
||||
ParticleLightnintBranchBehavior_t
|
||||
ParticleModelType_t
|
||||
ParticleOmni2LightTypeChoiceList_t
|
||||
ParticleOrientationChoiceList_t
|
||||
ParticleOrientationSetMode_t
|
||||
ParticleOutputBlendMode_t
|
||||
ParticleParentSetMode_t
|
||||
ParticlePinDistance_t
|
||||
ParticlePostProcessPriorityGroup_t
|
||||
ParticleRotationLockType_t
|
||||
ParticleSelection_t
|
||||
ParticleSequenceCropOverride_t
|
||||
ParticleSetMethod_t
|
||||
ParticleSortingChoiceList_t
|
||||
ParticleTextureLayerBlendType_t
|
||||
ParticleTopology_t
|
||||
ParticleTraceMissBehavior_t
|
||||
ParticleTraceSet_t
|
||||
ParticleTransformType_t
|
||||
ParticleVRHandChoiceList_t
|
||||
ParticleVecType_t
|
||||
PerformanceMode_t
|
||||
PermModelInfo_t__FlagEnum
|
||||
PetGroundType_t
|
||||
PlayerAnimEvent_t
|
||||
PlayerConnectedState
|
||||
PointTemplateClientOnlyEntityBehavior_t
|
||||
PointTemplateOwnerSpawnGroupType_t
|
||||
PointWorldTextJustifyHorizontal_t
|
||||
PointWorldTextJustifyVertical_t
|
||||
PointWorldTextReorientMode_t
|
||||
PoseType_t
|
||||
PropDoorRotatingOpenDirection_e
|
||||
PropDoorRotatingSpawnPos_t
|
||||
PulseInstructionCode_t
|
||||
PulseMethodCallMode_t
|
||||
PulseValueType_t
|
||||
QuestProgress__Reason
|
||||
RagdollPoseControl
|
||||
RenderBufferFlags_t
|
||||
RenderFx_t
|
||||
RenderMode_t
|
||||
RenderMultisampleType_t
|
||||
RenderPrimitiveType_t
|
||||
RenderSlotType_t
|
||||
ResetCycleOption
|
||||
RumbleEffect_t
|
||||
ScalarExpressionType_t
|
||||
SceneOnPlayerDeath_t
|
||||
ScriptedConflictResponse_t
|
||||
ScriptedMoveTo_t
|
||||
ScriptedMoveType_t
|
||||
ScriptedOnDeath_t
|
||||
SelectorTagBehavior_t
|
||||
SeqCmd_t
|
||||
SeqPoseSetting_t
|
||||
ShadowType_t
|
||||
ShakeCommand_t
|
||||
ShardSolid_t
|
||||
ShatterDamageCause
|
||||
ShatterGlassStressType
|
||||
ShatterPanelMode
|
||||
SimpleConstraintSoundProfile__SimpleConstraintsSoundProfileKeypoints_t
|
||||
SolidType_t
|
||||
SolveIKChainAnimNodeDebugSetting
|
||||
SosActionSortType_t
|
||||
SosActionStopType_t
|
||||
SosEditItemType_t
|
||||
SosGroupType_t
|
||||
SoundEventStartType_t
|
||||
SoundFlags_t
|
||||
SpawnDebugOverrideState_t
|
||||
SpawnDebugRestrictionOverrideState_t
|
||||
SpawnPointCoopEnemy__BotDefaultBehavior_t
|
||||
SpriteCardPerParticleScale_t
|
||||
SpriteCardShaderType_t
|
||||
SpriteCardTextureChannel_t
|
||||
SpriteCardTextureType_t
|
||||
StanceOverrideMode
|
||||
StanceType_t
|
||||
StandardLightingAttenuationStyle_t
|
||||
StateActionBehavior
|
||||
StepPhase
|
||||
SubclassVDataChangeType_t
|
||||
SurroundingBoundsType_t
|
||||
TOGGLE_STATE
|
||||
TRAIN_CODE
|
||||
TakeDamageFlags_t
|
||||
TextureRepetitionMode_t
|
||||
ThreeState_t
|
||||
TimelineCompression_t
|
||||
Touch_t
|
||||
TrackOrientationType_t
|
||||
TrainOrientationType_t
|
||||
TrainVelocityType_t
|
||||
VMixChannelOperation_t
|
||||
VMixFilterSlope_t
|
||||
VMixFilterType_t
|
||||
VMixLFOShape_t
|
||||
VMixPannerType_t
|
||||
VMixProcessorType_t
|
||||
VMixSubgraphSwitchInterpolationType_t
|
||||
VPhysXAggregateData_t__VPhysXFlagEnum_t
|
||||
VPhysXBodyPart_t__VPhysXFlagEnum_t
|
||||
VPhysXConstraintParams_t__EnumFlags0_t
|
||||
VPhysXJoint_t__Flags_t
|
||||
ValueRemapperHapticsType_t
|
||||
ValueRemapperInputType_t
|
||||
ValueRemapperMomentumType_t
|
||||
ValueRemapperOutputType_t
|
||||
ValueRemapperRatchetType_t
|
||||
VectorExpressionType_t
|
||||
VectorFloatExpressionType_t
|
||||
VelocityMetricMode
|
||||
VertJustification_e
|
||||
ViewFadeMode_t
|
||||
WaterLevel_t
|
||||
WeaponAttackType_t
|
||||
WeaponSound_t
|
||||
WorldTextPanelHorizontalAlign_t
|
||||
WorldTextPanelOrientation_t
|
||||
WorldTextPanelVerticalAlign_t
|
||||
attributeprovidertypes_t
|
||||
doorCheck_e
|
||||
fieldtype_t
|
||||
filter_t
|
||||
gear_slot_t
|
||||
loadout_slot_t
|
||||
navproperties_t
|
||||
soundlevel_t
|
||||
vote_create_failed_t
|
||||
Submodule libraries/hl2sdk-cs2 updated: f653b1ec62...492b8f9663
24596
libraries/nlohmann/json.hpp
Normal file
24596
libraries/nlohmann/json.hpp
Normal file
File diff suppressed because it is too large
Load Diff
@@ -6,8 +6,6 @@ namespace CounterStrikeSharp.API.Core;
|
||||
|
||||
public partial class CBaseEntity
|
||||
{
|
||||
public Vector AbsVelocity => Schema.GetDeclaredClass<Vector>(this.Handle, "CBaseEntity", "m_vecAbsVelocity");
|
||||
|
||||
public void Teleport(Vector position, QAngle angles, Vector velocity)
|
||||
{
|
||||
VirtualFunction.CreateVoid<IntPtr, IntPtr, IntPtr, IntPtr>(Handle, GameData.GetOffset("CBaseEntity_Teleport"))(
|
||||
@@ -18,10 +16,9 @@ public partial class CBaseEntity
|
||||
/// Shorthand for accessing an entity's CBodyComponent?.SceneNode?.AbsOrigin;
|
||||
/// </summary>
|
||||
public Vector? AbsOrigin => CBodyComponent?.SceneNode?.AbsOrigin;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Shorthand for accessing an entity's CBodyComponent?.SceneNode?.AbsRotation;
|
||||
/// </summary>
|
||||
public QAngle? AbsRotation => CBodyComponent?.SceneNode?.AbsRotation;
|
||||
|
||||
}
|
||||
@@ -38,6 +38,18 @@ public partial class CCSPlayerController
|
||||
{
|
||||
VirtualFunctions.ClientPrint(this.Handle, HudDestination.Center, message, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
public void PrintToCenterHtml(string message)
|
||||
{
|
||||
var @event = new EventShowSurvivalRespawnStatus(true)
|
||||
{
|
||||
LocToken = message,
|
||||
Duration = 5,
|
||||
Userid = this
|
||||
};
|
||||
@event.FireEvent(false);
|
||||
}
|
||||
|
||||
|
||||
public bool IsBot => ((PlayerFlags)Flags).HasFlag(PlayerFlags.FL_FAKECLIENT);
|
||||
|
||||
@@ -49,7 +61,7 @@ public partial class CCSPlayerController
|
||||
{
|
||||
VirtualFunctions.SwitchTeam(this.Handle, (byte)team);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Switches the team of the player, has the same effect as the "jointeam" console command.
|
||||
/// <remarks>
|
||||
@@ -62,4 +74,9 @@ public partial class CCSPlayerController
|
||||
VirtualFunction.CreateVoid<IntPtr, CsTeam>(Handle, GameData.GetOffset("CCSPlayerController_ChangeTeam"))(Handle,
|
||||
team);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the active pawns button state. Will work even if the player is dead or observing.
|
||||
/// </summary>
|
||||
public PlayerButtons Buttons => (PlayerButtons)Pawn.Value.MovementServices!.Buttons.ButtonStates[0];
|
||||
}
|
||||
@@ -51,9 +51,4 @@ public partial class CEntityIdentity
|
||||
{
|
||||
public unsafe CEntityInstance EntityInstance => new(Unsafe.Read<IntPtr>((void*)Handle));
|
||||
public unsafe CHandle<CEntityInstance> EntityHandle => new(Handle + 0x10);
|
||||
public unsafe string DesignerName => Utilities.ReadStringUtf8(Handle + 0x20);
|
||||
public unsafe PointerTo<CEntityIdentity> Prev => new(Handle + 0x58);
|
||||
public unsafe PointerTo<CEntityIdentity> Next => new(Handle + 0x60);
|
||||
public unsafe PointerTo<CEntityIdentity> PrevByClass => new(Handle + 0x68);
|
||||
public unsafe PointerTo<CEntityIdentity> NextByClass => new(Handle + 0x70);
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
using CounterStrikeSharp.API.Modules.Memory;
|
||||
using CounterStrikeSharp.API.Modules.Utils;
|
||||
|
||||
namespace CounterStrikeSharp.API.Core;
|
||||
|
||||
public class CInButtonState : NativeObject
|
||||
{
|
||||
public CInButtonState(IntPtr pointer) : base(pointer)
|
||||
{
|
||||
}
|
||||
|
||||
public unsafe ref PlayerButtons Value =>
|
||||
ref Unsafe.AsRef<PlayerButtons>((void*)(Handle + Schema.GetSchemaOffset("CInButtonState", "m_pButtonStates")));
|
||||
}
|
||||
|
||||
public partial class CPlayer_MovementServices
|
||||
{
|
||||
public CInButtonState ButtonState =>
|
||||
Schema.GetDeclaredClass<CInButtonState>(this.Handle, "CPlayer_MovementServices", "m_nButtons");
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -103,6 +103,7 @@ namespace CounterStrikeSharp.API.Core
|
||||
public void Invoke()
|
||||
{
|
||||
InvokeNativeInternal();
|
||||
GlobalCleanUp();
|
||||
}
|
||||
|
||||
[SecurityCritical]
|
||||
|
||||
@@ -52,7 +52,7 @@ namespace CounterStrikeSharp.API.Modules.Memory
|
||||
{ typeof(string), DataType.DATA_TYPE_STRING },
|
||||
{ typeof(long), DataType.DATA_TYPE_LONG },
|
||||
{ typeof(ulong), DataType.DATA_TYPE_ULONG },
|
||||
{ typeof(short), DataType.DATA_TYPE_VARIANT },
|
||||
{ typeof(short), DataType.DATA_TYPE_SHORT },
|
||||
{ typeof(sbyte), DataType.DATA_TYPE_UCHAR },
|
||||
{ typeof(byte), DataType.DATA_TYPE_CHAR },
|
||||
};
|
||||
|
||||
13
managed/CounterStrikeSharp.API/Modules/Utils/matrix3x4_t.cs
Normal file
13
managed/CounterStrikeSharp.API/Modules/Utils/matrix3x4_t.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace CounterStrikeSharp.API.Modules.Utils;
|
||||
|
||||
public partial class matrix3x4_t : NativeObject
|
||||
{
|
||||
public matrix3x4_t(IntPtr pointer) : base(pointer)
|
||||
{
|
||||
}
|
||||
|
||||
public unsafe ref float this[int row, int column] => ref Unsafe.Add(ref *(float*)Handle, row * 4 + column);
|
||||
}
|
||||
@@ -61,7 +61,7 @@ namespace CounterStrikeSharp.API
|
||||
public static IEnumerable<T> FindAllEntitiesByDesignerName<T>(string designerName) where T : CEntityInstance
|
||||
{
|
||||
var pEntity = new CEntityIdentity(NativeAPI.GetFirstActiveEntity());
|
||||
for (; pEntity.Handle != IntPtr.Zero; pEntity = pEntity.Next.Value)
|
||||
for (; pEntity != null && pEntity.Handle != IntPtr.Zero; pEntity = pEntity.Next)
|
||||
{
|
||||
if (!pEntity.DesignerName.Contains(designerName)) continue;
|
||||
yield return new PointerTo<T>(pEntity.Handle).Value;
|
||||
@@ -79,7 +79,7 @@ namespace CounterStrikeSharp.API
|
||||
{
|
||||
var controller = GetPlayerFromIndex(i);
|
||||
|
||||
if (!controller.IsValid || controller.UserId < 0)
|
||||
if (!controller.IsValid || controller.UserId == -1)
|
||||
continue;
|
||||
|
||||
players.Add(controller);
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
/**
|
||||
* This project has been copied & modified from the demofile-net project under the MIT license.
|
||||
* This project has been copied & modified from the demofile-net project under the MIT license.
|
||||
* See ACKNOWLEDGEMENTS file for more information.
|
||||
* https://github.com/saul/demofile-net
|
||||
*/
|
||||
|
||||
using System.Collections.Immutable;
|
||||
using System.Diagnostics;
|
||||
using System.Text;
|
||||
@@ -20,7 +21,14 @@ internal static partial class Program
|
||||
"GameTick_t",
|
||||
"AttachmentHandle_t",
|
||||
"CGameSceneNodeHandle",
|
||||
"HSequence"
|
||||
"HSequence",
|
||||
"CAttributeManager::cached_attribute_float_t",
|
||||
"QuestProgress::Reason",
|
||||
"IChoreoServices::ScriptState_t",
|
||||
"IChoreoServices::ChoreoState_t",
|
||||
"SpawnPointCoopEnemy::BotDefaultBehavior_t",
|
||||
"CLogicBranchList::LogicBranchListenerLastState_t",
|
||||
"SimpleConstraintSoundProfile::SimpleConstraintsSoundProfileKeypoints_t"
|
||||
};
|
||||
|
||||
public static string SanitiseTypeName(string typeName) => typeName.Replace(":", "");
|
||||
@@ -35,7 +43,7 @@ internal static partial class Program
|
||||
var allEnums = new SortedDictionary<string, SchemaEnum>();
|
||||
var allClasses = new SortedDictionary<string, SchemaClass>();
|
||||
|
||||
var schemaFiles = new[] { "server.json", "!GlobalTypes.json" };
|
||||
var schemaFiles = new[] { "server.json" };
|
||||
|
||||
foreach (var schemaFile in schemaFiles)
|
||||
{
|
||||
@@ -200,28 +208,20 @@ internal static partial class Program
|
||||
|
||||
foreach (var field in schemaClass.Fields)
|
||||
{
|
||||
var defaultValue = field.Type.Category switch
|
||||
// Putting these in the too hard basket for now.
|
||||
if (field.Name == "m_VoteOptions" || field.Type.Name.Contains("CEntityOutputTemplate") ||
|
||||
field.Type.Name.Contains("CVariantBase") ||
|
||||
field.Type.Name == "HSCRIPT" || field.Type.Name == "KeyValues3") continue;
|
||||
|
||||
if (field.Type is { Category: SchemaTypeCategory.Atomic, Atomic: SchemaAtomicCategory.Collection })
|
||||
{
|
||||
SchemaTypeCategory.DeclaredClass =>
|
||||
" = new();",
|
||||
SchemaTypeCategory.FixedArray =>
|
||||
field.Type.IsString
|
||||
? $" = \"\";"
|
||||
: $" = Array.Empty<{field.Type.Inner!.CsTypeName}>();",
|
||||
SchemaTypeCategory.Atomic when field.Type.Atomic == SchemaAtomicCategory.Collection =>
|
||||
$" = new NetworkedVector<{field.Type.Inner!.CsTypeName}>();",
|
||||
_ => null
|
||||
};
|
||||
if (IgnoreClasses.Contains(field.Type.Inner!.Name)) continue;
|
||||
}
|
||||
|
||||
var handleParams = $"this.Handle, \"{schemaClassName}\", \"{field.Name}\"";
|
||||
|
||||
builder.AppendLine($" // {field.Name}");
|
||||
foreach (var (metadataKey, value) in field.Metadata)
|
||||
{
|
||||
builder.AppendLine($" // {metadataKey}{(value == "" ? "" : $" \"{value}\"")}");
|
||||
}
|
||||
|
||||
|
||||
if (field.Type is { Category: SchemaTypeCategory.FixedArray, CsTypeName: "string" })
|
||||
{
|
||||
var getter = $"return Schema.GetString({handleParams});";
|
||||
@@ -237,7 +237,7 @@ internal static partial class Program
|
||||
builder.AppendLine();
|
||||
}
|
||||
// Networked Strings require UTF8 encoding/decoding
|
||||
else if ( field.Type is { Category: SchemaTypeCategory.Atomic, CsTypeName: "string" })
|
||||
else if (field.Type is { Category: SchemaTypeCategory.Atomic, CsTypeName: "string" })
|
||||
{
|
||||
var getter = $"return Schema.GetUtf8String({handleParams});";
|
||||
var setter = $"Schema.SetString({handleParams}, value);";
|
||||
@@ -253,19 +253,23 @@ internal static partial class Program
|
||||
}
|
||||
else if (field.Type.Category == SchemaTypeCategory.FixedArray)
|
||||
{
|
||||
var getter = $"Schema.GetFixedArray<{SanitiseTypeName(field.Type.Inner!.CsTypeName)}>({handleParams}, {field.Type.ArraySize});";
|
||||
var getter =
|
||||
$"Schema.GetFixedArray<{SanitiseTypeName(field.Type.Inner!.CsTypeName)}>({handleParams}, {field.Type.ArraySize});";
|
||||
builder.AppendLine(
|
||||
$" public Span<{SanitiseTypeName(field.Type.Inner!.CsTypeName)}> {schemaClass.CsPropertyNameForField(schemaClassName, field)} => {getter}");
|
||||
builder.AppendLine();
|
||||
}
|
||||
else if (field.Type.Category == SchemaTypeCategory.DeclaredClass && !IgnoreClasses.Contains(field.Type.Name))
|
||||
else if (field.Type.Category == SchemaTypeCategory.DeclaredClass &&
|
||||
!IgnoreClasses.Contains(field.Type.Name))
|
||||
{
|
||||
var getter = $"Schema.GetDeclaredClass<{SanitiseTypeName(field.Type.CsTypeName)}>({handleParams});";
|
||||
builder.AppendLine(
|
||||
$" public {SanitiseTypeName(field.Type.CsTypeName)} {schemaClass.CsPropertyNameForField(schemaClassName, field)} => {getter}");
|
||||
builder.AppendLine();
|
||||
}
|
||||
else if ((field.Type.Category == SchemaTypeCategory.Builtin || field.Type.Category == SchemaTypeCategory.DeclaredEnum) && !IgnoreClasses.Contains(field.Type.Name))
|
||||
else if ((field.Type.Category == SchemaTypeCategory.Builtin ||
|
||||
field.Type.Category == SchemaTypeCategory.DeclaredEnum) &&
|
||||
!IgnoreClasses.Contains(field.Type.Name))
|
||||
{
|
||||
var getter = $"ref Schema.GetRef<{SanitiseTypeName(field.Type.CsTypeName)}>({handleParams});";
|
||||
builder.AppendLine(
|
||||
@@ -275,13 +279,13 @@ internal static partial class Program
|
||||
else if (field.Type.Category == SchemaTypeCategory.Ptr)
|
||||
{
|
||||
var inner = field.Type.Inner!;
|
||||
Debug.Assert(inner.Category == SchemaTypeCategory.DeclaredClass);
|
||||
if (inner.Category != SchemaTypeCategory.DeclaredClass) continue;
|
||||
|
||||
builder.AppendLine(
|
||||
$" public {SanitiseTypeName(field.Type.CsTypeName)} {schemaClass.CsPropertyNameForField(schemaClassName, field)} => Schema.GetPointer<{SanitiseTypeName(inner.CsTypeName)}>({handleParams});");
|
||||
builder.AppendLine();
|
||||
}
|
||||
else if (field.Type is { Category: SchemaTypeCategory.Atomic, Name: "Color"})
|
||||
}
|
||||
else if (field.Type is { Category: SchemaTypeCategory.Atomic, Name: "Color" })
|
||||
{
|
||||
var getter = $"return Schema.GetCustomMarshalledType<{field.Type.CsTypeName}>({handleParams});";
|
||||
var setter = $"Schema.SetCustomMarshalledType<{field.Type.CsTypeName}>({handleParams}, value);";
|
||||
@@ -355,4 +359,4 @@ internal static partial class Program
|
||||
|
||||
builder.AppendLine("}");
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -32,6 +32,7 @@ public partial record SchemaClass(
|
||||
case ("CEnvScreenOverlay", "m_bIsActive"): return "IsOverlayActive";
|
||||
case ("CPlayerSprayDecal", "m_nEntity"): return "DecalEntity";
|
||||
case ("CHandleTest", "m_Handle"): return "TestHandle";
|
||||
case ("FilterTeam", "m_iFilterTeam"): return "Value";
|
||||
}
|
||||
|
||||
string CleanFieldName(string fieldName) =>
|
||||
|
||||
@@ -1,14 +1,39 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace CounterStrikeSharp.SchemaGen;
|
||||
|
||||
public record SchemaFieldType(
|
||||
string Name,
|
||||
SchemaTypeCategory Category,
|
||||
SchemaAtomicCategory? Atomic,
|
||||
SchemaFieldType? Inner,
|
||||
int? ArraySize)
|
||||
public record SchemaFieldType
|
||||
{
|
||||
public SchemaFieldType(string Name,
|
||||
SchemaTypeCategory Category,
|
||||
SchemaAtomicCategory? Atomic,
|
||||
SchemaFieldType? Inner)
|
||||
{
|
||||
this.Name = Name;
|
||||
this.Category = Category;
|
||||
this.Atomic = Atomic;
|
||||
this.Inner = Inner;
|
||||
|
||||
if (this.Name == "GameTime_t")
|
||||
{
|
||||
this.Category = SchemaTypeCategory.Builtin;
|
||||
this.Name = "float32";
|
||||
}
|
||||
else if
|
||||
(this.Name == "CPlayerSlot" || this.Name == "HSequence" || this.Name == "CSplitScreenSlot" || this.Name == "GameTick_t")
|
||||
{
|
||||
this.Category = SchemaTypeCategory.Builtin;
|
||||
this.Name = "int32";
|
||||
}
|
||||
else if (this.Name == "CBitVec< 64 >")
|
||||
{
|
||||
this.Category = SchemaTypeCategory.FixedArray;
|
||||
this.Inner = new SchemaFieldType("uint8", SchemaTypeCategory.Builtin, null, null);
|
||||
this.Name = "uint8[8]";
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsString =>
|
||||
Category == SchemaTypeCategory.FixedArray
|
||||
&& Inner!.Category == SchemaTypeCategory.Builtin
|
||||
@@ -46,19 +71,22 @@ public record SchemaFieldType(
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(name), name, $"Unknown built-in: {name}")
|
||||
};
|
||||
|
||||
private static string AtomicToCsTypeName(string name, SchemaAtomicCategory atomic, SchemaFieldType? inner) => atomic switch
|
||||
{
|
||||
SchemaAtomicCategory.Basic => name switch
|
||||
private static string AtomicToCsTypeName(string name, SchemaAtomicCategory atomic, SchemaFieldType? inner) =>
|
||||
atomic switch
|
||||
{
|
||||
"CUtlString" or "CUtlSymbolLarge" => "string",
|
||||
"CEntityHandle" => "CHandle<CEntityInstance>",
|
||||
"CNetworkedQuantizedFloat" => "float",
|
||||
_ => name
|
||||
},
|
||||
SchemaAtomicCategory.T => $"{name.Split('<')[0]}<{inner!.CsTypeName}>",
|
||||
SchemaAtomicCategory.Collection => $"NetworkedVector<{inner!.CsTypeName}>",
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(atomic), atomic, $"Unsupported atomic: {atomic}")
|
||||
};
|
||||
SchemaAtomicCategory.Basic => name switch
|
||||
{
|
||||
"CUtlString" or "CUtlSymbolLarge" => "string",
|
||||
"CEntityHandle" => "CHandle<CEntityInstance>",
|
||||
"CNetworkedQuantizedFloat" => "float",
|
||||
"RotationVector" => "Vector",
|
||||
_ => name
|
||||
},
|
||||
SchemaAtomicCategory.T => $"{name.Split('<')[0]}<{inner!.CsTypeName}>",
|
||||
SchemaAtomicCategory.Collection => $"NetworkedVector<{inner!.CsTypeName}>",
|
||||
SchemaAtomicCategory.Unknown => "CBitVec",
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(atomic), atomic, $"Unsupported atomic: {atomic}")
|
||||
};
|
||||
|
||||
public string CsTypeName => Category switch
|
||||
{
|
||||
@@ -72,4 +100,34 @@ public record SchemaFieldType(
|
||||
SchemaTypeCategory.DeclaredEnum => Name,
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(Category), Category, $"Unsupported type category: {Category}")
|
||||
};
|
||||
}
|
||||
|
||||
public string Name { get; init; }
|
||||
public SchemaTypeCategory Category { get; init; }
|
||||
public SchemaAtomicCategory? Atomic { get; init; }
|
||||
public SchemaFieldType? Inner { get; init; }
|
||||
|
||||
public int? ArraySize
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Category == SchemaTypeCategory.FixedArray)
|
||||
{
|
||||
// Extract number from name, e.g. `uint16[2]`
|
||||
var match = Regex.Match(this.Name, @"\[(\d+)\]$");
|
||||
return match.Success ? int.Parse(match.Groups[1].Value) : null;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public void Deconstruct(out string Name, out SchemaTypeCategory Category, out SchemaAtomicCategory? Atomic,
|
||||
out SchemaFieldType? Inner, out int? ArraySize)
|
||||
{
|
||||
Name = this.Name;
|
||||
Category = this.Category;
|
||||
Atomic = this.Atomic;
|
||||
Inner = this.Inner;
|
||||
ArraySize = this.ArraySize;
|
||||
}
|
||||
}
|
||||
130
src/core/cs2_sdk/interfaces/CUtlTSHash.h
Normal file
130
src/core/cs2_sdk/interfaces/CUtlTSHash.h
Normal file
@@ -0,0 +1,130 @@
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
using UtlTsHashHandleT = std::uint64_t;
|
||||
|
||||
class CUtlMemoryPool {
|
||||
public:
|
||||
// returns number of allocated blocks
|
||||
int BlockSize() const {
|
||||
return m_blocks_per_blob_;
|
||||
}
|
||||
int Count() const {
|
||||
return m_block_allocated_size_;
|
||||
}
|
||||
int PeakCount() const {
|
||||
return m_peak_alloc_;
|
||||
}
|
||||
private:
|
||||
std::int32_t m_block_size_ = 0; // 0x0558
|
||||
std::int32_t m_blocks_per_blob_ = 0; // 0x055C
|
||||
std::int32_t m_grow_mode_ = 0; // 0x0560
|
||||
std::int32_t m_blocks_allocated_ = 0; // 0x0564
|
||||
std::int32_t m_block_allocated_size_ = 0; // 0x0568
|
||||
std::int32_t m_peak_alloc_ = 0; // 0x056C
|
||||
};
|
||||
|
||||
template <class T, class Keytype = std::uint64_t>
|
||||
class CUtlTSHash {
|
||||
public:
|
||||
// Invalid handle.
|
||||
static UtlTsHashHandleT InvalidHandle(void) {
|
||||
return static_cast<UtlTsHashHandleT>(0);
|
||||
}
|
||||
|
||||
// Returns the number of elements in the hash table
|
||||
[[nodiscard]] int BlockSize() const {
|
||||
return m_entry_memory_.BlockSize();
|
||||
}
|
||||
[[nodiscard]] int Count() const {
|
||||
return m_entry_memory_.Count();
|
||||
}
|
||||
|
||||
// Returns elements in the table
|
||||
std::vector<T> GetElements(void);
|
||||
public:
|
||||
// Templatized for memory tracking purposes
|
||||
template <typename DataT>
|
||||
struct HashFixedDataInternalT {
|
||||
Keytype m_ui_key;
|
||||
HashFixedDataInternalT<DataT>* m_next;
|
||||
DataT m_data;
|
||||
};
|
||||
|
||||
using HashFixedDataT = HashFixedDataInternalT<T>;
|
||||
|
||||
// Templatized for memory tracking purposes
|
||||
template <typename DataT>
|
||||
struct HashFixedStructDataInternalT {
|
||||
DataT m_data;
|
||||
Keytype m_ui_key;
|
||||
char pad_0x0020[0x8];
|
||||
};
|
||||
|
||||
using HashFixedStructDataT = HashFixedStructDataInternalT<T>;
|
||||
|
||||
struct HashStructDataT {
|
||||
char pad_0x0000[0x10]; // 0x0000
|
||||
std::array<HashFixedStructDataT, 256> m_list;
|
||||
};
|
||||
|
||||
struct HashAllocatedDataT {
|
||||
public:
|
||||
auto GetList() {
|
||||
return m_list_;
|
||||
}
|
||||
private:
|
||||
char pad_0x0000[0x18]; // 0x0000
|
||||
std::array<HashFixedDataT, 128> m_list_;
|
||||
};
|
||||
|
||||
// Templatized for memory tracking purposes
|
||||
template <typename DataT>
|
||||
struct HashBucketDataInternalT {
|
||||
DataT m_data;
|
||||
HashFixedDataInternalT<DataT>* m_next;
|
||||
Keytype m_ui_key;
|
||||
};
|
||||
|
||||
using HashBucketDataT = HashBucketDataInternalT<T>;
|
||||
|
||||
struct HashUnallocatedDataT {
|
||||
HashUnallocatedDataT* m_next_ = nullptr; // 0x0000
|
||||
Keytype m_6114; // 0x0008
|
||||
Keytype m_ui_key; // 0x0010
|
||||
Keytype m_i_unk_1; // 0x0018
|
||||
std::array<HashBucketDataT, 256> m_current_block_list; // 0x0020
|
||||
};
|
||||
|
||||
struct HashBucketT {
|
||||
HashStructDataT* m_struct_data = nullptr;
|
||||
void* m_mutex_list = nullptr;
|
||||
HashAllocatedDataT* m_allocated_data = nullptr;
|
||||
HashUnallocatedDataT* m_unallocated_data = nullptr;
|
||||
};
|
||||
|
||||
CUtlMemoryPool m_entry_memory_;
|
||||
HashBucketT m_buckets_;
|
||||
bool m_needs_commit_ = false;
|
||||
};
|
||||
|
||||
template <class T, class Keytype>
|
||||
std::vector<T> CUtlTSHash<T, Keytype>::GetElements(void) {
|
||||
std::vector<T> list;
|
||||
|
||||
const int n_count = Count();
|
||||
auto n_index = 0;
|
||||
auto& unallocated_data = m_buckets_.m_unallocated_data;
|
||||
for (auto element = unallocated_data; element; element = element->m_next_) {
|
||||
for (auto i = 0; i < BlockSize() && i != n_count; i++) {
|
||||
list.emplace_back(element->m_current_block_list.at(i).m_data);
|
||||
n_index++;
|
||||
|
||||
if (n_index >= n_count)
|
||||
break;
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
@@ -1,127 +1,386 @@
|
||||
/**
|
||||
* =============================================================================
|
||||
* CS2Fixes
|
||||
* Copyright (C) 2023 Source2ZE
|
||||
* =============================================================================
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "../../utils/virtual.h"
|
||||
#include <platform.h>
|
||||
|
||||
struct CSchemaNetworkValue {
|
||||
union {
|
||||
const char* m_sz_value;
|
||||
int m_n_value;
|
||||
float m_f_value;
|
||||
uintptr_t m_p_value;
|
||||
};
|
||||
#include <vector>
|
||||
#include <utils/virtual.h>
|
||||
#include <string_view>
|
||||
#include <array>
|
||||
#include "core/cs2_sdk/interfaces/CUtlTSHash.h"
|
||||
#define CSGO2
|
||||
|
||||
#define CSCHEMATYPE_GETSIZES_INDEX 3
|
||||
#define SCHEMASYSTEM_TYPE_SCOPES_OFFSET 0x190
|
||||
#define SCHEMASYSTEMTYPESCOPE_OFF1 0x47E
|
||||
#define SCHEMASYSTEMTYPESCOPE_OFF2 0x2808
|
||||
#define SCHEMASYSTEM_FIND_DECLARED_CLASS_TYPE 2
|
||||
|
||||
class CSchemaClassInfo;
|
||||
class CSchemaSystemTypeScope;
|
||||
class CSchemaType;
|
||||
|
||||
struct SchemaMetadataEntryData_t;
|
||||
struct SchemaMetadataSetData_t;
|
||||
struct SchemaClassInfoData_t;
|
||||
|
||||
using SchemaString_t = const char*;
|
||||
|
||||
template <typename T> struct SchemaArray
|
||||
{
|
||||
public:
|
||||
T* begin() const { return m_data; }
|
||||
|
||||
T* end() const { return m_data + m_size; }
|
||||
|
||||
T* m_data;
|
||||
unsigned int m_size;
|
||||
};
|
||||
|
||||
struct SchemaMetadataEntryData_t {
|
||||
const char *m_name;
|
||||
CSchemaNetworkValue* m_value;
|
||||
struct CSchemaNetworkValue
|
||||
{
|
||||
union
|
||||
{
|
||||
const char* m_sz_value;
|
||||
int m_n_value;
|
||||
float m_f_value;
|
||||
std::uintptr_t m_p_value;
|
||||
};
|
||||
};
|
||||
|
||||
struct CSchemaClassBinding
|
||||
{
|
||||
CSchemaClassBinding* parent;
|
||||
const char* m_binary_name; // ex: C_World
|
||||
const char* m_module_name; // ex: libclient.so
|
||||
const char* m_class_name; // ex: client
|
||||
void* m_class_info_old_synthesized;
|
||||
void* m_class_info;
|
||||
void* m_this_module_binding_pointer;
|
||||
CSchemaType* m_schema_type;
|
||||
};
|
||||
|
||||
struct SchemaEnumeratorInfoData_t
|
||||
{
|
||||
SchemaString_t m_name;
|
||||
|
||||
union
|
||||
{
|
||||
unsigned char m_value_char;
|
||||
unsigned short m_value_short;
|
||||
unsigned int m_value_int;
|
||||
unsigned long long m_value;
|
||||
};
|
||||
|
||||
char pad_0x0010[0x10]; // 0x0010
|
||||
};
|
||||
|
||||
class CSchemaEnumInfo
|
||||
{
|
||||
public:
|
||||
SchemaEnumeratorInfoData_t m_field_;
|
||||
};
|
||||
|
||||
class CSchemaEnumBinding
|
||||
{
|
||||
public:
|
||||
virtual const char* GetBindingName() = 0;
|
||||
virtual CSchemaClassBinding* AsClassBinding() = 0;
|
||||
virtual CSchemaEnumBinding* AsEnumBinding() = 0;
|
||||
virtual const char* GetBinaryName() = 0;
|
||||
virtual const char* GetProjectName() = 0;
|
||||
|
||||
public:
|
||||
char* m_binding_name_; // 0x0008
|
||||
char* m_dll_name_; // 0x0010
|
||||
std::int8_t m_align_; // 0x0018
|
||||
char pad_0x0019[0x3]; // 0x0019
|
||||
std::int16_t m_size_; // 0x001C
|
||||
std::int16_t m_flags_; // 0x001E
|
||||
SchemaEnumeratorInfoData_t* m_enum_info_;
|
||||
char pad_0x0028[0x8]; // 0x0028
|
||||
CSchemaSystemTypeScope* m_type_scope_; // 0x0030
|
||||
char pad_0x0038[0x8]; // 0x0038
|
||||
std::int32_t m_i_unk1_; // 0x0040
|
||||
};
|
||||
|
||||
enum SchemaClassFlags_t
|
||||
{
|
||||
SCHEMA_CLASS_HAS_VIRTUAL_MEMBERS = 1,
|
||||
SCHEMA_CLASS_IS_ABSTRACT = 2,
|
||||
SCHEMA_CLASS_HAS_TRIVIAL_CONSTRUCTOR = 4,
|
||||
SCHEMA_CLASS_HAS_TRIVIAL_DESTRUCTOR = 8,
|
||||
SCHEMA_CLASS_TEMP_HACK_HAS_NOSCHEMA_MEMBERS = 16,
|
||||
SCHEMA_CLASS_TEMP_HACK_HAS_CONSTRUCTOR_LIKE_METHODS = 32,
|
||||
SCHEMA_CLASS_TEMP_HACK_HAS_DESTRUCTOR_LIKE_METHODS = 64,
|
||||
SCHEMA_CLASS_IS_NOSCHEMA_CLASS = 128,
|
||||
};
|
||||
|
||||
enum ETypeCategory
|
||||
{
|
||||
Schema_Builtin = 0,
|
||||
Schema_Ptr = 1,
|
||||
Schema_Bitfield = 2,
|
||||
Schema_FixedArray = 3,
|
||||
Schema_Atomic = 4,
|
||||
Schema_DeclaredClass = 5,
|
||||
Schema_DeclaredEnum = 6,
|
||||
Schema_None = 7
|
||||
};
|
||||
|
||||
enum EAtomicCategory
|
||||
{
|
||||
Atomic_Basic,
|
||||
Atomic_T,
|
||||
Atomic_CollectionOfT,
|
||||
Atomic_TT,
|
||||
Atomic_I,
|
||||
Atomic_None
|
||||
};
|
||||
|
||||
#define __thiscall
|
||||
|
||||
class CSchemaType
|
||||
{
|
||||
public:
|
||||
bool GetSizes(int* out_size1, uint8_t* unk_probably_not_size)
|
||||
{
|
||||
return reinterpret_cast<int(__thiscall*)(void*, int*, uint8_t*)>(
|
||||
_vtable[CSCHEMATYPE_GETSIZES_INDEX])(this, out_size1, unk_probably_not_size);
|
||||
}
|
||||
|
||||
public:
|
||||
bool GetSize(int* out_size)
|
||||
{
|
||||
uint8_t smh = 0;
|
||||
return GetSizes(out_size, &smh);
|
||||
}
|
||||
|
||||
public:
|
||||
uintptr_t* _vtable; // 0x0000
|
||||
const char* m_name_; // 0x0008
|
||||
|
||||
CSchemaSystemTypeScope* m_type_scope_; // 0x0010
|
||||
uint8_t type_category; // ETypeCategory 0x0018
|
||||
uint8_t atomic_category; // EAtomicCategory 0x0019
|
||||
|
||||
// find out to what class pointer points.
|
||||
CSchemaType* GetRefClass()
|
||||
{
|
||||
if (type_category != Schema_Ptr)
|
||||
return nullptr;
|
||||
|
||||
auto ptr = m_schema_type_;
|
||||
while (ptr && ptr->type_category == ETypeCategory::Schema_Ptr)
|
||||
ptr = ptr->m_schema_type_;
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
struct array_t
|
||||
{
|
||||
uint32_t array_size;
|
||||
uint32_t unknown;
|
||||
CSchemaType* element_type_;
|
||||
};
|
||||
|
||||
struct generic_type_t {
|
||||
uint64_t unknown;
|
||||
const char* m_name_; // 0x0008
|
||||
};
|
||||
|
||||
struct atomic_t
|
||||
{ // same goes for CollectionOfT
|
||||
generic_type_t* generic_type;
|
||||
uint64_t unknown;
|
||||
CSchemaType* template_typename;
|
||||
};
|
||||
|
||||
struct atomic_tt
|
||||
{
|
||||
uint64_t gap[2];
|
||||
CSchemaType* templates[2];
|
||||
};
|
||||
|
||||
struct atomic_i
|
||||
{
|
||||
uint64_t gap[2];
|
||||
uint64_t integer;
|
||||
};
|
||||
|
||||
// this union depends on CSchema implementation, all members above
|
||||
// is from base class ( CSchemaType )
|
||||
union // 0x020
|
||||
{
|
||||
CSchemaType* m_schema_type_;
|
||||
CSchemaClassInfo* m_class_info;
|
||||
CSchemaEnumBinding* m_enum_binding_;
|
||||
array_t m_array_;
|
||||
atomic_t m_atomic_t_;
|
||||
atomic_tt m_atomic_tt_;
|
||||
atomic_i m_atomic_i_;
|
||||
};
|
||||
};
|
||||
static_assert(offsetof(CSchemaType, m_schema_type_) == 0x20);
|
||||
|
||||
struct SchemaMetadataEntryData_t
|
||||
{
|
||||
SchemaString_t m_name;
|
||||
CSchemaNetworkValue* m_value;
|
||||
// CSchemaType* m_pDataType;
|
||||
// void* unaccounted;
|
||||
};
|
||||
|
||||
struct SchemaMetadataSetData_t
|
||||
{
|
||||
SchemaMetadataEntryData_t m_static_entries;
|
||||
};
|
||||
|
||||
struct SchemaClassFieldData_t
|
||||
{
|
||||
const char *m_name;
|
||||
char pad0[0x8];
|
||||
short m_offset;
|
||||
int32_t m_metadata_size;
|
||||
SchemaMetadataEntryData_t* m_metadata;
|
||||
SchemaString_t m_name; // 0x0000
|
||||
CSchemaType* m_type; // 0x0008
|
||||
std::int32_t m_single_inheritance_offset; // 0x0010
|
||||
std::int32_t m_metadata_size; // 0x0014
|
||||
SchemaMetadataEntryData_t* m_metadata; // 0x0018
|
||||
};
|
||||
|
||||
class SchemaClassInfoData_t;
|
||||
struct SchemaStaticFieldData_t
|
||||
{
|
||||
const char* name; // 0x0000
|
||||
CSchemaType* m_type; // 0x0008
|
||||
void* m_instance; // 0x0010
|
||||
char pad_0x0018[0x10]; // 0x0018
|
||||
};
|
||||
|
||||
struct SchemaBaseClassInfoData_t
|
||||
{
|
||||
unsigned int m_offset;
|
||||
SchemaClassInfoData_t *m_class;
|
||||
unsigned int m_offset;
|
||||
CSchemaClassInfo* m_class;
|
||||
};
|
||||
|
||||
class SchemaClassInfoData_t
|
||||
// Classes
|
||||
struct SchemaClassInfoData_t
|
||||
{
|
||||
public:
|
||||
auto GetName()
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
char pad_0x0000[0x8]; // 0x0000
|
||||
|
||||
auto GetFieldsSize()
|
||||
{
|
||||
return m_align;
|
||||
}
|
||||
const char* m_name; // 0x0008
|
||||
char* m_module; // 0x0010
|
||||
|
||||
auto GetFields()
|
||||
{
|
||||
return m_fields;
|
||||
}
|
||||
int m_size; // 0x0018
|
||||
std::int16_t m_align; // 0x001C
|
||||
|
||||
SchemaClassInfoData_t* GetParent()
|
||||
{
|
||||
if (!m_schema_parent)
|
||||
return nullptr;
|
||||
std::int16_t m_static_size; // 0x001E
|
||||
std::int16_t m_metadata_size; // 0x0020
|
||||
std::int16_t m_i_unk1; // 0x0022
|
||||
std::int16_t m_i_unk2; // 0x0024
|
||||
std::int16_t m_i_unk3; // 0x0026
|
||||
|
||||
return m_schema_parent->m_class;
|
||||
}
|
||||
SchemaClassFieldData_t* m_fields; // 0x0028
|
||||
|
||||
private:
|
||||
char pad_0x0000[0x8]; // 0x0000
|
||||
SchemaStaticFieldData_t* m_static_fields; // 0x0030
|
||||
SchemaBaseClassInfoData_t* m_schema_parent; // 0x0038
|
||||
|
||||
const char *m_name; // 0x0008
|
||||
char *m_module; // 0x0010
|
||||
char pad_0x0038[0x10]; // 0x0038
|
||||
|
||||
int m_size; // 0x0018
|
||||
int16_t m_align; // 0x001C
|
||||
SchemaMetadataSetData_t* m_metadata; // 0x0048
|
||||
CSchemaSystemTypeScope* m_type_scope; // 0x0050
|
||||
CSchemaType* m_shema_type; // 0x0058
|
||||
SchemaClassFlags_t m_class_flags : 8; // 0x0060
|
||||
};
|
||||
|
||||
int16_t m_static_size; // 0x001E
|
||||
int16_t m_metadata_size; // 0x0020
|
||||
int16_t m_i_unk1; // 0x0022
|
||||
int16_t m_i_unk2; // 0x0024
|
||||
int16_t m_i_unk3; // 0x0026
|
||||
class CSchemaClassInfo : public SchemaClassInfoData_t
|
||||
{
|
||||
public:
|
||||
bool GetMetaStrings(const char* metaName, std::vector<const char**>& strings);
|
||||
|
||||
SchemaClassFieldData_t *m_fields; // 0x0028
|
||||
unsigned int CalculateInheritanceDataSize(bool ignoreVirtuals = false);
|
||||
|
||||
char pad_0x0030[0x8]; // 0x0030
|
||||
SchemaBaseClassInfoData_t *m_schema_parent; // 0x0038
|
||||
bool DependsOn(CSchemaClassInfo* other);
|
||||
bool InheritsFrom(CSchemaClassInfo* other);
|
||||
bool UsesClass(CSchemaClassInfo* other);
|
||||
bool InheritsVirtuals();
|
||||
|
||||
char pad_0x0038[0x10]; // 0x0038
|
||||
void FillClassFieldsList(std::vector<SchemaClassFieldData_t*>& fields);
|
||||
void FillInheritanceList(std::vector<const char*>& inheritance);
|
||||
CSchemaClassInfo* GetParent()
|
||||
{
|
||||
if (!m_schema_parent)
|
||||
return nullptr;
|
||||
|
||||
return m_schema_parent->m_class;
|
||||
}
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
class CSchemaSystemTypeScope
|
||||
{
|
||||
public:
|
||||
SchemaClassInfoData_t* FindDeclaredClass(const char *pClass)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
SchemaClassInfoData_t *rv = nullptr;
|
||||
CALL_VIRTUAL(void, 2, this, &rv, pClass);
|
||||
return rv;
|
||||
#else
|
||||
return CALL_VIRTUAL(SchemaClassInfoData_t*, 2, this, pClass);
|
||||
#endif
|
||||
}
|
||||
public:
|
||||
CSchemaClassInfo* FindDeclaredClass(const char* class_name)
|
||||
{
|
||||
return CALL_VIRTUAL(CSchemaClassInfo*, 2, this, class_name);
|
||||
}
|
||||
|
||||
CSchemaEnumBinding* FindDeclaredEnum(const char* name)
|
||||
{
|
||||
return CALL_VIRTUAL(CSchemaEnumBinding*, 3, this, name);
|
||||
}
|
||||
|
||||
CSchemaType* FindSchemaTypeByName(const char* name, std::uintptr_t* pSchema)
|
||||
{
|
||||
return CALL_VIRTUAL(CSchemaType*, 4, this, name, pSchema);
|
||||
}
|
||||
|
||||
CSchemaType* FindTypeDeclaredClass(const char* name)
|
||||
{
|
||||
return CALL_VIRTUAL(CSchemaType*, 5, this, name);
|
||||
}
|
||||
|
||||
CSchemaType* FindTypeDeclaredEnum(const char* name)
|
||||
{
|
||||
return CALL_VIRTUAL(CSchemaType*, 6, this, name);
|
||||
}
|
||||
|
||||
CSchemaClassBinding* FindRawClassBinding(const char* name)
|
||||
{
|
||||
return CALL_VIRTUAL(CSchemaClassBinding*, 7, this, name);
|
||||
}
|
||||
|
||||
CSchemaEnumBinding* FindRawEnumBinding(const char* name)
|
||||
{
|
||||
return CALL_VIRTUAL(CSchemaEnumBinding*, 8, this, name);
|
||||
}
|
||||
|
||||
std::string_view GetScopeName() {
|
||||
return {m_name_.data()};
|
||||
}
|
||||
|
||||
[[nodiscard]] CUtlTSHash<CSchemaClassBinding*> GetClasses() const {
|
||||
return m_classes_;
|
||||
}
|
||||
|
||||
[[nodiscard]] CUtlTSHash<CSchemaEnumBinding*> GetEnums() const {
|
||||
return m_enumes_;
|
||||
}
|
||||
private:
|
||||
char pad_0x0000[0x8]; // 0x0000
|
||||
std::array<char, 256> m_name_ = {};
|
||||
char pad_0x0108[SCHEMASYSTEMTYPESCOPE_OFF1]; // 0x0108
|
||||
CUtlTSHash<CSchemaClassBinding*> m_classes_; // 0x0588
|
||||
char pad_0x0594[SCHEMASYSTEMTYPESCOPE_OFF2]; // 0x05C8
|
||||
CUtlTSHash<CSchemaEnumBinding*> m_enumes_; // 0x2DD0
|
||||
private:
|
||||
static constexpr unsigned int s_class_list = 0x580;
|
||||
};
|
||||
|
||||
class CSchemaSystem
|
||||
{
|
||||
public:
|
||||
auto FindTypeScopeForModule(const char *module)
|
||||
{
|
||||
return CALL_VIRTUAL(CSchemaSystemTypeScope *, 13, this, module, nullptr);
|
||||
}
|
||||
};
|
||||
public:
|
||||
CSchemaSystemTypeScope* GlobalTypeScope(void)
|
||||
{
|
||||
return CALL_VIRTUAL(CSchemaSystemTypeScope*, 11, this);
|
||||
}
|
||||
|
||||
CSchemaSystemTypeScope* FindTypeScopeForModule(const char* m_module_name)
|
||||
{
|
||||
return CALL_VIRTUAL(CSchemaSystemTypeScope*, 13, this, m_module_name, nullptr);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -57,8 +57,8 @@ static bool InitSchemaFieldsForClass(SchemaTableMap_t* tableMap,
|
||||
return false;
|
||||
}
|
||||
|
||||
short fieldsSize = pClassInfo->GetFieldsSize();
|
||||
SchemaClassFieldData_t* pFields = pClassInfo->GetFields();
|
||||
short fieldsSize = pClassInfo->m_align;
|
||||
SchemaClassFieldData_t* pFields = pClassInfo->m_fields;
|
||||
|
||||
SchemaKeyValueMap_t* keyValueMap = new SchemaKeyValueMap_t(0, 0, DefLessFunc(uint32_t));
|
||||
keyValueMap->EnsureCapacity(fieldsSize);
|
||||
@@ -68,7 +68,7 @@ static bool InitSchemaFieldsForClass(SchemaTableMap_t* tableMap,
|
||||
SchemaClassFieldData_t& field = pFields[i];
|
||||
|
||||
keyValueMap->Insert(hash_32_fnv1a_const(field.m_name),
|
||||
{field.m_offset, IsFieldNetworked(field)});
|
||||
{field.m_single_inheritance_offset, IsFieldNetworked(field)});
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -80,16 +80,16 @@ int16_t schema::FindChainOffset(const char* className) {
|
||||
|
||||
if (!pType) return false;
|
||||
|
||||
SchemaClassInfoData_t* pClassInfo = pType->FindDeclaredClass(className);
|
||||
auto* pClassInfo = pType->FindDeclaredClass(className);
|
||||
|
||||
do {
|
||||
SchemaClassFieldData_t* pFields = pClassInfo->GetFields();
|
||||
short fieldsSize = pClassInfo->GetFieldsSize();
|
||||
SchemaClassFieldData_t* pFields = pClassInfo->m_fields;
|
||||
short fieldsSize = pClassInfo->m_align;
|
||||
for (int i = 0; i < fieldsSize; ++i) {
|
||||
SchemaClassFieldData_t& field = pFields[i];
|
||||
|
||||
if (V_strcmp(field.m_name, "__m_pChainEntity") == 0) {
|
||||
return field.m_offset;
|
||||
return field.m_single_inheritance_offset;
|
||||
}
|
||||
}
|
||||
} while ((pClassInfo = pClassInfo->GetParent()) != nullptr);
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
#undef schema
|
||||
|
||||
struct SchemaKey {
|
||||
int16_t offset;
|
||||
int32_t offset;
|
||||
bool networked;
|
||||
};
|
||||
|
||||
|
||||
@@ -38,9 +38,123 @@
|
||||
|
||||
#include "scripting/callback_manager.h"
|
||||
#include "core/log.h"
|
||||
#include "core/cs2_sdk/interfaces/cschemasystem.h"
|
||||
#include "core/utils.h"
|
||||
#include "core/memory.h"
|
||||
#include "interfaces/cs2_interfaces.h"
|
||||
#include <nlohmann/json.hpp>
|
||||
using json = nlohmann::json;
|
||||
|
||||
namespace counterstrikesharp {
|
||||
|
||||
json WriteTypeJson(json obj, CSchemaType* current_type)
|
||||
{
|
||||
obj["name"] = current_type->m_name_;
|
||||
obj["category"] = current_type->type_category;
|
||||
|
||||
if (current_type->type_category == Schema_Atomic) {
|
||||
obj["atomic"] = current_type->atomic_category;
|
||||
|
||||
if (current_type->atomic_category == Atomic_T &&
|
||||
current_type->m_atomic_t_.generic_type != nullptr) {
|
||||
obj["outer"] = current_type->m_atomic_t_.generic_type->m_name_;
|
||||
}
|
||||
|
||||
if (current_type->atomic_category == Atomic_T ||
|
||||
current_type->atomic_category == Atomic_CollectionOfT) {
|
||||
obj["inner"] =
|
||||
WriteTypeJson(json::object(), current_type->m_atomic_t_.template_typename);
|
||||
}
|
||||
} else if (current_type->type_category == Schema_FixedArray) {
|
||||
obj["inner"] = WriteTypeJson(json::object(), current_type->m_array_.element_type_);
|
||||
} else if (current_type->type_category == Schema_Ptr) {
|
||||
obj["inner"] = WriteTypeJson(json::object(), current_type->m_schema_type_);
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
CON_COMMAND(dump_schema, "dump schema symbols")
|
||||
{
|
||||
std::vector<std::string> classNames;
|
||||
std::vector<std::string> enumNames;
|
||||
// Reading these from a static file since I cannot seem to get the
|
||||
// CSchemaSystemTypeScope->GetClasses() to return anything on linux.
|
||||
std::ifstream inputClasses(utils::GamedataDirectory() + "/schema_classes.txt");
|
||||
std::ifstream inputEnums(utils::GamedataDirectory() + "/schema_enums.txt");
|
||||
std::ofstream output(utils::GamedataDirectory() + "/schema.json");
|
||||
std::string line;
|
||||
|
||||
while (std::getline(inputClasses, line)) {
|
||||
if (!line.empty() && line.back() == '\r') {
|
||||
line.pop_back();
|
||||
}
|
||||
classNames.push_back(line);
|
||||
}
|
||||
|
||||
while (std::getline(inputEnums, line)) {
|
||||
if (!line.empty() && line.back() == '\r') {
|
||||
line.pop_back();
|
||||
}
|
||||
enumNames.push_back(line);
|
||||
}
|
||||
|
||||
CSchemaSystemTypeScope* pType =
|
||||
interfaces::pSchemaSystem->FindTypeScopeForModule(MODULE_PREFIX "server" MODULE_EXT);
|
||||
|
||||
json j;
|
||||
j["classes"] = json::object();
|
||||
j["enums"] = json::object();
|
||||
|
||||
for (const auto& line : classNames) {
|
||||
SchemaClassInfoData_t* pClassInfo = pType->FindDeclaredClass(line.c_str());
|
||||
if (!pClassInfo)
|
||||
continue;
|
||||
|
||||
short fieldsSize = pClassInfo->m_align;
|
||||
SchemaClassFieldData_t* pFields = pClassInfo->m_fields;
|
||||
|
||||
j["classes"][pClassInfo->m_name] = json::object();
|
||||
if (pClassInfo->m_schema_parent) {
|
||||
j["classes"][pClassInfo->m_name]["parent"] =
|
||||
pClassInfo->m_schema_parent->m_class->m_name;
|
||||
}
|
||||
|
||||
j["classes"][pClassInfo->m_name]["fields"] = json::array();
|
||||
|
||||
for (int i = 0; i < fieldsSize; ++i) {
|
||||
SchemaClassFieldData_t& field = pFields[i];
|
||||
|
||||
j["classes"][pClassInfo->m_name]["fields"].push_back({
|
||||
{"name", field.m_name},
|
||||
{"type", WriteTypeJson(json::object(), field.m_type)},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto& line : enumNames) {
|
||||
auto* pEnumInfo = pType->FindDeclaredEnum(line.c_str());
|
||||
if (!pEnumInfo)
|
||||
continue;
|
||||
|
||||
j["enums"][pEnumInfo->m_binding_name_] = json::object();
|
||||
j["enums"][pEnumInfo->m_binding_name_]["align"] = pEnumInfo->m_align_;
|
||||
j["enums"][pEnumInfo->m_binding_name_]["items"] = json::array();
|
||||
|
||||
for (int i = 0; i < pEnumInfo->m_size_; ++i) {
|
||||
auto& field = pEnumInfo->m_enum_info_[i];
|
||||
|
||||
j["enums"][pEnumInfo->m_binding_name_]["items"].push_back({
|
||||
{"name", field.m_name},
|
||||
{"value", field.m_value},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Msg("Schema dumped to %s\n", (utils::GamedataDirectory() + "/schema.json").c_str());
|
||||
output << std::setw(2) << j << std::endl;
|
||||
}
|
||||
|
||||
SH_DECL_HOOK2_void(
|
||||
ConCommandHandle, Dispatch, SH_NOATTRIB, false, const CCommandContext&, const CCommand&);
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ inline std::string GameDirectory() {
|
||||
}
|
||||
|
||||
inline std::string PluginDirectory() { return GameDirectory() + "/addons/counterstrikesharp"; }
|
||||
inline std::string GamedataDirectory() { return GameDirectory() + "/addons/counterstrikesharp/gamedata"; }
|
||||
|
||||
inline std::string ConfigDirectory() { return PluginDirectory() + "/config"; }
|
||||
} // namespace utils
|
||||
} // namespace counterstrikesharp
|
||||
|
||||
Reference in New Issue
Block a user