mirror of
https://github.com/roflmuffin/CounterStrikeSharp.git
synced 2025-12-07 08:26:34 -08:00
Compare commits
20 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0e3698b370 | ||
|
|
bb38b1cb1a | ||
|
|
10f472ec85 | ||
|
|
28ce183cdc | ||
|
|
dddf24d0f3 | ||
|
|
fce68cb160 | ||
|
|
a82faeb5c8 | ||
|
|
ce3ff449b9 | ||
|
|
aa40d81a86 | ||
|
|
5644921873 | ||
|
|
3860ca1662 | ||
|
|
b79fd19c85 | ||
|
|
b7ea025b03 | ||
|
|
5ac173df51 | ||
|
|
c82a58f5ab | ||
|
|
1806919559 | ||
|
|
f8451c2818 | ||
|
|
a87bd25b48 | ||
|
|
9c5468e5ba | ||
|
|
f826be664f |
11
.devcontainer/linux/devcontainer.json
Normal file
11
.devcontainer/linux/devcontainer.json
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"name": "SteamRT Sniper SDK",
|
||||
"image": "registry.gitlab.steamos.cloud/steamrt/sniper/sdk:latest",
|
||||
"customizations": {
|
||||
"vscode": {
|
||||
"extensions": [
|
||||
"ms-vscode.cpptools"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10,5 +10,5 @@ indent_size = 4
|
||||
max_line_length = 140
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[*.json]
|
||||
[{*.json,*.yaml,*.yml}]
|
||||
indent_size = 2
|
||||
|
||||
21
.github/workflows/actionlint.yaml
vendored
Normal file
21
.github/workflows/actionlint.yaml
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
name: actionlint
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
pull_request:
|
||||
branches: ["main"]
|
||||
paths:
|
||||
- ".github/actions/**"
|
||||
- ".github/workflows/**"
|
||||
|
||||
jobs:
|
||||
actionlint:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 3
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: actionlint
|
||||
uses: reviewdog/action-actionlint@v1
|
||||
with:
|
||||
reporter: github-pr-review
|
||||
fail_on_error: true
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -3,6 +3,7 @@
|
||||
cmake-build-*/
|
||||
.kdev4/
|
||||
generated/
|
||||
!**/protobuf/generated/
|
||||
|
||||
# configure_file auto generated.
|
||||
configs/addons/metamod/counterstrikesharp.vdf
|
||||
@@ -11,6 +12,7 @@ libraries/mono/
|
||||
|
||||
CMakeSettings.json
|
||||
|
||||
build-*/
|
||||
build/
|
||||
build_test/
|
||||
|
||||
|
||||
@@ -15,6 +15,8 @@ add_subdirectory(libraries/DynoHook)
|
||||
set_property(TARGET dynohook PROPERTY DYNO_ARCH_X86 64)
|
||||
set_property(TARGET funchook-static PROPERTY POSITION_INDEPENDENT_CODE ON)
|
||||
|
||||
include("makefiles/protobuf.cmake")
|
||||
|
||||
set(SOURCE_FILES
|
||||
libraries/hl2sdk-cs2/public/tier0/memoverride.cpp
|
||||
src/mm_plugin.cpp
|
||||
@@ -88,35 +90,20 @@ set(SOURCE_FILES
|
||||
src/core/managers/server_manager.cpp
|
||||
src/core/managers/server_manager.h
|
||||
src/scripting/natives/natives_server.cpp
|
||||
src/scripting/natives/natives_usermessages.cpp
|
||||
libraries/nlohmann/json.hpp
|
||||
src/core/managers/voice_manager.cpp
|
||||
src/core/managers/voice_manager.h
|
||||
src/core/managers/usermessage_manager.cpp
|
||||
src/core/managers/usermessage_manager.h
|
||||
src/scripting/natives/natives_dynamichooks.cpp
|
||||
src/core/game_system.h
|
||||
src/core/game_system.cpp
|
||||
src/core/UserMessage.h
|
||||
src/core/UserMessage.cpp
|
||||
src/core/recipientfilters.h
|
||||
)
|
||||
|
||||
set(PROTO_DIRS -I${CMAKE_CURRENT_SOURCE_DIR}/libraries/Protobufs/csgo)
|
||||
file(GLOB PROTOS "${CMAKE_CURRENT_SOURCE_DIR}/libraries/Protobufs/csgo/*.proto")
|
||||
|
||||
## Generate protobuf source & headers
|
||||
if(LINUX)
|
||||
set(PROTOC_EXECUTABLE ${CMAKE_CURRENT_SOURCE_DIR}/libraries/hl2sdk-cs2/devtools/bin/linux/protoc)
|
||||
elseif(WIN32)
|
||||
set(PROTOC_EXECUTABLE ${CMAKE_CURRENT_SOURCE_DIR}/libraries/hl2sdk-cs2/devtools/bin/protoc.exe)
|
||||
endif()
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT protobuf_output_stamp
|
||||
COMMAND ${PROTOC_EXECUTABLE} --proto_path=thirdparty/protobuf-3.21.8/src --proto_path=common --cpp_out=common common/network_connection.proto
|
||||
COMMENT "Generating protobuf file"
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/libraries/hl2sdk-cs2
|
||||
VERBATIM
|
||||
)
|
||||
|
||||
set(SOURCE_FILES ${SOURCE_FILES} protobuf_output_stamp)
|
||||
|
||||
# Sources
|
||||
add_library(${PROJECT_NAME} SHARED ${SOURCE_FILES} ${NATIVES_SOURCES} ${CONVERSIONS_SOURCES} ${CONVERSIONS_HEADERS})
|
||||
|
||||
target_include_directories(
|
||||
@@ -141,7 +128,7 @@ elseif(WIN32)
|
||||
endif()
|
||||
|
||||
# Libraries
|
||||
target_link_libraries(${PROJECT_NAME} ${COUNTER_STRIKE_SHARP_LINK_LIBRARIES})
|
||||
target_link_libraries(${PROJECT_NAME} ${COUNTER_STRIKE_SHARP_LINK_LIBRARIES} Protobufs)
|
||||
|
||||
add_custom_command(
|
||||
TARGET ${PROJECT_NAME} PRE_BUILD
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
"ClientPrint": {
|
||||
"signatures": {
|
||||
"library": "server",
|
||||
"windows": "48 85 C9 0F 84 ? ? ? ? 48 8B C4 48 89 58 18",
|
||||
"windows": "48 85 C9 0F 84 ? ? ? ? 48 89 5C 24 ? 55",
|
||||
"linux": "55 48 89 E5 41 57 49 89 CF 41 56 49 89 D6 41 55 41 89 F5 41 54 4C 8D A5 A0 FE FF FF"
|
||||
}
|
||||
},
|
||||
@@ -35,7 +35,7 @@
|
||||
"CBasePlayerController_SetPawn": {
|
||||
"signatures": {
|
||||
"library": "server",
|
||||
"windows": "44 88 4C 24 ? 55 56 57 41 54 41 56 48 8D 6C 24 ?",
|
||||
"windows": "48 89 74 24 ? 55 41 54 41 55 41 56 41 57 48 8D 6C 24 ? 48 81 EC ? ? ? ? 4C 8B F9",
|
||||
"linux": "55 48 89 E5 41 57 41 56 41 55 49 89 FD 41 54 45 89 C4"
|
||||
}
|
||||
},
|
||||
@@ -84,8 +84,8 @@
|
||||
"CCSPlayer_WeaponServices_CanUse": {
|
||||
"signatures": {
|
||||
"library": "server",
|
||||
"windows": "48 89 5C 24 10 48 89 6C 24 18 56 57 41 56 48 83 EC 30 80 B9 A0 00 00 00 00",
|
||||
"linux": "48 85 F6 0F 84 ? ? ? ? 55 31 C9 48 89 E5 41 55 49 89 FD"
|
||||
"windows": "48 89 5C 24 10 48 89 6C 24 18 56 57 41 56 48 83 EC 30 48 8B 01",
|
||||
"linux": "55 48 8D 15 ? ? ? ? 48 89 E5 41 55 49 89 FD 41 54 49 89 F4"
|
||||
}
|
||||
},
|
||||
"CCSPlayer_ItemServices_GiveNamedItem": {
|
||||
@@ -197,7 +197,7 @@
|
||||
"StateChanged": {
|
||||
"signatures": {
|
||||
"library": "server",
|
||||
"windows": "40 55 53 56 41 55 41 57 48 8D 6C 24 B0",
|
||||
"windows": "40 ? 53 56 41 ? 41 ? 48 ? ? ? ? 48 ? ? ? ? ? ? 48 ? ? 45",
|
||||
"linux": "55 48 89 E5 41 57 41 56 41 55 41 54 53 89 D3"
|
||||
}
|
||||
},
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,320 +0,0 @@
|
||||
ActionType_t
|
||||
AimMatrixBlendMode
|
||||
AmmoFlags_t
|
||||
AmmoPosition_t
|
||||
AnimationProcessingType_t
|
||||
AnimationSnapshotType_t
|
||||
AnimationType_t
|
||||
AnimLoopMode_t
|
||||
AnimNodeNetworkMode
|
||||
AnimParamButton_t
|
||||
AnimParamNetworkSetting
|
||||
AnimParamType_t
|
||||
AnimPoseControl
|
||||
AnimScriptType
|
||||
AnimValueSource
|
||||
AnimVectorSource
|
||||
attributeprovidertypes_t
|
||||
BaseExplosionTypes_t
|
||||
BBoxVolumeType_t
|
||||
BeamClipStyle_t
|
||||
BeamType_t
|
||||
BeginDeathLifeStateTransition_t
|
||||
BinaryNodeChildOption
|
||||
BinaryNodeTiming
|
||||
Blend2DMode
|
||||
BlendKeyType
|
||||
BloomBlendMode_t
|
||||
BlurFilterType_t
|
||||
BoneMaskBlendSpace
|
||||
BoneTransformSpace_t
|
||||
BrushSolidities_e
|
||||
C4LightEffect_t
|
||||
CAnimationGraphVisualizerPrimitiveType
|
||||
CanPlaySequence_t
|
||||
ChatIgnoreType_t
|
||||
ChickenActivity
|
||||
ChoiceBlendMethod
|
||||
ChoiceChangeMethod
|
||||
ChoiceMethod
|
||||
Class_T
|
||||
CLogicBranchList__LogicBranchListenerLastState_t
|
||||
ClosestPointTestType_t
|
||||
CNmBoneMask__WeightInfo_t
|
||||
CommandEntitySpecType_t
|
||||
CommandExecMode_t
|
||||
CompMatPropertyMutatorConditionType_t
|
||||
CompMatPropertyMutatorType_t
|
||||
CompositeMaterialInputContainerSourceType_t
|
||||
CompositeMaterialInputLooseVariableType_t
|
||||
CompositeMaterialInputTextureType_t
|
||||
CompositeMaterialMatchFilterType_t
|
||||
CompositeMaterialVarSystemVar_t
|
||||
CRR_Response__ResponseEnum_t
|
||||
CSPlayerBlockingUseAction_t
|
||||
CSPlayerState
|
||||
CSWeaponCategory
|
||||
CSWeaponMode
|
||||
CSWeaponSilencerType
|
||||
CSWeaponState_t
|
||||
CSWeaponType
|
||||
DamageTypes_t
|
||||
DampingSpeedFunction
|
||||
DebugOverlayBits_t
|
||||
Detail2Combo_t
|
||||
DetailCombo_t
|
||||
DisableShadows_t
|
||||
Disposition_t
|
||||
doorCheck_e
|
||||
DoorState_t
|
||||
EDemoBoneSelectionMode
|
||||
EInButtonState
|
||||
EKillTypes_t
|
||||
ELayoutNodeType
|
||||
EntFinderMethod_t
|
||||
EntityDisolveType_t
|
||||
EntityDormancyType_t
|
||||
EntityIOTargetType_t
|
||||
EntitySubclassScope_t
|
||||
EOverrideBlockLOS_t
|
||||
EStyleNodeType
|
||||
Explosions
|
||||
FacingMode
|
||||
FieldNetworkOption
|
||||
fieldtype_t
|
||||
filter_t
|
||||
FixAngleSet_t
|
||||
FlexOpCode_t
|
||||
FootFallTagFoot_t
|
||||
FootLockSubVisualization
|
||||
FootPinningTimingSource
|
||||
FootstepLandedFootSoundType_t
|
||||
ForcedCrouchState_t
|
||||
FuncDoorSpawnPos_t
|
||||
FuseVariableAccess_t
|
||||
FuseVariableType_t
|
||||
GameAnimEventIndex_t
|
||||
gear_slot_t
|
||||
GrenadeType_t
|
||||
HierarchyType_t
|
||||
HitboxLerpType_t
|
||||
HitGroup_t
|
||||
HorizJustification_e
|
||||
Hull_t
|
||||
IChoreoServices__ChoreoState_t
|
||||
IChoreoServices__ScriptState_t
|
||||
IKChannelMode
|
||||
IkEndEffectorType
|
||||
IKSolverType
|
||||
IKTargetCoordinateSystem
|
||||
IKTargetSource
|
||||
IkTargetType
|
||||
InheritableBoolType_t
|
||||
InputBitMask_t
|
||||
InputLayoutVariation_t
|
||||
ItemFlagTypes_t
|
||||
JiggleBoneSimSpace
|
||||
JointAxis_t
|
||||
JointMotion_t
|
||||
JumpCorrectionMethod
|
||||
LatchDirtyPermission_t
|
||||
LayoutPositionType_e
|
||||
LessonPanelLayoutFileTypes_t
|
||||
LifeState_t
|
||||
loadout_slot_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
|
||||
MovementGait_t
|
||||
MoveMountingAmount_t
|
||||
MoveType_t
|
||||
NavAttributeEnum
|
||||
NavDirType
|
||||
navproperties_t
|
||||
NmFootPhase_t
|
||||
NmFootPhaseCondition_t
|
||||
NmFrameSnapEventMode_t
|
||||
NmTransitionRule_t
|
||||
NmTransitionRuleCondition_t
|
||||
NPCFollowFormation_t
|
||||
NPCLookType_t
|
||||
ObjectTypeFlags_t
|
||||
ObserverInterpState_t
|
||||
ObserverMode_t
|
||||
OnFrame
|
||||
ParticleAlphaReferenceType_t
|
||||
ParticleAttachment_t
|
||||
ParticleAttrBoxFlags_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
|
||||
ParticleLightingQuality_t
|
||||
ParticleLightnintBranchBehavior_t
|
||||
ParticleLightTypeChoiceList_t
|
||||
ParticleLightUnitChoiceList_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
|
||||
ParticleVecType_t
|
||||
ParticleVRHandChoiceList_t
|
||||
PerformanceMode_t
|
||||
PermModelInfo_t__FlagEnum
|
||||
PetGroundType_t
|
||||
PFNoiseModifier_t
|
||||
PFNoiseTurbulence_t
|
||||
PFNoiseType_t
|
||||
PFuncVisualizationType_t
|
||||
PlayerAnimEvent_t
|
||||
PlayerConnectedState
|
||||
PointTemplateClientOnlyEntityBehavior_t
|
||||
PointTemplateOwnerSpawnGroupType_t
|
||||
PointWorldTextJustifyHorizontal_t
|
||||
PointWorldTextJustifyVertical_t
|
||||
PointWorldTextReorientMode_t
|
||||
PoseType_t
|
||||
PreviewCharacterMode
|
||||
PreviewEOMCelebration
|
||||
PreviewWeaponState
|
||||
PropDoorRotatingOpenDirection_e
|
||||
PropDoorRotatingSpawnPos_t
|
||||
PulseCursorCancelPriority_t
|
||||
PulseCursorExecResult_t
|
||||
PulseInstructionCode_t
|
||||
PulseMethodCallMode_t
|
||||
PulseTestEnumColor_t
|
||||
PulseTestEnumShape_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
|
||||
SequenceFinishNotifyState_t
|
||||
ShadowType_t
|
||||
ShakeCommand_t
|
||||
ShardSolid_t
|
||||
ShatterDamageCause
|
||||
ShatterGlassStressType
|
||||
ShatterPanelMode
|
||||
SimpleConstraintSoundProfile__SimpleConstraintsSoundProfileKeypoints_t
|
||||
SnapshotIndexType_t
|
||||
SolidType_t
|
||||
SolveIKChainAnimNodeDebugSetting
|
||||
SosActionSortType_t
|
||||
SosActionStopType_t
|
||||
SosEditItemType_t
|
||||
SosGroupType_t
|
||||
SoundEventStartType_t
|
||||
SoundFlags_t
|
||||
soundlevel_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
|
||||
TakeDamageFlags_t
|
||||
TextureRepetitionMode_t
|
||||
ThreeState_t
|
||||
TimelineCompression_t
|
||||
TOGGLE_STATE
|
||||
Touch_t
|
||||
TrackOrientationType_t
|
||||
TRAIN_CODE
|
||||
TrainOrientationType_t
|
||||
TrainVelocityType_t
|
||||
ValueRemapperHapticsType_t
|
||||
ValueRemapperInputType_t
|
||||
ValueRemapperMomentumType_t
|
||||
ValueRemapperOutputType_t
|
||||
ValueRemapperRatchetType_t
|
||||
VectorExpressionType_t
|
||||
VectorFloatExpressionType_t
|
||||
VelocityMetricMode
|
||||
VertJustification_e
|
||||
ViewFadeMode_t
|
||||
VMixChannelOperation_t
|
||||
VMixFilterSlope_t
|
||||
VMixFilterType_t
|
||||
VMixLFOShape_t
|
||||
VMixPannerType_t
|
||||
VMixProcessorType_t
|
||||
VMixSubgraphSwitchInterpolationType_t
|
||||
vote_create_failed_t
|
||||
VPhysXAggregateData_t__VPhysXFlagEnum_t
|
||||
VPhysXBodyPart_t__VPhysXFlagEnum_t
|
||||
VPhysXConstraintParams_t__EnumFlags0_t
|
||||
VPhysXJoint_t__Flags_t
|
||||
WaterLevel_t
|
||||
WeaponAttackType_t
|
||||
WeaponSound_t
|
||||
WeaponSwitchReason_t
|
||||
WorldTextPanelHorizontalAlign_t
|
||||
WorldTextPanelOrientation_t
|
||||
WorldTextPanelVerticalAlign_t
|
||||
5
docfx/examples/WithUserMessages.md
Normal file
5
docfx/examples/WithUserMessages.md
Normal file
@@ -0,0 +1,5 @@
|
||||
[!INCLUDE [WithUserMessages](../../examples/WithUserMessages/README.md)]
|
||||
|
||||
<a href="https://github.com/roflmuffin/CounterStrikeSharp/tree/main/examples/WithUserMessages" class="btn btn-secondary">View project on Github <i class="bi bi-github"></i></a>
|
||||
|
||||
[!code-csharp[](../../examples/WithUserMessages/WithUserMessagesPlugin.cs)]
|
||||
@@ -19,6 +19,8 @@ items:
|
||||
href: WithSharedTypes.md
|
||||
- name: Translations
|
||||
href: WithTranslations.md
|
||||
- name: User Messages
|
||||
href: WithUserMessages.md
|
||||
- name: Voice Overrides
|
||||
href: WithVoiceOverrides.md
|
||||
- name: Warcraft Plugin
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System.Globalization;
|
||||
using System.Globalization;
|
||||
using CounterStrikeSharp.API;
|
||||
using CounterStrikeSharp.API.Core;
|
||||
using CounterStrikeSharp.API.Core.Attributes;
|
||||
@@ -22,18 +22,29 @@ public class WithTranslationsPlugin : BasePlugin
|
||||
// A global `Localizer` is provided on the plugin instance.
|
||||
// You can also use dependency injection to inject `IStringLocalizer` in your own services.
|
||||
Logger.LogInformation("This message is in the server language: {Message}", Localizer["test.translation"]);
|
||||
|
||||
|
||||
// IStringLocalizer can accept standard string format arguments.
|
||||
// "This number has 2 decimal places {0:n2}" -> "This number has 2 decimal places 123.55"
|
||||
Logger.LogInformation(Localizer["test.format", 123.551]);
|
||||
|
||||
|
||||
// This message has colour codes
|
||||
Server.PrintToChatAll(Localizer["test.colors"]);
|
||||
|
||||
// This message has colour codes and formatted values
|
||||
Server.PrintToChatAll(Localizer["test.colors.withformat", 123.551]);
|
||||
|
||||
// This prints the message to all players in their respective language
|
||||
PrintToAllPlayersLocalized("test.format", 123.456);
|
||||
}
|
||||
|
||||
|
||||
void PrintToAllPlayersLocalized(string key, params object[] args)
|
||||
{
|
||||
foreach (var player in Utilities.GetPlayers().Where(x => x.IsValid))
|
||||
{
|
||||
player.PrintToChat(Localizer.ForPlayer(player, key, args));
|
||||
}
|
||||
}
|
||||
|
||||
[ConsoleCommand("css_replylanguage", "Test Translations")]
|
||||
public void OnCommandReplyLanguage(CCSPlayerController? player, CommandInfo command)
|
||||
{
|
||||
|
||||
2
examples/WithUserMessages/README.md
Normal file
2
examples/WithUserMessages/README.md
Normal file
@@ -0,0 +1,2 @@
|
||||
# With User Messages
|
||||
This is example shows how you can hook, interrupt and send User Messages.
|
||||
12
examples/WithUserMessages/WithUserMessages.csproj
Normal file
12
examples/WithUserMessages/WithUserMessages.csproj
Normal file
@@ -0,0 +1,12 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||
<CopyLocalLockFileAssemblies>false</CopyLocalLockFileAssemblies>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\managed\CounterStrikeSharp.API\CounterStrikeSharp.API.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
84
examples/WithUserMessages/WithUserMessagesPlugin.cs
Normal file
84
examples/WithUserMessages/WithUserMessagesPlugin.cs
Normal file
@@ -0,0 +1,84 @@
|
||||
using CounterStrikeSharp.API.Core;
|
||||
using CounterStrikeSharp.API.Core.Attributes;
|
||||
using CounterStrikeSharp.API.Core.Attributes.Registration;
|
||||
using CounterStrikeSharp.API.Modules.Commands;
|
||||
using CounterStrikeSharp.API.Modules.UserMessages;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace WithUserMessages;
|
||||
|
||||
[MinimumApiVersion(80)]
|
||||
public class WithUserMessagesPlugin : BasePlugin
|
||||
{
|
||||
public override string ModuleName => "Example: With User Messages";
|
||||
public override string ModuleVersion => "1.0.0";
|
||||
public override string ModuleAuthor => "CounterStrikeSharp & Contributors";
|
||||
public override string ModuleDescription => "A simple plugin that hooks and sends User Messages";
|
||||
|
||||
public override void Load(bool hotReload)
|
||||
{
|
||||
// Hooks can be added using the user message ID. In this case it's the ID for `CMsgTEFireBullets`.
|
||||
HookUserMessage(452, um =>
|
||||
{
|
||||
// Sets all weapon sounds to the sound of a silenced usp.
|
||||
um.SetUInt("weapon_id", 0);
|
||||
um.SetInt("sound_type", 9);
|
||||
um.SetUInt("item_def_index", 61);
|
||||
|
||||
return HookResult.Continue;
|
||||
}, HookMode.Pre);
|
||||
|
||||
HookUserMessage(118, um =>
|
||||
{
|
||||
var author = um.ReadString("param1");
|
||||
var message = um.ReadString("param2");
|
||||
Logger.LogInformation("Chat message from {Author}: {Message}", author, message);
|
||||
|
||||
for (var i = 0; i < um.Recipients.Count; i++)
|
||||
{
|
||||
Logger.LogInformation("Recipient {Index}: {Name}", i, um.Recipients[i].PlayerName);
|
||||
}
|
||||
|
||||
if (message.Contains("stop"))
|
||||
{
|
||||
return HookResult.Stop;
|
||||
}
|
||||
|
||||
if (message.Contains("skip"))
|
||||
{
|
||||
um.Recipients.Clear();
|
||||
}
|
||||
|
||||
return HookResult.Continue;
|
||||
});
|
||||
}
|
||||
|
||||
[ConsoleCommand("css_shake")]
|
||||
public void OnCommandShake(CCSPlayerController? player, CommandInfo command)
|
||||
{
|
||||
if (player == null) return;
|
||||
|
||||
// UserMessage.FromPartialName is a helper method that creates a UserMessage object from a partial network name.
|
||||
// In this case, it will resolve to `CUserMessageShake`.
|
||||
var message = UserMessage.FromPartialName("Shake");
|
||||
|
||||
message.SetFloat("duration", 2);
|
||||
message.SetFloat("amplitude", 5);
|
||||
message.SetFloat("frequency", 10f);
|
||||
message.SetInt("command", 0);
|
||||
|
||||
if (command.GetArg(1) == "all")
|
||||
{
|
||||
message.Recipients.AddAllPlayers();
|
||||
}
|
||||
else
|
||||
{
|
||||
message.Recipients.Add(player);
|
||||
}
|
||||
|
||||
message.Send();
|
||||
|
||||
// You can also use an overload of `Send` to send the message to a specific player without manually creating a recipient filter.
|
||||
// message.Send(player);
|
||||
}
|
||||
}
|
||||
Submodule libraries/hl2sdk-cs2 updated: 4b31db7505...0b862d725a
@@ -1,5 +1,4 @@
|
||||
#set(_ITERATOR_DEBUG_LEVEL 2)
|
||||
add_definitions(-D_LINUX -DPOSIX -DLINUX -DGNUC -DCOMPILER_GCC -DPLATFORM_64BITS -D_FILE_OFFSET_BITS=64)
|
||||
add_definitions(-D_LINUX -DPOSIX -DLINUX -DGNUC -DCOMPILER_GCC -DPLATFORM_64BITS -D_FILE_OFFSET_BITS=64 -D_GLIBCXX_USE_CXX11_ABI=0)
|
||||
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Dstricmp=strcasecmp -D_stricmp=strcasecmp -D_strnicmp=strncasecmp")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Dstrnicmp=strncasecmp -D_snprintf=snprintf")
|
||||
@@ -16,6 +15,7 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mfpmath=sse -msse -fno-strict-aliasing"
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-threadsafe-statics -v -fvisibility=default")
|
||||
|
||||
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -static-libgcc -static-libstdc++")
|
||||
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--exclude-libs=libprotobuf.a")
|
||||
|
||||
set(
|
||||
COUNTER_STRIKE_SHARP_LINK_LIBRARIES
|
||||
|
||||
59
makefiles/protobuf.cmake
Normal file
59
makefiles/protobuf.cmake
Normal file
@@ -0,0 +1,59 @@
|
||||
# Credit for this protobuf generation cmake file goes to Poggicek.
|
||||
# Based on their work at https://github.com/Poggicek/StickerInspect
|
||||
|
||||
set(PROTO_TARGETS
|
||||
${PROJECT_SOURCE_DIR}/libraries/Protobufs/csgo/network_connection.proto
|
||||
${PROJECT_SOURCE_DIR}/libraries/Protobufs/csgo/networkbasetypes.proto
|
||||
${PROJECT_SOURCE_DIR}/libraries/Protobufs/csgo/cs_gameevents.proto
|
||||
${PROJECT_SOURCE_DIR}/libraries/Protobufs/csgo/engine_gcmessages.proto
|
||||
${PROJECT_SOURCE_DIR}/libraries/Protobufs/csgo/gcsdk_gcmessages.proto
|
||||
${PROJECT_SOURCE_DIR}/libraries/Protobufs/csgo/cstrike15_gcmessages.proto
|
||||
${PROJECT_SOURCE_DIR}/libraries/Protobufs/csgo/cstrike15_usermessages.proto
|
||||
${PROJECT_SOURCE_DIR}/libraries/Protobufs/csgo/netmessages.proto
|
||||
${PROJECT_SOURCE_DIR}/libraries/Protobufs/csgo/steammessages.proto
|
||||
${PROJECT_SOURCE_DIR}/libraries/Protobufs/csgo/usermessages.proto
|
||||
${PROJECT_SOURCE_DIR}/libraries/Protobufs/csgo/gameevents.proto
|
||||
${PROJECT_SOURCE_DIR}/libraries/Protobufs/csgo/clientmessages.proto
|
||||
${PROJECT_SOURCE_DIR}/libraries/Protobufs/csgo/te.proto
|
||||
)
|
||||
|
||||
if(UNIX)
|
||||
set(PROTOC_EXECUTABLE ${PROJECT_SOURCE_DIR}/libraries/hl2sdk-cs2/devtools/bin/linux/protoc)
|
||||
elseif(WIN32)
|
||||
set(PROTOC_EXECUTABLE ${PROJECT_SOURCE_DIR}/libraries/hl2sdk-cs2/devtools/bin/protoc.exe)
|
||||
endif()
|
||||
|
||||
foreach(PROTO_TARGET ${PROTO_TARGETS})
|
||||
get_filename_component(PROTO_FILENAME ${PROTO_TARGET} NAME_WLE)
|
||||
list(APPEND PROTO_OUTPUT ${PROTO_FILENAME}.pb.cc ${PROTO_FILENAME}.pb.h)
|
||||
list(APPEND PROTO_INPUT ${PROTO_FILENAME}.proto)
|
||||
get_filename_component(PROTO_PATH ${PROTO_TARGET} DIRECTORY)
|
||||
list(APPEND PROTO_PATHS "--proto_path=${PROTO_PATH}")
|
||||
endforeach()
|
||||
|
||||
list(REMOVE_DUPLICATES PROTO_PATHS)
|
||||
list(TRANSFORM PROTO_OUTPUT PREPEND ${CMAKE_CURRENT_BINARY_DIR}/protobufcompiler/)
|
||||
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/protobufcompiler)
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT ${PROTO_OUTPUT}
|
||||
COMMAND "${PROTOC_EXECUTABLE}" -I ${PROJECT_SOURCE_DIR}/libraries/hl2sdk-cs2/thirdparty/protobuf-3.21.8/src --proto_path=${PROJECT_SOURCE_DIR}/libraries/Protobufs/csgo ${PROTO_PATHS} --cpp_out=${CMAKE_CURRENT_BINARY_DIR}/protobufcompiler ${PROTO_INPUT}
|
||||
COMMENT "Generating protobuf file"
|
||||
)
|
||||
|
||||
add_library(Protobufs STATIC
|
||||
${PROTO_OUTPUT}
|
||||
)
|
||||
|
||||
target_include_directories(Protobufs
|
||||
PUBLIC ${CMAKE_CURRENT_BINARY_DIR}/protobufcompiler
|
||||
PUBLIC ${PROJECT_SOURCE_DIR}/libraries/hl2sdk-cs2/thirdparty/protobuf-3.21.8/src
|
||||
)
|
||||
|
||||
if(WIN32)
|
||||
target_link_libraries(Protobufs PUBLIC ${PROJECT_SOURCE_DIR}/libraries/hl2sdk-cs2/lib/public/win64/2015/libprotobuf.lib)
|
||||
elseif(UNIX)
|
||||
target_link_libraries(Protobufs PUBLIC ${PROJECT_SOURCE_DIR}/libraries/hl2sdk-cs2/lib/linux64/release/libprotobuf.a)
|
||||
endif()
|
||||
set_target_properties(Protobufs PROPERTIES LINKER_LANGUAGE CXX)
|
||||
set_target_properties(Protobufs PROPERTIES FOLDER SDK)
|
||||
@@ -20,13 +20,14 @@ endif()
|
||||
|
||||
set(CMAKE_STATIC_LIBRARY_PREFIX "")
|
||||
|
||||
set(LIBRARIES_DIR ${CMAKE_CURRENT_SOURCE_DIR}/libraries)
|
||||
set(SOURCESDK_DIR ${CMAKE_CURRENT_SOURCE_DIR}/libraries/hl2sdk-cs2)
|
||||
set(METAMOD_DIR ${CMAKE_CURRENT_SOURCE_DIR}/libraries/metamod-source)
|
||||
|
||||
set(SOURCESDK ${SOURCESDK_DIR}/${BRANCH})
|
||||
set(SOURCESDK_LIB ${SOURCESDK}/lib)
|
||||
|
||||
add_definitions(-DMETA_IS_SOURCE2)
|
||||
add_definitions(-DMETA_IS_SOURCE2 -D_ITERATOR_DEBUG_LEVEL=0)
|
||||
|
||||
if(DEFINED ENV{GITHUB_SHA_SHORT})
|
||||
add_definitions(-DGITHUB_SHA="$ENV{GITHUB_SHA_SHORT}")
|
||||
@@ -40,6 +41,10 @@ else()
|
||||
add_definitions(-DBUILD_NUMBER="0")
|
||||
endif()
|
||||
|
||||
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
||||
add_compile_definitions(_GLIBCXX_USE_CXX11_ABI=0)
|
||||
endif()
|
||||
|
||||
include_directories(
|
||||
${SOURCESDK}
|
||||
${SOURCESDK}/thirdparty/protobuf-3.21.8/src
|
||||
@@ -68,3 +73,5 @@ include_directories(
|
||||
)
|
||||
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/metamod/configure_metamod.cmake)
|
||||
|
||||
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
|
||||
using System;
|
||||
using CounterStrikeSharp.API.Modules.Memory;
|
||||
using CounterStrikeSharp.API.Modules.UserMessages;
|
||||
using CounterStrikeSharp.API.Modules.Commands;
|
||||
using CounterStrikeSharp.API.Modules.Utils;
|
||||
|
||||
namespace CounterStrikeSharp.API.Core
|
||||
{
|
||||
@@ -558,6 +560,17 @@ namespace CounterStrikeSharp.API.Core
|
||||
}
|
||||
}
|
||||
|
||||
public static void DisconnectClient(int slot, int reason){
|
||||
lock (ScriptContext.GlobalScriptContext.Lock) {
|
||||
ScriptContext.GlobalScriptContext.Reset();
|
||||
ScriptContext.GlobalScriptContext.Push(slot);
|
||||
ScriptContext.GlobalScriptContext.Push(reason);
|
||||
ScriptContext.GlobalScriptContext.SetIdentifier(0x799EE9C3);
|
||||
ScriptContext.GlobalScriptContext.Invoke();
|
||||
ScriptContext.GlobalScriptContext.CheckErrors();
|
||||
}
|
||||
}
|
||||
|
||||
public static IntPtr GetEntityFromIndex(int index){
|
||||
lock (ScriptContext.GlobalScriptContext.Lock) {
|
||||
ScriptContext.GlobalScriptContext.Reset();
|
||||
@@ -1243,6 +1256,375 @@ namespace CounterStrikeSharp.API.Core
|
||||
}
|
||||
}
|
||||
|
||||
public static void HookUsermessage(int messageid, InputArgument callback, HookMode mode){
|
||||
lock (ScriptContext.GlobalScriptContext.Lock) {
|
||||
ScriptContext.GlobalScriptContext.Reset();
|
||||
ScriptContext.GlobalScriptContext.Push(messageid);
|
||||
ScriptContext.GlobalScriptContext.Push((InputArgument)callback);
|
||||
ScriptContext.GlobalScriptContext.Push(mode);
|
||||
ScriptContext.GlobalScriptContext.SetIdentifier(0x76C63A83);
|
||||
ScriptContext.GlobalScriptContext.Invoke();
|
||||
ScriptContext.GlobalScriptContext.CheckErrors();
|
||||
}
|
||||
}
|
||||
|
||||
public static void UnhookUsermessage(int messageid, InputArgument callback, HookMode mode){
|
||||
lock (ScriptContext.GlobalScriptContext.Lock) {
|
||||
ScriptContext.GlobalScriptContext.Reset();
|
||||
ScriptContext.GlobalScriptContext.Push(messageid);
|
||||
ScriptContext.GlobalScriptContext.Push((InputArgument)callback);
|
||||
ScriptContext.GlobalScriptContext.Push(mode);
|
||||
ScriptContext.GlobalScriptContext.SetIdentifier(0x63B0AC38);
|
||||
ScriptContext.GlobalScriptContext.Invoke();
|
||||
ScriptContext.GlobalScriptContext.CheckErrors();
|
||||
}
|
||||
}
|
||||
|
||||
public static bool PbHasfield(UserMessage message, string name){
|
||||
lock (ScriptContext.GlobalScriptContext.Lock) {
|
||||
ScriptContext.GlobalScriptContext.Reset();
|
||||
ScriptContext.GlobalScriptContext.Push(message);
|
||||
ScriptContext.GlobalScriptContext.Push(name);
|
||||
ScriptContext.GlobalScriptContext.SetIdentifier(0xC971FB70);
|
||||
ScriptContext.GlobalScriptContext.Invoke();
|
||||
ScriptContext.GlobalScriptContext.CheckErrors();
|
||||
return (bool)ScriptContext.GlobalScriptContext.GetResult(typeof(bool));
|
||||
}
|
||||
}
|
||||
|
||||
public static int PbReadint(UserMessage message, string name, int index){
|
||||
lock (ScriptContext.GlobalScriptContext.Lock) {
|
||||
ScriptContext.GlobalScriptContext.Reset();
|
||||
ScriptContext.GlobalScriptContext.Push(message);
|
||||
ScriptContext.GlobalScriptContext.Push(name);
|
||||
ScriptContext.GlobalScriptContext.Push(index);
|
||||
ScriptContext.GlobalScriptContext.SetIdentifier(0x5FA8BDC9);
|
||||
ScriptContext.GlobalScriptContext.Invoke();
|
||||
ScriptContext.GlobalScriptContext.CheckErrors();
|
||||
return (int)ScriptContext.GlobalScriptContext.GetResult(typeof(int));
|
||||
}
|
||||
}
|
||||
|
||||
public static long PbReadint64(UserMessage message, string name, int index){
|
||||
lock (ScriptContext.GlobalScriptContext.Lock) {
|
||||
ScriptContext.GlobalScriptContext.Reset();
|
||||
ScriptContext.GlobalScriptContext.Push(message);
|
||||
ScriptContext.GlobalScriptContext.Push(name);
|
||||
ScriptContext.GlobalScriptContext.Push(index);
|
||||
ScriptContext.GlobalScriptContext.SetIdentifier(0xECCF528B);
|
||||
ScriptContext.GlobalScriptContext.Invoke();
|
||||
ScriptContext.GlobalScriptContext.CheckErrors();
|
||||
return (long)ScriptContext.GlobalScriptContext.GetResult(typeof(long));
|
||||
}
|
||||
}
|
||||
|
||||
public static float PbReadfloat(UserMessage message, string name, int index){
|
||||
lock (ScriptContext.GlobalScriptContext.Lock) {
|
||||
ScriptContext.GlobalScriptContext.Reset();
|
||||
ScriptContext.GlobalScriptContext.Push(message);
|
||||
ScriptContext.GlobalScriptContext.Push(name);
|
||||
ScriptContext.GlobalScriptContext.Push(index);
|
||||
ScriptContext.GlobalScriptContext.SetIdentifier(0xED208CEA);
|
||||
ScriptContext.GlobalScriptContext.Invoke();
|
||||
ScriptContext.GlobalScriptContext.CheckErrors();
|
||||
return (float)ScriptContext.GlobalScriptContext.GetResult(typeof(float));
|
||||
}
|
||||
}
|
||||
|
||||
public static bool PbReadbool(UserMessage message, string name, int index){
|
||||
lock (ScriptContext.GlobalScriptContext.Lock) {
|
||||
ScriptContext.GlobalScriptContext.Reset();
|
||||
ScriptContext.GlobalScriptContext.Push(message);
|
||||
ScriptContext.GlobalScriptContext.Push(name);
|
||||
ScriptContext.GlobalScriptContext.Push(index);
|
||||
ScriptContext.GlobalScriptContext.SetIdentifier(0x54C0D7F4);
|
||||
ScriptContext.GlobalScriptContext.Invoke();
|
||||
ScriptContext.GlobalScriptContext.CheckErrors();
|
||||
return (bool)ScriptContext.GlobalScriptContext.GetResult(typeof(bool));
|
||||
}
|
||||
}
|
||||
|
||||
public static string PbReadstring(UserMessage message, string name, int index){
|
||||
lock (ScriptContext.GlobalScriptContext.Lock) {
|
||||
ScriptContext.GlobalScriptContext.Reset();
|
||||
ScriptContext.GlobalScriptContext.Push(message);
|
||||
ScriptContext.GlobalScriptContext.Push(name);
|
||||
ScriptContext.GlobalScriptContext.Push(index);
|
||||
ScriptContext.GlobalScriptContext.SetIdentifier(0x66CACEEF);
|
||||
ScriptContext.GlobalScriptContext.Invoke();
|
||||
ScriptContext.GlobalScriptContext.CheckErrors();
|
||||
return (string)ScriptContext.GlobalScriptContext.GetResult(typeof(string));
|
||||
}
|
||||
}
|
||||
|
||||
public static int PbGetrepeatedfieldcount(UserMessage message, string name){
|
||||
lock (ScriptContext.GlobalScriptContext.Lock) {
|
||||
ScriptContext.GlobalScriptContext.Reset();
|
||||
ScriptContext.GlobalScriptContext.Push(message);
|
||||
ScriptContext.GlobalScriptContext.Push(name);
|
||||
ScriptContext.GlobalScriptContext.SetIdentifier(0xDE4E1549);
|
||||
ScriptContext.GlobalScriptContext.Invoke();
|
||||
ScriptContext.GlobalScriptContext.CheckErrors();
|
||||
return (int)ScriptContext.GlobalScriptContext.GetResult(typeof(int));
|
||||
}
|
||||
}
|
||||
|
||||
public static void PbSetint(UserMessage message, string name, int value, int index){
|
||||
lock (ScriptContext.GlobalScriptContext.Lock) {
|
||||
ScriptContext.GlobalScriptContext.Reset();
|
||||
ScriptContext.GlobalScriptContext.Push(message);
|
||||
ScriptContext.GlobalScriptContext.Push(name);
|
||||
ScriptContext.GlobalScriptContext.Push(value);
|
||||
ScriptContext.GlobalScriptContext.Push(index);
|
||||
ScriptContext.GlobalScriptContext.SetIdentifier(0x99BBC059);
|
||||
ScriptContext.GlobalScriptContext.Invoke();
|
||||
ScriptContext.GlobalScriptContext.CheckErrors();
|
||||
}
|
||||
}
|
||||
|
||||
public static void PbSetint64(UserMessage message, string name, long value, int index){
|
||||
lock (ScriptContext.GlobalScriptContext.Lock) {
|
||||
ScriptContext.GlobalScriptContext.Reset();
|
||||
ScriptContext.GlobalScriptContext.Push(message);
|
||||
ScriptContext.GlobalScriptContext.Push(name);
|
||||
ScriptContext.GlobalScriptContext.Push(value);
|
||||
ScriptContext.GlobalScriptContext.Push(index);
|
||||
ScriptContext.GlobalScriptContext.SetIdentifier(0xF7AD351B);
|
||||
ScriptContext.GlobalScriptContext.Invoke();
|
||||
ScriptContext.GlobalScriptContext.CheckErrors();
|
||||
}
|
||||
}
|
||||
|
||||
public static void PbSetfloat(UserMessage message, string name, float value, int index){
|
||||
lock (ScriptContext.GlobalScriptContext.Lock) {
|
||||
ScriptContext.GlobalScriptContext.Reset();
|
||||
ScriptContext.GlobalScriptContext.Push(message);
|
||||
ScriptContext.GlobalScriptContext.Push(name);
|
||||
ScriptContext.GlobalScriptContext.Push(value);
|
||||
ScriptContext.GlobalScriptContext.Push(index);
|
||||
ScriptContext.GlobalScriptContext.SetIdentifier(0xF7FDEB7A);
|
||||
ScriptContext.GlobalScriptContext.Invoke();
|
||||
ScriptContext.GlobalScriptContext.CheckErrors();
|
||||
}
|
||||
}
|
||||
|
||||
public static void PbSetbool(UserMessage message, string name, bool value, int index){
|
||||
lock (ScriptContext.GlobalScriptContext.Lock) {
|
||||
ScriptContext.GlobalScriptContext.Reset();
|
||||
ScriptContext.GlobalScriptContext.Push(message);
|
||||
ScriptContext.GlobalScriptContext.Push(name);
|
||||
ScriptContext.GlobalScriptContext.Push(value);
|
||||
ScriptContext.GlobalScriptContext.Push(index);
|
||||
ScriptContext.GlobalScriptContext.SetIdentifier(0xD1342864);
|
||||
ScriptContext.GlobalScriptContext.Invoke();
|
||||
ScriptContext.GlobalScriptContext.CheckErrors();
|
||||
}
|
||||
}
|
||||
|
||||
public static void PbSetstring(UserMessage message, string name, string value, int index){
|
||||
lock (ScriptContext.GlobalScriptContext.Lock) {
|
||||
ScriptContext.GlobalScriptContext.Reset();
|
||||
ScriptContext.GlobalScriptContext.Push(message);
|
||||
ScriptContext.GlobalScriptContext.Push(name);
|
||||
ScriptContext.GlobalScriptContext.Push(value);
|
||||
ScriptContext.GlobalScriptContext.Push(index);
|
||||
ScriptContext.GlobalScriptContext.SetIdentifier(0x15C78B7F);
|
||||
ScriptContext.GlobalScriptContext.Invoke();
|
||||
ScriptContext.GlobalScriptContext.CheckErrors();
|
||||
}
|
||||
}
|
||||
|
||||
public static void PbAddint(UserMessage message, string name, int value){
|
||||
lock (ScriptContext.GlobalScriptContext.Lock) {
|
||||
ScriptContext.GlobalScriptContext.Reset();
|
||||
ScriptContext.GlobalScriptContext.Push(message);
|
||||
ScriptContext.GlobalScriptContext.Push(name);
|
||||
ScriptContext.GlobalScriptContext.Push(value);
|
||||
ScriptContext.GlobalScriptContext.SetIdentifier(0x66CD6A1A);
|
||||
ScriptContext.GlobalScriptContext.Invoke();
|
||||
ScriptContext.GlobalScriptContext.CheckErrors();
|
||||
}
|
||||
}
|
||||
|
||||
public static void PbAddint64(UserMessage message, string name, object value){
|
||||
lock (ScriptContext.GlobalScriptContext.Lock) {
|
||||
ScriptContext.GlobalScriptContext.Reset();
|
||||
ScriptContext.GlobalScriptContext.Push(message);
|
||||
ScriptContext.GlobalScriptContext.Push(name);
|
||||
ScriptContext.GlobalScriptContext.Push(value);
|
||||
ScriptContext.GlobalScriptContext.SetIdentifier(0x4FD05AD8);
|
||||
ScriptContext.GlobalScriptContext.Invoke();
|
||||
ScriptContext.GlobalScriptContext.CheckErrors();
|
||||
}
|
||||
}
|
||||
|
||||
public static void PbAddfloat(UserMessage message, string name, float value){
|
||||
lock (ScriptContext.GlobalScriptContext.Lock) {
|
||||
ScriptContext.GlobalScriptContext.Reset();
|
||||
ScriptContext.GlobalScriptContext.Push(message);
|
||||
ScriptContext.GlobalScriptContext.Push(name);
|
||||
ScriptContext.GlobalScriptContext.Push(value);
|
||||
ScriptContext.GlobalScriptContext.SetIdentifier(0x5117B239);
|
||||
ScriptContext.GlobalScriptContext.Invoke();
|
||||
ScriptContext.GlobalScriptContext.CheckErrors();
|
||||
}
|
||||
}
|
||||
|
||||
public static void PbAddbool(UserMessage message, string name, bool value){
|
||||
lock (ScriptContext.GlobalScriptContext.Lock) {
|
||||
ScriptContext.GlobalScriptContext.Reset();
|
||||
ScriptContext.GlobalScriptContext.Push(message);
|
||||
ScriptContext.GlobalScriptContext.Push(name);
|
||||
ScriptContext.GlobalScriptContext.Push(value);
|
||||
ScriptContext.GlobalScriptContext.SetIdentifier(0x40827C47);
|
||||
ScriptContext.GlobalScriptContext.Invoke();
|
||||
ScriptContext.GlobalScriptContext.CheckErrors();
|
||||
}
|
||||
}
|
||||
|
||||
public static void PbAddstring(UserMessage message, string name, string value){
|
||||
lock (ScriptContext.GlobalScriptContext.Lock) {
|
||||
ScriptContext.GlobalScriptContext.Reset();
|
||||
ScriptContext.GlobalScriptContext.Push(message);
|
||||
ScriptContext.GlobalScriptContext.Push(name);
|
||||
ScriptContext.GlobalScriptContext.Push(value);
|
||||
ScriptContext.GlobalScriptContext.SetIdentifier(0x8DFD739C);
|
||||
ScriptContext.GlobalScriptContext.Invoke();
|
||||
ScriptContext.GlobalScriptContext.CheckErrors();
|
||||
}
|
||||
}
|
||||
|
||||
public static void PbRemoverepeatedfieldvalue(UserMessage message, string name, int index){
|
||||
lock (ScriptContext.GlobalScriptContext.Lock) {
|
||||
ScriptContext.GlobalScriptContext.Reset();
|
||||
ScriptContext.GlobalScriptContext.Push(message);
|
||||
ScriptContext.GlobalScriptContext.Push(name);
|
||||
ScriptContext.GlobalScriptContext.Push(index);
|
||||
ScriptContext.GlobalScriptContext.SetIdentifier(0x1721FCB1);
|
||||
ScriptContext.GlobalScriptContext.Invoke();
|
||||
ScriptContext.GlobalScriptContext.CheckErrors();
|
||||
}
|
||||
}
|
||||
|
||||
public static string PbGetdebugstring(UserMessage message){
|
||||
lock (ScriptContext.GlobalScriptContext.Lock) {
|
||||
ScriptContext.GlobalScriptContext.Reset();
|
||||
ScriptContext.GlobalScriptContext.Push(message);
|
||||
ScriptContext.GlobalScriptContext.SetIdentifier(0x913FB7BA);
|
||||
ScriptContext.GlobalScriptContext.Invoke();
|
||||
ScriptContext.GlobalScriptContext.CheckErrors();
|
||||
return (string)ScriptContext.GlobalScriptContext.GetResult(typeof(string));
|
||||
}
|
||||
}
|
||||
|
||||
public static ulong UsermessageGetrecipients(UserMessage message){
|
||||
lock (ScriptContext.GlobalScriptContext.Lock) {
|
||||
ScriptContext.GlobalScriptContext.Reset();
|
||||
ScriptContext.GlobalScriptContext.Push(message);
|
||||
ScriptContext.GlobalScriptContext.SetIdentifier(0x70CDDEBE);
|
||||
ScriptContext.GlobalScriptContext.Invoke();
|
||||
ScriptContext.GlobalScriptContext.CheckErrors();
|
||||
return (ulong)ScriptContext.GlobalScriptContext.GetResult(typeof(ulong));
|
||||
}
|
||||
}
|
||||
|
||||
public static void UsermessageSetrecipients(UserMessage message, ulong recipients){
|
||||
lock (ScriptContext.GlobalScriptContext.Lock) {
|
||||
ScriptContext.GlobalScriptContext.Reset();
|
||||
ScriptContext.GlobalScriptContext.Push(message);
|
||||
ScriptContext.GlobalScriptContext.Push(recipients);
|
||||
ScriptContext.GlobalScriptContext.SetIdentifier(0xB4ED43AA);
|
||||
ScriptContext.GlobalScriptContext.Invoke();
|
||||
ScriptContext.GlobalScriptContext.CheckErrors();
|
||||
}
|
||||
}
|
||||
|
||||
public static int UsermessageFindmessageidbyname(string name){
|
||||
lock (ScriptContext.GlobalScriptContext.Lock) {
|
||||
ScriptContext.GlobalScriptContext.Reset();
|
||||
ScriptContext.GlobalScriptContext.Push(name);
|
||||
ScriptContext.GlobalScriptContext.SetIdentifier(0x22CD6C9F);
|
||||
ScriptContext.GlobalScriptContext.Invoke();
|
||||
ScriptContext.GlobalScriptContext.CheckErrors();
|
||||
return (int)ScriptContext.GlobalScriptContext.GetResult(typeof(int));
|
||||
}
|
||||
}
|
||||
|
||||
public static IntPtr UsermessageCreate(string name){
|
||||
lock (ScriptContext.GlobalScriptContext.Lock) {
|
||||
ScriptContext.GlobalScriptContext.Reset();
|
||||
ScriptContext.GlobalScriptContext.Push(name);
|
||||
ScriptContext.GlobalScriptContext.SetIdentifier(0xE8E83344);
|
||||
ScriptContext.GlobalScriptContext.Invoke();
|
||||
ScriptContext.GlobalScriptContext.CheckErrors();
|
||||
return (IntPtr)ScriptContext.GlobalScriptContext.GetResult(typeof(IntPtr));
|
||||
}
|
||||
}
|
||||
|
||||
public static IntPtr UsermessageCreatebyid(int id){
|
||||
lock (ScriptContext.GlobalScriptContext.Lock) {
|
||||
ScriptContext.GlobalScriptContext.Reset();
|
||||
ScriptContext.GlobalScriptContext.Push(id);
|
||||
ScriptContext.GlobalScriptContext.SetIdentifier(0xBC758632);
|
||||
ScriptContext.GlobalScriptContext.Invoke();
|
||||
ScriptContext.GlobalScriptContext.CheckErrors();
|
||||
return (IntPtr)ScriptContext.GlobalScriptContext.GetResult(typeof(IntPtr));
|
||||
}
|
||||
}
|
||||
|
||||
public static void UsermessageSend(UserMessage message){
|
||||
lock (ScriptContext.GlobalScriptContext.Lock) {
|
||||
ScriptContext.GlobalScriptContext.Reset();
|
||||
ScriptContext.GlobalScriptContext.Push(message);
|
||||
ScriptContext.GlobalScriptContext.SetIdentifier(0x24EB6B3C);
|
||||
ScriptContext.GlobalScriptContext.Invoke();
|
||||
ScriptContext.GlobalScriptContext.CheckErrors();
|
||||
}
|
||||
}
|
||||
|
||||
public static void UsermessageDelete(UserMessage message){
|
||||
lock (ScriptContext.GlobalScriptContext.Lock) {
|
||||
ScriptContext.GlobalScriptContext.Reset();
|
||||
ScriptContext.GlobalScriptContext.Push(message);
|
||||
ScriptContext.GlobalScriptContext.SetIdentifier(0xE10465D9);
|
||||
ScriptContext.GlobalScriptContext.Invoke();
|
||||
ScriptContext.GlobalScriptContext.CheckErrors();
|
||||
}
|
||||
}
|
||||
|
||||
public static int UsermessageGetid(UserMessage message){
|
||||
lock (ScriptContext.GlobalScriptContext.Lock) {
|
||||
ScriptContext.GlobalScriptContext.Reset();
|
||||
ScriptContext.GlobalScriptContext.Push(message);
|
||||
ScriptContext.GlobalScriptContext.SetIdentifier(0xC17BA71B);
|
||||
ScriptContext.GlobalScriptContext.Invoke();
|
||||
ScriptContext.GlobalScriptContext.CheckErrors();
|
||||
return (int)ScriptContext.GlobalScriptContext.GetResult(typeof(int));
|
||||
}
|
||||
}
|
||||
|
||||
public static string UsermessageGetname(UserMessage message){
|
||||
lock (ScriptContext.GlobalScriptContext.Lock) {
|
||||
ScriptContext.GlobalScriptContext.Reset();
|
||||
ScriptContext.GlobalScriptContext.Push(message);
|
||||
ScriptContext.GlobalScriptContext.SetIdentifier(0xEFE0FD1);
|
||||
ScriptContext.GlobalScriptContext.Invoke();
|
||||
ScriptContext.GlobalScriptContext.CheckErrors();
|
||||
return (string)ScriptContext.GlobalScriptContext.GetResult(typeof(string));
|
||||
}
|
||||
}
|
||||
|
||||
public static string UsermessageGettype(UserMessage message){
|
||||
lock (ScriptContext.GlobalScriptContext.Lock) {
|
||||
ScriptContext.GlobalScriptContext.Reset();
|
||||
ScriptContext.GlobalScriptContext.Push(message);
|
||||
ScriptContext.GlobalScriptContext.SetIdentifier(0xEF4842E);
|
||||
ScriptContext.GlobalScriptContext.Invoke();
|
||||
ScriptContext.GlobalScriptContext.CheckErrors();
|
||||
return (string)ScriptContext.GlobalScriptContext.GetResult(typeof(string));
|
||||
}
|
||||
}
|
||||
|
||||
public static IntPtr VectorNew(){
|
||||
lock (ScriptContext.GlobalScriptContext.Lock) {
|
||||
ScriptContext.GlobalScriptContext.Reset();
|
||||
|
||||
@@ -156,17 +156,10 @@ namespace CounterStrikeSharp.API.Core
|
||||
break;
|
||||
}
|
||||
|
||||
// If our arugment doesn't end in ".dll" - try and construct a path similar to PluginName/PluginName.dll.
|
||||
// If our argument doesn't end in ".dll" - try and construct a path similar to PluginName/PluginName.dll.
|
||||
// We'll assume we have a full path if we have ".dll".
|
||||
var path = info.GetArg(2);
|
||||
if (!path.EndsWith(".dll"))
|
||||
{
|
||||
path = Path.Combine(_scriptHostConfiguration.RootPath, $"plugins/{path}/{path}.dll");
|
||||
}
|
||||
else
|
||||
{
|
||||
path = Path.Combine(_scriptHostConfiguration.RootPath, path);
|
||||
}
|
||||
path = Path.Combine(_scriptHostConfiguration.RootPath, !path.EndsWith(".dll") ? $"plugins/{path}/{path}.dll" : path);
|
||||
|
||||
var plugin = _pluginContextQueryHandler.FindPluginByModulePath(path);
|
||||
|
||||
@@ -204,7 +197,13 @@ namespace CounterStrikeSharp.API.Core
|
||||
}
|
||||
|
||||
var pluginIdentifier = info.GetArg(2);
|
||||
IPluginContext? plugin = _pluginContextQueryHandler.FindPluginByIdOrName(pluginIdentifier);
|
||||
string path;
|
||||
path = Path.Combine(_scriptHostConfiguration.RootPath,
|
||||
!pluginIdentifier.EndsWith(".dll") ? $"plugins/{pluginIdentifier}/{pluginIdentifier}.dll" : pluginIdentifier);
|
||||
|
||||
var plugin = _pluginContextQueryHandler.FindPluginByIdOrName(pluginIdentifier)
|
||||
?? _pluginContextQueryHandler.FindPluginByModulePath(path);
|
||||
|
||||
if (plugin == null)
|
||||
{
|
||||
info.ReplyToCommand($"Could not unload plugin \"{pluginIdentifier}\"");
|
||||
@@ -249,7 +248,7 @@ namespace CounterStrikeSharp.API.Core
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void OnLangCommand(CCSPlayerController? player, CommandInfo command)
|
||||
{
|
||||
if (player == null) return;
|
||||
@@ -305,4 +304,4 @@ namespace CounterStrikeSharp.API.Core
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ using CounterStrikeSharp.API.Modules.Timers;
|
||||
using CounterStrikeSharp.API.Modules.Config;
|
||||
using CounterStrikeSharp.API.Modules.Cvars;
|
||||
using CounterStrikeSharp.API.Modules.Entities;
|
||||
using CounterStrikeSharp.API.Modules.UserMessages;
|
||||
using Microsoft.Extensions.Localization;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
@@ -528,6 +529,24 @@ namespace CounterStrikeSharp.API.Core
|
||||
NativeAPI.HookEntityOutput(classname, outputName, subscriber.GetInputArgument(), mode);
|
||||
EntityOutputHooks[handler] = subscriber;
|
||||
}
|
||||
|
||||
public void HookUserMessage(int messageId, UserMessage.UserMessageHandler handler, HookMode mode = HookMode.Pre)
|
||||
{
|
||||
var subscriber = new CallbackSubscriber(handler, handler,
|
||||
() => UnhookUserMessage(messageId, handler));
|
||||
|
||||
NativeAPI.HookUsermessage(messageId, subscriber.GetInputArgument(), mode);
|
||||
Handlers[handler] = subscriber;
|
||||
}
|
||||
|
||||
public void UnhookUserMessage(int messageId, UserMessage.UserMessageHandler handler, HookMode mode = HookMode.Pre)
|
||||
{
|
||||
if (!Handlers.TryGetValue(handler, out var subscriber)) return;
|
||||
|
||||
NativeAPI.UnhookUsermessage(messageId, subscriber.GetInputArgument(), mode);
|
||||
FunctionReference.Remove(subscriber.GetReferenceIdentifier());
|
||||
Handlers.Remove(handler);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unhooks an entity output.
|
||||
|
||||
@@ -716,6 +716,86 @@ namespace CounterStrikeSharp.API.Core
|
||||
}
|
||||
}
|
||||
|
||||
[EventName("bullet_damage")]
|
||||
public class EventBulletDamage : GameEvent
|
||||
{
|
||||
public EventBulletDamage(IntPtr pointer) : base(pointer){}
|
||||
public EventBulletDamage(bool force) : base("bullet_damage", force){}
|
||||
|
||||
|
||||
|
||||
// player index who was hurt
|
||||
public CCSPlayerController? Victim
|
||||
{
|
||||
get => GetPlayer("victim");
|
||||
set => SetPlayer("victim", value);
|
||||
}
|
||||
|
||||
|
||||
// player index who attacked
|
||||
public CCSPlayerController? Attacker
|
||||
{
|
||||
get => GetPlayer("attacker");
|
||||
set => SetPlayer("attacker", value);
|
||||
}
|
||||
|
||||
|
||||
// how far the bullet travelled before it hit the player
|
||||
public float Distance
|
||||
{
|
||||
get => Get<float>("distance");
|
||||
set => Set<float>("distance", value);
|
||||
}
|
||||
|
||||
|
||||
// direction vector of the bullet
|
||||
public float DamageDirX
|
||||
{
|
||||
get => Get<float>("damage_dir_x");
|
||||
set => Set<float>("damage_dir_x", value);
|
||||
}
|
||||
|
||||
|
||||
// direction vector of the bullet
|
||||
public float DamageDirY
|
||||
{
|
||||
get => Get<float>("damage_dir_y");
|
||||
set => Set<float>("damage_dir_y", value);
|
||||
}
|
||||
|
||||
|
||||
// direction vector of the bullet
|
||||
public float DamageDirZ
|
||||
{
|
||||
get => Get<float>("damage_dir_z");
|
||||
set => Set<float>("damage_dir_z", value);
|
||||
}
|
||||
|
||||
|
||||
// how many surfaces were penetrated
|
||||
public int NumPenetrations
|
||||
{
|
||||
get => Get<int>("num_penetrations");
|
||||
set => Set<int>("num_penetrations", value);
|
||||
}
|
||||
|
||||
|
||||
// was the shooter noscoped?
|
||||
public bool NoScope
|
||||
{
|
||||
get => Get<bool>("no_scope");
|
||||
set => Set<bool>("no_scope", value);
|
||||
}
|
||||
|
||||
|
||||
// was the shooter jumping?
|
||||
public bool InAir
|
||||
{
|
||||
get => Get<bool>("in_air");
|
||||
set => Set<bool>("in_air", value);
|
||||
}
|
||||
}
|
||||
|
||||
[EventName("bullet_flight_resolution")]
|
||||
public class EventBulletFlightResolution : GameEvent
|
||||
{
|
||||
|
||||
@@ -8,16 +8,19 @@ namespace CounterStrikeSharp.API.Core;
|
||||
public partial class CBaseEntity
|
||||
{
|
||||
/// <exception cref="InvalidOperationException">Entity is not valid</exception>
|
||||
/// <exception cref="ArgumentNullException">No valid argument</exception>
|
||||
public void Teleport(Vector? position = null, QAngle? angles = null, Vector? velocity = null)
|
||||
{
|
||||
Guard.IsValidEntity(this);
|
||||
|
||||
position ??= AbsOrigin!;
|
||||
angles ??= AbsRotation!;
|
||||
velocity ??= AbsVelocity;
|
||||
|
||||
VirtualFunction.CreateVoid<IntPtr, IntPtr, IntPtr, IntPtr>(Handle, GameData.GetOffset("CBaseEntity_Teleport"))(
|
||||
Handle, position.Handle, angles.Handle, velocity.Handle);
|
||||
|
||||
if (position == null && angles == null && velocity == null)
|
||||
throw new ArgumentNullException("No valid argument");
|
||||
|
||||
nint _position = position?.Handle ?? 0;
|
||||
nint _angles = angles?.Handle ?? 0;
|
||||
nint _velocity = velocity?.Handle ?? 0;
|
||||
|
||||
VirtualFunction.CreateVoid<IntPtr, IntPtr, IntPtr, IntPtr>(Handle, GameData.GetOffset("CBaseEntity_Teleport"))(Handle, _position, _angles, _velocity);
|
||||
}
|
||||
|
||||
/// <exception cref="InvalidOperationException">Entity is not valid</exception>
|
||||
@@ -45,4 +48,4 @@ public partial class CBaseEntity
|
||||
|
||||
return (T)Activator.CreateInstance(typeof(T), Marshal.ReadIntPtr(SubclassID.Handle + 4));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
using System;
|
||||
|
||||
using CounterStrikeSharp.API.Modules.Cvars;
|
||||
using CounterStrikeSharp.API.Modules.Entities;
|
||||
using CounterStrikeSharp.API.Modules.Entities.Constants;
|
||||
using CounterStrikeSharp.API.Modules.Memory;
|
||||
using CounterStrikeSharp.API.Modules.Utils;
|
||||
using CounterStrikeSharp.API.ValveConstants.Protobuf;
|
||||
|
||||
namespace CounterStrikeSharp.API.Core;
|
||||
|
||||
@@ -241,6 +241,15 @@ public partial class CCSPlayerController
|
||||
NativeAPI.IssueClientCommand(Slot, command);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Disconnects a player from the server with the specified reason.
|
||||
/// </summary>
|
||||
/// <param name="reason"></param>
|
||||
public void Disconnect(NetworkDisconnectionReason reason)
|
||||
{
|
||||
NativeAPI.DisconnectClient(Slot, (int)reason);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Issue the specified command directly from the server (mimics the server executing the command with the given player context).
|
||||
/// <remarks>Works with server commands like `kill`, `explode`, `noclip`, etc. </remarks>
|
||||
|
||||
@@ -52,7 +52,7 @@ public partial class CBaseAnimGraphController : CSkeletonAnimationController
|
||||
|
||||
// m_flPlaybackRate
|
||||
[SchemaMember("CBaseAnimGraphController", "m_flPlaybackRate")]
|
||||
public float PlaybackRate => Schema.GetDeclaredClass<float>(this.Handle, "CBaseAnimGraphController", "m_flPlaybackRate");
|
||||
public ref float PlaybackRate => ref Schema.GetRef<float>(this.Handle, "CBaseAnimGraphController", "m_flPlaybackRate");
|
||||
|
||||
// m_nNotifyState
|
||||
[SchemaMember("CBaseAnimGraphController", "m_nNotifyState")]
|
||||
|
||||
@@ -94,14 +94,6 @@ public partial class CBasePlayerController : CBaseEntity
|
||||
[SchemaMember("CBasePlayerController", "m_bGamePaused")]
|
||||
public ref bool GamePaused => ref Schema.GetRef<bool>(this.Handle, "CBasePlayerController", "m_bGamePaused");
|
||||
|
||||
// m_nLastRealCommandNumberExecuted
|
||||
[SchemaMember("CBasePlayerController", "m_nLastRealCommandNumberExecuted")]
|
||||
public ref Int32 LastRealCommandNumberExecuted => ref Schema.GetRef<Int32>(this.Handle, "CBasePlayerController", "m_nLastRealCommandNumberExecuted");
|
||||
|
||||
// m_nLastLateCommandExecuted
|
||||
[SchemaMember("CBasePlayerController", "m_nLastLateCommandExecuted")]
|
||||
public ref Int32 LastLateCommandExecuted => ref Schema.GetRef<Int32>(this.Handle, "CBasePlayerController", "m_nLastLateCommandExecuted");
|
||||
|
||||
// m_iIgnoreGlobalChat
|
||||
[SchemaMember("CBasePlayerController", "m_iIgnoreGlobalChat")]
|
||||
public ref ChatIgnoreType_t IgnoreGlobalChat => ref Schema.GetRef<ChatIgnoreType_t>(this.Handle, "CBasePlayerController", "m_iIgnoreGlobalChat");
|
||||
|
||||
@@ -370,10 +370,6 @@ public partial class CCSPlayerPawn : CCSPlayerPawnBase
|
||||
[SchemaMember("CCSPlayerPawn", "m_ignoreLadderJumpTime")]
|
||||
public ref float IgnoreLadderJumpTime => ref Schema.GetRef<float>(this.Handle, "CCSPlayerPawn", "m_ignoreLadderJumpTime");
|
||||
|
||||
// m_NumEnemiesKilledThisRound
|
||||
[SchemaMember("CCSPlayerPawn", "m_NumEnemiesKilledThisRound")]
|
||||
public ref Int32 NumEnemiesKilledThisRound => ref Schema.GetRef<Int32>(this.Handle, "CCSPlayerPawn", "m_NumEnemiesKilledThisRound");
|
||||
|
||||
// m_bKilledByHeadshot
|
||||
[SchemaMember("CCSPlayerPawn", "m_bKilledByHeadshot")]
|
||||
public ref bool KilledByHeadshot => ref Schema.GetRef<bool>(this.Handle, "CCSPlayerPawn", "m_bKilledByHeadshot");
|
||||
|
||||
@@ -94,10 +94,6 @@ public partial class CCSPlayerPawnBase : CBasePlayerPawn
|
||||
[SchemaMember("CCSPlayerPawnBase", "m_angEyeAngles")]
|
||||
public QAngle EyeAngles => Schema.GetDeclaredClass<QAngle>(this.Handle, "CCSPlayerPawnBase", "m_angEyeAngles");
|
||||
|
||||
// m_NumEnemiesAtRoundStart
|
||||
[SchemaMember("CCSPlayerPawnBase", "m_NumEnemiesAtRoundStart")]
|
||||
public ref Int32 NumEnemiesAtRoundStart => ref Schema.GetRef<Int32>(this.Handle, "CCSPlayerPawnBase", "m_NumEnemiesAtRoundStart");
|
||||
|
||||
// m_wasNotKilledNaturally
|
||||
[SchemaMember("CCSPlayerPawnBase", "m_wasNotKilledNaturally")]
|
||||
public ref bool WasNotKilledNaturally => ref Schema.GetRef<bool>(this.Handle, "CCSPlayerPawnBase", "m_wasNotKilledNaturally");
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
// <auto-generated />
|
||||
#nullable enable
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Drawing;
|
||||
using CounterStrikeSharp;
|
||||
using CounterStrikeSharp.API.Modules.Events;
|
||||
using CounterStrikeSharp.API.Modules.Entities;
|
||||
using CounterStrikeSharp.API.Modules.Memory;
|
||||
using CounterStrikeSharp.API.Modules.Utils;
|
||||
using CounterStrikeSharp.API.Core.Attributes;
|
||||
|
||||
namespace CounterStrikeSharp.API.Core;
|
||||
|
||||
public partial class CCSWeaponBaseVDataAPI : NativeObject
|
||||
{
|
||||
public CCSWeaponBaseVDataAPI (IntPtr pointer) : base(pointer) {}
|
||||
|
||||
}
|
||||
@@ -36,14 +36,14 @@ public partial class CNetworkOriginCellCoordQuantizedVector : NativeObject
|
||||
|
||||
// m_vecX
|
||||
[SchemaMember("CNetworkOriginCellCoordQuantizedVector", "m_vecX")]
|
||||
public float X => Schema.GetDeclaredClass<float>(this.Handle, "CNetworkOriginCellCoordQuantizedVector", "m_vecX");
|
||||
public ref float X => ref Schema.GetRef<float>(this.Handle, "CNetworkOriginCellCoordQuantizedVector", "m_vecX");
|
||||
|
||||
// m_vecY
|
||||
[SchemaMember("CNetworkOriginCellCoordQuantizedVector", "m_vecY")]
|
||||
public float Y => Schema.GetDeclaredClass<float>(this.Handle, "CNetworkOriginCellCoordQuantizedVector", "m_vecY");
|
||||
public ref float Y => ref Schema.GetRef<float>(this.Handle, "CNetworkOriginCellCoordQuantizedVector", "m_vecY");
|
||||
|
||||
// m_vecZ
|
||||
[SchemaMember("CNetworkOriginCellCoordQuantizedVector", "m_vecZ")]
|
||||
public float Z => Schema.GetDeclaredClass<float>(this.Handle, "CNetworkOriginCellCoordQuantizedVector", "m_vecZ");
|
||||
public ref float Z => ref Schema.GetRef<float>(this.Handle, "CNetworkOriginCellCoordQuantizedVector", "m_vecZ");
|
||||
|
||||
}
|
||||
|
||||
@@ -20,14 +20,14 @@ public partial class CNetworkVelocityVector : NativeObject
|
||||
|
||||
// m_vecX
|
||||
[SchemaMember("CNetworkVelocityVector", "m_vecX")]
|
||||
public float X => Schema.GetDeclaredClass<float>(this.Handle, "CNetworkVelocityVector", "m_vecX");
|
||||
public ref float X => ref Schema.GetRef<float>(this.Handle, "CNetworkVelocityVector", "m_vecX");
|
||||
|
||||
// m_vecY
|
||||
[SchemaMember("CNetworkVelocityVector", "m_vecY")]
|
||||
public float Y => Schema.GetDeclaredClass<float>(this.Handle, "CNetworkVelocityVector", "m_vecY");
|
||||
public ref float Y => ref Schema.GetRef<float>(this.Handle, "CNetworkVelocityVector", "m_vecY");
|
||||
|
||||
// m_vecZ
|
||||
[SchemaMember("CNetworkVelocityVector", "m_vecZ")]
|
||||
public float Z => Schema.GetDeclaredClass<float>(this.Handle, "CNetworkVelocityVector", "m_vecZ");
|
||||
public ref float Z => ref Schema.GetRef<float>(this.Handle, "CNetworkVelocityVector", "m_vecZ");
|
||||
|
||||
}
|
||||
|
||||
@@ -20,14 +20,14 @@ public partial class CNetworkViewOffsetVector : NativeObject
|
||||
|
||||
// m_vecX
|
||||
[SchemaMember("CNetworkViewOffsetVector", "m_vecX")]
|
||||
public float X => Schema.GetDeclaredClass<float>(this.Handle, "CNetworkViewOffsetVector", "m_vecX");
|
||||
public ref float X => ref Schema.GetRef<float>(this.Handle, "CNetworkViewOffsetVector", "m_vecX");
|
||||
|
||||
// m_vecY
|
||||
[SchemaMember("CNetworkViewOffsetVector", "m_vecY")]
|
||||
public float Y => Schema.GetDeclaredClass<float>(this.Handle, "CNetworkViewOffsetVector", "m_vecY");
|
||||
public ref float Y => ref Schema.GetRef<float>(this.Handle, "CNetworkViewOffsetVector", "m_vecY");
|
||||
|
||||
// m_vecZ
|
||||
[SchemaMember("CNetworkViewOffsetVector", "m_vecZ")]
|
||||
public float Z => Schema.GetDeclaredClass<float>(this.Handle, "CNetworkViewOffsetVector", "m_vecZ");
|
||||
public ref float Z => ref Schema.GetRef<float>(this.Handle, "CNetworkViewOffsetVector", "m_vecZ");
|
||||
|
||||
}
|
||||
|
||||
@@ -50,4 +50,8 @@ public partial class CSmokeGrenadeProjectile : CBaseCSGrenadeProjectile
|
||||
[SchemaMember("CSmokeGrenadeProjectile", "m_fllastSimulationTime")]
|
||||
public ref float FllastSimulationTime => ref Schema.GetRef<float>(this.Handle, "CSmokeGrenadeProjectile", "m_fllastSimulationTime");
|
||||
|
||||
// m_bExplodeFromInferno
|
||||
[SchemaMember("CSmokeGrenadeProjectile", "m_bExplodeFromInferno")]
|
||||
public ref bool ExplodeFromInferno => ref Schema.GetRef<bool>(this.Handle, "CSmokeGrenadeProjectile", "m_bExplodeFromInferno");
|
||||
|
||||
}
|
||||
|
||||
@@ -12,15 +12,9 @@ public enum BloodType : uint
|
||||
ColorRed = 0x0,
|
||||
ColorYellow = 0x1,
|
||||
ColorGreen = 0x2,
|
||||
ColorBrightGreen = 0x3,
|
||||
EntityMech = 0x4,
|
||||
EntityAntlion = 0x5,
|
||||
EntityZombie = 0x6,
|
||||
EntityBlob = 0x7,
|
||||
EntityBlobFrozen = 0x8,
|
||||
ColorRedLVL2 = 0x9,
|
||||
ColorRedLVL3 = 0xA,
|
||||
ColorRedLVL4 = 0xB,
|
||||
ColorRedLVL5 = 0xC,
|
||||
ColorRedLVL6 = 0xD,
|
||||
ColorRedLVL2 = 0x3,
|
||||
ColorRedLVL3 = 0x4,
|
||||
ColorRedLVL4 = 0x5,
|
||||
ColorRedLVL5 = 0x6,
|
||||
ColorRedLVL6 = 0x7,
|
||||
}
|
||||
|
||||
@@ -17,4 +17,5 @@ public enum PreviewCharacterMode : uint
|
||||
WALKING = 0x6,
|
||||
TEAM_INTRO = 0x7,
|
||||
WINGMAN_INTRO = 0x8,
|
||||
BANNER = 0x9,
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ using System.Collections.Concurrent;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security;
|
||||
using System.Text;
|
||||
using CounterStrikeSharp.API.Modules.Utils;
|
||||
|
||||
namespace CounterStrikeSharp.API.Core
|
||||
{
|
||||
@@ -205,6 +206,15 @@ namespace CounterStrikeSharp.API.Core
|
||||
|
||||
return;
|
||||
}
|
||||
else if (arg is IMarshalToNative marshalToNative)
|
||||
{
|
||||
foreach (var value in marshalToNative.GetNativeObject())
|
||||
{
|
||||
Push(context ,value);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
else if (arg is NativeObject nativeObject)
|
||||
{
|
||||
Push(context, (InputArgument)nativeObject);
|
||||
@@ -497,4 +507,4 @@ namespace CounterStrikeSharp.API.Core
|
||||
return $"ScriptContext{{numArgs={m_extContext.numArguments}}}";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
using Microsoft.Extensions.Localization;
|
||||
|
||||
namespace CounterStrikeSharp.API.Core.Translations;
|
||||
|
||||
public static class LocalizerExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Returns a localized string using the locale of the specified player.
|
||||
/// <remarks>Defaults to the server language if the player is invalid.</remarks>
|
||||
/// </summary>
|
||||
public static string ForPlayer(this IStringLocalizer localizer, CCSPlayerController? player, string key)
|
||||
{
|
||||
using WithTemporaryCulture temporaryCulture = new WithTemporaryCulture(player.GetLanguage());
|
||||
return localizer[key];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <inheritdoc cref="ForPlayer(Microsoft.Extensions.Localization.IStringLocalizer,CounterStrikeSharp.API.Core.CCSPlayerController?,string)"/>
|
||||
/// </summary>
|
||||
public static string ForPlayer(this IStringLocalizer localizer, CCSPlayerController? player, string key, params object[] args)
|
||||
{
|
||||
using WithTemporaryCulture temporaryCulture = new WithTemporaryCulture(player.GetLanguage());
|
||||
return localizer[key, args];
|
||||
}
|
||||
}
|
||||
@@ -32,4 +32,10 @@ public class ColorMarshaler : ICustomMarshal<Color>
|
||||
{
|
||||
Marshal.WriteInt32(pointer, (managedObj.A << 24) | (managedObj.B << 16) | (managedObj.G << 8) | managedObj.R);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal interface IMarshalToNative
|
||||
{
|
||||
// Returns the object format that will be passed to the native API when marshalled by the script context.
|
||||
IEnumerable<object> GetNativeObject();
|
||||
}
|
||||
|
||||
@@ -82,9 +82,9 @@ public static class VirtualFunctions
|
||||
new(GameData.GetSignature("CBasePlayerPawn_RemovePlayerItem"));
|
||||
public static Action<IntPtr, IntPtr> RemovePlayerItemVirtual = RemovePlayerItemFunc.Invoke;
|
||||
|
||||
public static MemoryFunctionVoid<IntPtr, IntPtr, int, short, short> StateChangedFunc =
|
||||
public static MemoryFunctionVoid<IntPtr, IntPtr, int, short, int> StateChangedFunc =
|
||||
new(GameData.GetSignature("StateChanged"));
|
||||
public static Action<IntPtr, IntPtr, int, short, short> StateChanged = StateChangedFunc.Invoke;
|
||||
public static Action<IntPtr, IntPtr, int, short, int> StateChanged = StateChangedFunc.Invoke;
|
||||
|
||||
public static MemoryFunctionVoid<IntPtr, int, long> NetworkStateChangedFunc = new(GameData.GetSignature("NetworkStateChanged"));
|
||||
public static Action<IntPtr, int, long> NetworkStateChanged = NetworkStateChangedFunc.Invoke;
|
||||
|
||||
@@ -0,0 +1,171 @@
|
||||
using System.Collections.ObjectModel;
|
||||
using CounterStrikeSharp.API.Modules.Utils;
|
||||
|
||||
namespace CounterStrikeSharp.API.Modules.UserMessages;
|
||||
|
||||
public class UserMessage : NativeObject, IDisposable
|
||||
{
|
||||
private RecipientFilter _recipients;
|
||||
|
||||
public delegate HookResult UserMessageHandler(UserMessage native);
|
||||
|
||||
public UserMessage(IntPtr pointer) : base(pointer)
|
||||
{
|
||||
Recipients = new RecipientFilter(NativeAPI.UsermessageGetrecipients(this));
|
||||
Recipients.CollectionChanged = () => NativeAPI.UsermessageSetrecipients(this, Recipients.GetRecipientMask());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new user message with a given network message name partial match.
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <throws>if the name is not a valid network message name</throws>
|
||||
public static UserMessage FromPartialName(string name) => new(NativeAPI.UsermessageCreate(name));
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new user message with a given network message ID.
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
public static UserMessage FromId(int id) => new(NativeAPI.UsermessageCreatebyid(id));
|
||||
|
||||
/// <summary>
|
||||
/// Finds a network message ID by name.
|
||||
/// <remarks>
|
||||
/// Network message system must be loaded before this function can be used.
|
||||
/// Avoid calling this method from <see cref="IPlugin.Load"/>
|
||||
/// </remarks>
|
||||
/// </summary>
|
||||
public static int FindIdByName(string name) => NativeAPI.UsermessageFindmessageidbyname(name);
|
||||
|
||||
public bool HasField(string fieldName) => NativeAPI.PbHasfield(this, fieldName);
|
||||
|
||||
public int ReadInt(string fieldName, int? index = null) => NativeAPI.PbReadint(this, fieldName, index ?? -1);
|
||||
public uint ReadUInt(string fieldName, int? index = null) => (uint)NativeAPI.PbReadint(this, fieldName, index ?? -1);
|
||||
public long ReadInt64(string fieldName, int? index = null) => NativeAPI.PbReadint64(this, fieldName, index ?? -1);
|
||||
public ulong ReadUInt64(string fieldName, int? index = null) => (ulong)NativeAPI.PbReadint64(this, fieldName, index ?? -1);
|
||||
public float ReadFloat(string fieldName, int? index = null) => NativeAPI.PbReadfloat(this, fieldName, index ?? -1);
|
||||
public double ReadDouble(string fieldName, int? index = null) => NativeAPI.PbReadfloat(this, fieldName, index ?? -1);
|
||||
public string ReadString(string fieldName, int? index = null) => NativeAPI.PbReadstring(this, fieldName, index ?? -1);
|
||||
public bool ReadBool(string fieldName, int? index = null) => NativeAPI.PbReadbool(this, fieldName, index ?? -1);
|
||||
|
||||
public void SetInt(string fieldName, int value, int? index = null) => NativeAPI.PbSetint(this, fieldName, value, index ?? -1);
|
||||
public void SetUInt(string fieldName, uint value, int? index = null) => NativeAPI.PbSetint(this, fieldName, (int)value, index ?? -1);
|
||||
public void SetInt64(string fieldName, long value, int? index = null) => NativeAPI.PbSetint64(this, fieldName, value, index ?? -1);
|
||||
|
||||
public void SetUInt64(string fieldName, ulong value, int? index = null) =>
|
||||
NativeAPI.PbSetint64(this, fieldName, (long)value, index ?? -1);
|
||||
|
||||
public void SetFloat(string fieldName, float value, int? index = null) => NativeAPI.PbSetfloat(this, fieldName, value, index ?? -1);
|
||||
|
||||
public void SetDouble(string fieldName, double value, int? index = null) =>
|
||||
NativeAPI.PbSetfloat(this, fieldName, (float)value, index ?? -1);
|
||||
|
||||
public void SetString(string fieldName, string value, int? index = null) => NativeAPI.PbSetstring(this, fieldName, value, index ?? -1);
|
||||
public void SetBool(string fieldName, bool value, int? index = null) => NativeAPI.PbSetbool(this, fieldName, value, index ?? -1);
|
||||
|
||||
public int GetRepeatedFieldCount(string fieldName) => NativeAPI.PbGetrepeatedfieldcount(this, fieldName);
|
||||
|
||||
public void RemoveRepeatedField(string fieldName, int index) => NativeAPI.PbRemoverepeatedfieldvalue(this, fieldName, index);
|
||||
|
||||
public void AddInt(string fieldName, int value) => NativeAPI.PbAddint(this, fieldName, value);
|
||||
public void AddUInt(string fieldName, uint value) => NativeAPI.PbAddint(this, fieldName, (int)value);
|
||||
public void AddInt64(string fieldName, long value) => NativeAPI.PbAddint64(this, fieldName, value);
|
||||
public void AddUInt64(string fieldName, ulong value) => NativeAPI.PbAddint64(this, fieldName, (long)value);
|
||||
public void AddFloat(string fieldName, float value) => NativeAPI.PbAddfloat(this, fieldName, value);
|
||||
public void AddDouble(string fieldName, double value) => NativeAPI.PbAddfloat(this, fieldName, (float)value);
|
||||
public void AddString(string fieldName, string value) => NativeAPI.PbAddstring(this, fieldName, value);
|
||||
public void AddBool(string fieldName, bool value) => NativeAPI.PbAddbool(this, fieldName, value);
|
||||
|
||||
// public UserMessage ReadMessage(string fieldName) => NativeAPI.PbReadmessage(this, fieldName);
|
||||
// public UserMessage ReadRepeatedMessage(string fieldName, int index ) => NativeAPI.PbReadrepeatedmessage(this, fieldName, index);
|
||||
// public UserMessage AddMessage(string fieldName) => NativeAPI.PbAddmessage(this, fieldName);
|
||||
|
||||
public void Send() => NativeAPI.UsermessageSend(this);
|
||||
|
||||
public void Send(RecipientFilter recipientFilter)
|
||||
{
|
||||
Recipients = recipientFilter;
|
||||
Send();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the network message name of this user message.
|
||||
/// <example>CMsgTEFireBullets [452]</example>
|
||||
/// </summary>
|
||||
public string Name => NativeAPI.UsermessageGetname(this);
|
||||
|
||||
/// <summary>
|
||||
/// Returns the network message ID of this user message.
|
||||
/// <example>452</example>
|
||||
/// </summary>
|
||||
public int Id => NativeAPI.UsermessageGetid(this);
|
||||
|
||||
/// <summary>
|
||||
/// Returns the protobuf message type of this user message.
|
||||
/// <example>CMsgTEFireBullets</example>
|
||||
/// </summary>
|
||||
public string Type => NativeAPI.UsermessageGettype(this);
|
||||
|
||||
/// <summary>
|
||||
/// Returns the debug string of this user message, as defined by protobuf.
|
||||
/// <example>
|
||||
/// <code>
|
||||
/// CMsgTEFireBullets [452], 452, origin {
|
||||
/// x: -1969.24951
|
||||
/// y: 2046.12683
|
||||
/// z: 60.9242516
|
||||
/// }
|
||||
/// angles {
|
||||
/// x: 32.8350143
|
||||
/// y: 19.0894909
|
||||
/// z: 0
|
||||
/// }
|
||||
/// weapon_id: 2441476
|
||||
/// mode: 1
|
||||
/// seed: 991759080
|
||||
/// player: 6390016
|
||||
/// inaccuracy: 0.00490000239
|
||||
/// recoil_index: 0
|
||||
/// spread: 0.0015
|
||||
/// sound_type: 9
|
||||
/// item_def_index: 61
|
||||
/// sound_dsp_effect: 2005810340
|
||||
/// ent_origin {
|
||||
/// x: -1969.24976
|
||||
/// y: 2046.12671
|
||||
/// z: -1.92980957
|
||||
/// }
|
||||
/// num_bullets_remaining: 12
|
||||
/// attack_type: 0
|
||||
/// </code>
|
||||
/// </example>
|
||||
/// </summary>
|
||||
public string DebugString => NativeAPI.PbGetdebugstring(this);
|
||||
|
||||
public RecipientFilter Recipients
|
||||
{
|
||||
get => _recipients;
|
||||
set
|
||||
{
|
||||
_recipients = value;
|
||||
NativeAPI.UsermessageSetrecipients(this, _recipients.GetRecipientMask());
|
||||
}
|
||||
}
|
||||
|
||||
private void ReleaseUnmanagedResources()
|
||||
{
|
||||
Server.NextFrame(() => { NativeAPI.UsermessageDelete(this); });
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
ReleaseUnmanagedResources();
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
~UserMessage()
|
||||
{
|
||||
ReleaseUnmanagedResources();
|
||||
}
|
||||
}
|
||||
164
managed/CounterStrikeSharp.API/Modules/Utils/RecipientFilter.cs
Normal file
164
managed/CounterStrikeSharp.API/Modules/Utils/RecipientFilter.cs
Normal file
@@ -0,0 +1,164 @@
|
||||
/*
|
||||
* This file is part of CounterStrikeSharp.
|
||||
* CounterStrikeSharp is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* CounterStrikeSharp 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 CounterStrikeSharp. If not, see <https://www.gnu.org/licenses/>. *
|
||||
*/
|
||||
|
||||
using System.Collections;
|
||||
|
||||
namespace CounterStrikeSharp.API.Modules.Utils;
|
||||
|
||||
/// <summary>
|
||||
/// A generic filter for determining whom to send message/sounds etc.
|
||||
/// to and providing a bit of additional state information
|
||||
/// </summary>
|
||||
public class RecipientFilter : IList<CCSPlayerController>, IMarshalToNative
|
||||
{
|
||||
private readonly List<CCSPlayerController> _recipients = new();
|
||||
|
||||
internal Action? CollectionChanged;
|
||||
|
||||
public RecipientFilter()
|
||||
{
|
||||
}
|
||||
|
||||
public RecipientFilter(params CCSPlayerController[] slots)
|
||||
{
|
||||
foreach (var slot in slots)
|
||||
{
|
||||
Add(slot);
|
||||
}
|
||||
}
|
||||
|
||||
public RecipientFilter(params int[] slots)
|
||||
{
|
||||
foreach (var slot in slots)
|
||||
{
|
||||
Add(slot);
|
||||
}
|
||||
}
|
||||
|
||||
public RecipientFilter(ulong mask)
|
||||
{
|
||||
for (var i = 0; i < 64; i++)
|
||||
{
|
||||
if ((mask & ((ulong)1 << i)) != 0)
|
||||
{
|
||||
Add(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<object> GetNativeObject()
|
||||
{
|
||||
yield return GetRecipientMask();
|
||||
}
|
||||
|
||||
public ulong GetRecipientMask()
|
||||
{
|
||||
ulong recipientMask = 0;
|
||||
foreach (var recipient in _recipients)
|
||||
{
|
||||
recipientMask |= (ulong)1 << recipient.Slot;
|
||||
}
|
||||
|
||||
return recipientMask;
|
||||
}
|
||||
|
||||
public int IndexOf(CCSPlayerController item)
|
||||
{
|
||||
return _recipients.IndexOf(item);
|
||||
}
|
||||
|
||||
public void Insert(int index, CCSPlayerController item)
|
||||
{
|
||||
_recipients.Insert(index, item);
|
||||
CollectionChanged?.Invoke();
|
||||
}
|
||||
|
||||
public void RemoveAt(int index)
|
||||
{
|
||||
_recipients.RemoveAt(index);
|
||||
CollectionChanged?.Invoke();
|
||||
}
|
||||
|
||||
public CCSPlayerController this[int index]
|
||||
{
|
||||
get => _recipients[index];
|
||||
set => throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void Add(int slot)
|
||||
{
|
||||
var player = Utilities.GetPlayerFromSlot(slot);
|
||||
if (player == null)
|
||||
{
|
||||
throw new ArgumentException($"Player with slot {slot} not found");
|
||||
}
|
||||
|
||||
_recipients.Add(player);
|
||||
CollectionChanged?.Invoke();
|
||||
}
|
||||
|
||||
public void AddAllPlayers()
|
||||
{
|
||||
_recipients.AddRange(Utilities.GetPlayers());
|
||||
CollectionChanged?.Invoke();
|
||||
}
|
||||
|
||||
public IEnumerator<CCSPlayerController> GetEnumerator()
|
||||
{
|
||||
return _recipients.GetEnumerator();
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return GetEnumerator();
|
||||
}
|
||||
|
||||
public void Add(CCSPlayerController item)
|
||||
{
|
||||
_recipients.Add(item);
|
||||
CollectionChanged?.Invoke();
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
_recipients.Clear();
|
||||
CollectionChanged?.Invoke();
|
||||
}
|
||||
|
||||
public bool Contains(CCSPlayerController item)
|
||||
{
|
||||
return _recipients.Contains(item);
|
||||
}
|
||||
|
||||
public void CopyTo(CCSPlayerController[] array, int arrayIndex)
|
||||
{
|
||||
_recipients.CopyTo(array, arrayIndex);
|
||||
}
|
||||
|
||||
public bool Remove(CCSPlayerController item)
|
||||
{
|
||||
var success = _recipients.Remove(item);
|
||||
CollectionChanged?.Invoke();
|
||||
return success;
|
||||
}
|
||||
|
||||
public int Count => _recipients.Count;
|
||||
public bool IsReadOnly => false;
|
||||
|
||||
public static implicit operator RecipientFilter(CCSPlayerController player) => new(player);
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,126 @@
|
||||
namespace CounterStrikeSharp.API.ValveConstants.Protobuf;
|
||||
|
||||
/// <summary>
|
||||
/// Enum derived from `network_connection.proto`
|
||||
/// </summary>
|
||||
public enum NetworkDisconnectionReason
|
||||
{
|
||||
NETWORK_DISCONNECT_INVALID = 0,
|
||||
NETWORK_DISCONNECT_SHUTDOWN = 1,
|
||||
NETWORK_DISCONNECT_DISCONNECT_BY_USER = 2,
|
||||
NETWORK_DISCONNECT_DISCONNECT_BY_SERVER = 3,
|
||||
NETWORK_DISCONNECT_LOST = 4,
|
||||
NETWORK_DISCONNECT_OVERFLOW = 5,
|
||||
NETWORK_DISCONNECT_STEAM_BANNED = 6,
|
||||
NETWORK_DISCONNECT_STEAM_INUSE = 7,
|
||||
NETWORK_DISCONNECT_STEAM_TICKET = 8,
|
||||
NETWORK_DISCONNECT_STEAM_LOGON = 9,
|
||||
NETWORK_DISCONNECT_STEAM_AUTHCANCELLED = 10,
|
||||
NETWORK_DISCONNECT_STEAM_AUTHALREADYUSED = 11,
|
||||
NETWORK_DISCONNECT_STEAM_AUTHINVALID = 12,
|
||||
NETWORK_DISCONNECT_STEAM_VACBANSTATE = 13,
|
||||
NETWORK_DISCONNECT_STEAM_LOGGED_IN_ELSEWHERE = 14,
|
||||
NETWORK_DISCONNECT_STEAM_VAC_CHECK_TIMEDOUT = 15,
|
||||
NETWORK_DISCONNECT_STEAM_DROPPED = 16,
|
||||
NETWORK_DISCONNECT_STEAM_OWNERSHIP = 17,
|
||||
NETWORK_DISCONNECT_SERVERINFO_OVERFLOW = 18,
|
||||
NETWORK_DISCONNECT_TICKMSG_OVERFLOW = 19,
|
||||
NETWORK_DISCONNECT_STRINGTABLEMSG_OVERFLOW = 20,
|
||||
NETWORK_DISCONNECT_DELTAENTMSG_OVERFLOW = 21,
|
||||
NETWORK_DISCONNECT_TEMPENTMSG_OVERFLOW = 22,
|
||||
NETWORK_DISCONNECT_SOUNDSMSG_OVERFLOW = 23,
|
||||
NETWORK_DISCONNECT_SNAPSHOTOVERFLOW = 24,
|
||||
NETWORK_DISCONNECT_SNAPSHOTERROR = 25,
|
||||
NETWORK_DISCONNECT_RELIABLEOVERFLOW = 26,
|
||||
NETWORK_DISCONNECT_BADDELTATICK = 27,
|
||||
NETWORK_DISCONNECT_NOMORESPLITS = 28,
|
||||
NETWORK_DISCONNECT_TIMEDOUT = 29,
|
||||
NETWORK_DISCONNECT_DISCONNECTED = 30,
|
||||
NETWORK_DISCONNECT_LEAVINGSPLIT = 31,
|
||||
NETWORK_DISCONNECT_DIFFERENTCLASSTABLES = 32,
|
||||
NETWORK_DISCONNECT_BADRELAYPASSWORD = 33,
|
||||
NETWORK_DISCONNECT_BADSPECTATORPASSWORD = 34,
|
||||
NETWORK_DISCONNECT_HLTVRESTRICTED = 35,
|
||||
NETWORK_DISCONNECT_NOSPECTATORS = 36,
|
||||
NETWORK_DISCONNECT_HLTVUNAVAILABLE = 37,
|
||||
NETWORK_DISCONNECT_HLTVSTOP = 38,
|
||||
NETWORK_DISCONNECT_KICKED = 39,
|
||||
NETWORK_DISCONNECT_BANADDED = 40,
|
||||
NETWORK_DISCONNECT_KICKBANADDED = 41,
|
||||
NETWORK_DISCONNECT_HLTVDIRECT = 42,
|
||||
NETWORK_DISCONNECT_PURESERVER_CLIENTEXTRA = 43,
|
||||
NETWORK_DISCONNECT_PURESERVER_MISMATCH = 44,
|
||||
NETWORK_DISCONNECT_USERCMD = 45,
|
||||
NETWORK_DISCONNECT_REJECTED_BY_GAME = 46,
|
||||
NETWORK_DISCONNECT_MESSAGE_PARSE_ERROR = 47,
|
||||
NETWORK_DISCONNECT_INVALID_MESSAGE_ERROR = 48,
|
||||
NETWORK_DISCONNECT_BAD_SERVER_PASSWORD = 49,
|
||||
NETWORK_DISCONNECT_DIRECT_CONNECT_RESERVATION = 50,
|
||||
NETWORK_DISCONNECT_CONNECTION_FAILURE = 51,
|
||||
NETWORK_DISCONNECT_NO_PEER_GROUP_HANDLERS = 52,
|
||||
NETWORK_DISCONNECT_RECONNECTION = 53,
|
||||
NETWORK_DISCONNECT_LOOPSHUTDOWN = 54,
|
||||
NETWORK_DISCONNECT_LOOPDEACTIVATE = 55,
|
||||
NETWORK_DISCONNECT_HOST_ENDGAME = 56,
|
||||
NETWORK_DISCONNECT_LOOP_LEVELLOAD_ACTIVATE = 57,
|
||||
NETWORK_DISCONNECT_CREATE_SERVER_FAILED = 58,
|
||||
NETWORK_DISCONNECT_EXITING = 59,
|
||||
NETWORK_DISCONNECT_REQUEST_HOSTSTATE_IDLE = 60,
|
||||
NETWORK_DISCONNECT_REQUEST_HOSTSTATE_HLTVRELAY = 61,
|
||||
NETWORK_DISCONNECT_CLIENT_CONSISTENCY_FAIL = 62,
|
||||
NETWORK_DISCONNECT_CLIENT_UNABLE_TO_CRC_MAP = 63,
|
||||
NETWORK_DISCONNECT_CLIENT_NO_MAP = 64,
|
||||
NETWORK_DISCONNECT_CLIENT_DIFFERENT_MAP = 65,
|
||||
NETWORK_DISCONNECT_SERVER_REQUIRES_STEAM = 66,
|
||||
NETWORK_DISCONNECT_STEAM_DENY_MISC = 67,
|
||||
NETWORK_DISCONNECT_STEAM_DENY_BAD_ANTI_CHEAT = 68,
|
||||
NETWORK_DISCONNECT_SERVER_SHUTDOWN = 69,
|
||||
NETWORK_DISCONNECT_REPLAY_INCOMPATIBLE = 71,
|
||||
NETWORK_DISCONNECT_CONNECT_REQUEST_TIMEDOUT = 72,
|
||||
NETWORK_DISCONNECT_SERVER_INCOMPATIBLE = 73,
|
||||
NETWORK_DISCONNECT_LOCALPROBLEM_MANYRELAYS = 74,
|
||||
NETWORK_DISCONNECT_LOCALPROBLEM_HOSTEDSERVERPRIMARYRELAY = 75,
|
||||
NETWORK_DISCONNECT_LOCALPROBLEM_NETWORKCONFIG = 76,
|
||||
NETWORK_DISCONNECT_LOCALPROBLEM_OTHER = 77,
|
||||
NETWORK_DISCONNECT_REMOTE_TIMEOUT = 79,
|
||||
NETWORK_DISCONNECT_REMOTE_TIMEOUT_CONNECTING = 80,
|
||||
NETWORK_DISCONNECT_REMOTE_OTHER = 81,
|
||||
NETWORK_DISCONNECT_REMOTE_BADCRYPT = 82,
|
||||
NETWORK_DISCONNECT_REMOTE_CERTNOTTRUSTED = 83,
|
||||
NETWORK_DISCONNECT_UNUSUAL = 84,
|
||||
NETWORK_DISCONNECT_INTERNAL_ERROR = 85,
|
||||
NETWORK_DISCONNECT_REJECT_BADCHALLENGE = 128,
|
||||
NETWORK_DISCONNECT_REJECT_NOLOBBY = 129,
|
||||
NETWORK_DISCONNECT_REJECT_BACKGROUND_MAP = 130,
|
||||
NETWORK_DISCONNECT_REJECT_SINGLE_PLAYER = 131,
|
||||
NETWORK_DISCONNECT_REJECT_HIDDEN_GAME = 132,
|
||||
NETWORK_DISCONNECT_REJECT_LANRESTRICT = 133,
|
||||
NETWORK_DISCONNECT_REJECT_BADPASSWORD = 134,
|
||||
NETWORK_DISCONNECT_REJECT_SERVERFULL = 135,
|
||||
NETWORK_DISCONNECT_REJECT_INVALIDRESERVATION = 136,
|
||||
NETWORK_DISCONNECT_REJECT_FAILEDCHANNEL = 137,
|
||||
NETWORK_DISCONNECT_REJECT_CONNECT_FROM_LOBBY = 138,
|
||||
NETWORK_DISCONNECT_REJECT_RESERVED_FOR_LOBBY = 139,
|
||||
NETWORK_DISCONNECT_REJECT_INVALIDKEYLENGTH = 140,
|
||||
NETWORK_DISCONNECT_REJECT_OLDPROTOCOL = 141,
|
||||
NETWORK_DISCONNECT_REJECT_NEWPROTOCOL = 142,
|
||||
NETWORK_DISCONNECT_REJECT_INVALIDCONNECTION = 143,
|
||||
NETWORK_DISCONNECT_REJECT_INVALIDCERTLEN = 144,
|
||||
NETWORK_DISCONNECT_REJECT_INVALIDSTEAMCERTLEN = 145,
|
||||
NETWORK_DISCONNECT_REJECT_STEAM = 146,
|
||||
NETWORK_DISCONNECT_REJECT_SERVERAUTHDISABLED = 147,
|
||||
NETWORK_DISCONNECT_REJECT_SERVERCDKEYAUTHINVALID = 148,
|
||||
NETWORK_DISCONNECT_REJECT_BANNED = 149,
|
||||
NETWORK_DISCONNECT_KICKED_TEAMKILLING = 150,
|
||||
NETWORK_DISCONNECT_KICKED_TK_START = 151,
|
||||
NETWORK_DISCONNECT_KICKED_UNTRUSTEDACCOUNT = 152,
|
||||
NETWORK_DISCONNECT_KICKED_CONVICTEDACCOUNT = 153,
|
||||
NETWORK_DISCONNECT_KICKED_COMPETITIVECOOLDOWN = 154,
|
||||
NETWORK_DISCONNECT_KICKED_TEAMHURTING = 155,
|
||||
NETWORK_DISCONNECT_KICKED_HOSTAGEKILLING = 156,
|
||||
NETWORK_DISCONNECT_KICKED_VOTEDOFF = 157,
|
||||
NETWORK_DISCONNECT_KICKED_IDLE = 158,
|
||||
NETWORK_DISCONNECT_KICKED_SUICIDE = 159,
|
||||
NETWORK_DISCONNECT_KICKED_NOSTEAMLOGIN = 160,
|
||||
NETWORK_DISCONNECT_KICKED_NOSTEAMTICKET = 161
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -15,7 +15,7 @@ public record SchemaFieldType
|
||||
this.Atomic = Atomic;
|
||||
this.Inner = Inner;
|
||||
|
||||
if (this.Name == "GameTime_t")
|
||||
if (this.Name == "GameTime_t" || this.Name == "CNetworkedQuantizedFloat")
|
||||
{
|
||||
this.Category = SchemaTypeCategory.Builtin;
|
||||
this.Name = "float32";
|
||||
@@ -99,7 +99,8 @@ public record SchemaFieldType
|
||||
{
|
||||
SchemaTypeCategory.Builtin => BuiltinToCsKeyword(Name),
|
||||
SchemaTypeCategory.Ptr => IsString
|
||||
? "string" : $"{Inner!.CsTypeName}?",
|
||||
? "string"
|
||||
: $"{Inner!.CsTypeName}?",
|
||||
SchemaTypeCategory.FixedArray => IsString
|
||||
? "string"
|
||||
: $"{Inner!.CsTypeName}[]",
|
||||
|
||||
@@ -40,6 +40,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MySharedTypes.Contracts", "
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WithSharedTypesConsumer", "..\examples\WithSharedTypesConsumer\WithSharedTypesConsumer.csproj", "{76AD7BB0-A096-4336-83E2-B32CAE4E9933}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WithUserMessages", "..\examples\WithUserMessages\WithUserMessages.csproj", "{A14029BA-CADE-4F25-ADC5-48CF14332F61}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
@@ -122,6 +124,10 @@ Global
|
||||
{76AD7BB0-A096-4336-83E2-B32CAE4E9933}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{76AD7BB0-A096-4336-83E2-B32CAE4E9933}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{76AD7BB0-A096-4336-83E2-B32CAE4E9933}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{A14029BA-CADE-4F25-ADC5-48CF14332F61}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{A14029BA-CADE-4F25-ADC5-48CF14332F61}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{A14029BA-CADE-4F25-ADC5-48CF14332F61}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{A14029BA-CADE-4F25-ADC5-48CF14332F61}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(NestedProjects) = preSolution
|
||||
{57E64289-5D69-4AA1-BEF0-D0D96A55EE8F} = {7DF99C35-881D-4FF2-B1C9-246BD3DECB9A}
|
||||
@@ -139,5 +145,6 @@ Global
|
||||
{1309954E-FAF7-47A5-9FF9-C7263B33E4E3} = {7DF99C35-881D-4FF2-B1C9-246BD3DECB9A}
|
||||
{A37676EA-CF2F-424D-85A1-C359D07A679D} = {7DF99C35-881D-4FF2-B1C9-246BD3DECB9A}
|
||||
{76AD7BB0-A096-4336-83E2-B32CAE4E9933} = {7DF99C35-881D-4FF2-B1C9-246BD3DECB9A}
|
||||
{A14029BA-CADE-4F25-ADC5-48CF14332F61} = {7DF99C35-881D-4FF2-B1C9-246BD3DECB9A}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
||||
@@ -30,6 +30,7 @@ using CounterStrikeSharp.API.Modules.Entities;
|
||||
using CounterStrikeSharp.API.Modules.Entities.Constants;
|
||||
using CounterStrikeSharp.API.Modules.Events;
|
||||
using CounterStrikeSharp.API.Modules.Memory;
|
||||
using CounterStrikeSharp.API.Modules.UserMessages;
|
||||
using CounterStrikeSharp.API.Modules.Utils;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
@@ -160,6 +161,19 @@ namespace TestPlugin
|
||||
info.DontBroadcast = true;
|
||||
}
|
||||
|
||||
if (@event.Attacker != null)
|
||||
{
|
||||
var message = UserMessage.FromPartialName("Shake");
|
||||
Logger.LogInformation("Created user message CCSUsrMsg_Shake {Message:x}", message.Handle);
|
||||
|
||||
message.SetFloat("duration", 2);
|
||||
message.SetFloat("amplitude", 5);
|
||||
message.SetFloat("frequency", 10f);
|
||||
message.SetInt("command", 0);
|
||||
|
||||
message.Send(@event.Attacker);
|
||||
}
|
||||
|
||||
return HookResult.Continue;
|
||||
}, HookMode.Pre);
|
||||
|
||||
@@ -283,7 +297,7 @@ namespace TestPlugin
|
||||
case "flashbang_projectile":
|
||||
var flashbang = entity.As<CBaseCSGrenadeProjectile>();
|
||||
|
||||
Server.NextFrame(() => { flashbang.Remove(); });
|
||||
// Server.NextFrame(() => { flashbang.Remove(); });
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
41
src/core/UserMessage.cpp
Normal file
41
src/core/UserMessage.cpp
Normal file
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* This file is part of CounterStrikeSharp.
|
||||
* CounterStrikeSharp is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* CounterStrikeSharp 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 CounterStrikeSharp. If not, see <https://www.gnu.org/licenses/>. *
|
||||
*/
|
||||
#include "UserMessage.h"
|
||||
|
||||
#include "networksystem/inetworkserializer.h"
|
||||
|
||||
using namespace google;
|
||||
|
||||
namespace counterstrikesharp {
|
||||
int UserMessage::GetMessageID() { return msgSerializable->GetNetMessageInfo()->m_MessageId; }
|
||||
|
||||
std::string UserMessage::GetMessageName() { return msgSerializable->GetUnscopedName(); }
|
||||
|
||||
bool UserMessage::HasField(std::string fieldName)
|
||||
{
|
||||
const google::protobuf::Descriptor* descriptor = msg->GetDescriptor();
|
||||
const google::protobuf::FieldDescriptor* field = descriptor->FindFieldByName(fieldName);
|
||||
|
||||
if (field == nullptr || (field->label() == google::protobuf::FieldDescriptor::LABEL_REPEATED))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return this->msg->GetReflection()->HasField(*this->msg, field);
|
||||
}
|
||||
|
||||
const CNetMessagePB<google::protobuf::Message>* UserMessage::GetProtobufMessage() { return msg; }
|
||||
} // namespace counterstrikesharp
|
||||
1168
src/core/UserMessage.h
Normal file
1168
src/core/UserMessage.h
Normal file
File diff suppressed because it is too large
Load Diff
@@ -35,7 +35,12 @@
|
||||
#include "pch.h"
|
||||
#include "dynohook/core.h"
|
||||
#include "dynohook/manager.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "dynohook/conventions/x64/x64MsFastcall.h"
|
||||
#else
|
||||
#include "dynohook/conventions/x64/x64SystemVcall.h"
|
||||
#endif
|
||||
|
||||
namespace counterstrikesharp {
|
||||
|
||||
@@ -275,8 +280,11 @@ void ValveFunction::AddHook(CallbackT callable, bool post)
|
||||
{
|
||||
dyno::HookManager& manager = dyno::HookManager::Get();
|
||||
dyno::Hook* hook = manager.hook((void*)m_ulAddr, [this] {
|
||||
return new dyno::x64SystemVcall(ConvertArgsToDynoHook(m_Args),
|
||||
static_cast<dyno::DataType>(this->m_eReturnType));
|
||||
#ifdef _WIN32
|
||||
return new dyno::x64MsFastcall(ConvertArgsToDynoHook(m_Args), static_cast<dyno::DataType>(this->m_eReturnType));
|
||||
#else
|
||||
return new dyno::x64SystemVcall(ConvertArgsToDynoHook(m_Args), static_cast<dyno::DataType>(this->m_eReturnType));
|
||||
#endif
|
||||
});
|
||||
g_HookMap[hook] = this;
|
||||
hook->addCallback(dyno::HookType::Post, (dyno::HookHandler*)&HookHandler);
|
||||
@@ -297,8 +305,11 @@ void ValveFunction::AddHook(CallbackT callable, bool post)
|
||||
void ValveFunction::RemoveHook(CallbackT callable, bool post) {
|
||||
dyno::HookManager& manager = dyno::HookManager::Get();
|
||||
dyno::Hook* hook = manager.hook((void*)m_ulAddr, [this] {
|
||||
return new dyno::x64SystemVcall(ConvertArgsToDynoHook(m_Args),
|
||||
static_cast<dyno::DataType>(this->m_eReturnType));
|
||||
#ifdef _WIN32
|
||||
return new dyno::x64MsFastcall(ConvertArgsToDynoHook(m_Args), static_cast<dyno::DataType>(this->m_eReturnType));
|
||||
#else
|
||||
return new dyno::x64SystemVcall(ConvertArgsToDynoHook(m_Args), static_cast<dyno::DataType>(this->m_eReturnType));
|
||||
#endif
|
||||
});
|
||||
g_HookMap[hook] = this;
|
||||
|
||||
@@ -313,4 +324,4 @@ void ValveFunction::RemoveHook(CallbackT callable, bool post) {
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace counterstrikesharp
|
||||
} // namespace counterstrikesharp
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include "core/managers/entity_manager.h"
|
||||
#include "core/managers/server_manager.h"
|
||||
#include "core/managers/voice_manager.h"
|
||||
#include "core/managers/usermessage_manager.h"
|
||||
#include <public/game/server/iplayerinfo.h>
|
||||
#include <public/entity2/entitysystem.h>
|
||||
|
||||
@@ -52,6 +53,7 @@ IUniformRandomStream* randomStream = nullptr;
|
||||
IEngineTrace* engineTrace = nullptr;
|
||||
IEngineSound* engineSound = nullptr;
|
||||
IEngineServiceMgr* engineServiceManager = nullptr;
|
||||
INetworkMessages* networkMessages = nullptr;
|
||||
INetworkStringTableContainer* netStringTables = nullptr;
|
||||
CGlobalVars* globalVars = nullptr;
|
||||
IFileSystem* fileSystem = nullptr;
|
||||
@@ -88,6 +90,7 @@ ChatManager chatManager;
|
||||
ServerManager serverManager;
|
||||
VoiceManager voiceManager;
|
||||
TickScheduler tickScheduler;
|
||||
UserMessageManager userMessageManager;
|
||||
|
||||
bool gameLoopInitialized = false;
|
||||
GetLegacyGameEventListener_t* GetLegacyGameEventListener = nullptr;
|
||||
|
||||
@@ -6,14 +6,14 @@
|
||||
#undef protected
|
||||
#undef private
|
||||
|
||||
#include <thread>
|
||||
#include <sourcehook/sourcehook.h>
|
||||
|
||||
#include <memory>
|
||||
#include <thread>
|
||||
|
||||
#include "ISmmAPI.h"
|
||||
#include "eiface.h"
|
||||
#include "iserver.h"
|
||||
#include <sourcehook/sourcehook.h>
|
||||
|
||||
class IGameEventManager2;
|
||||
class IPlayerInfoManager;
|
||||
@@ -26,6 +26,7 @@ class IEngineServiceMgr;
|
||||
class INetworkStringTableContainer;
|
||||
class CGlobalVars;
|
||||
class IFileSystem;
|
||||
class INetworkMessages;
|
||||
class IServerTools;
|
||||
class IPhysics;
|
||||
class IPhysicsCollision;
|
||||
@@ -73,6 +74,7 @@ extern IUniformRandomStream* randomStream;
|
||||
extern IEngineTrace* engineTrace;
|
||||
extern IEngineSound* engineSound;
|
||||
extern IEngineServiceMgr* engineServiceManager;
|
||||
extern INetworkMessages* networkMessages;
|
||||
extern INetworkStringTableContainer* netStringTables;
|
||||
extern CGlobalVars* globalVars;
|
||||
extern IFileSystem* fileSystem;
|
||||
|
||||
@@ -95,44 +95,47 @@ json WriteTypeJson(json obj, CSchemaType* current_type)
|
||||
|
||||
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 = globals::schemaSystem->FindTypeScopeForModule(MODULE_PREFIX "server" MODULE_EXT);
|
||||
|
||||
auto index = pType->m_DeclaredClasses.m_Map.FirstInorder();
|
||||
std::vector<CSchemaClassInfo*> classes;
|
||||
do
|
||||
{
|
||||
classes.push_back(pType->m_DeclaredClasses.m_Map.Element(index)->m_pClassInfo);
|
||||
index = pType->m_DeclaredClasses.m_Map.NextInorder(index);
|
||||
} while (index != pType->m_DeclaredClasses.m_Map.InvalidIndex());
|
||||
|
||||
index = pType->m_DeclaredEnums.m_Map.FirstInorder();
|
||||
std::vector<CSchemaEnumInfo*> enums;
|
||||
do
|
||||
{
|
||||
enums.push_back(pType->m_DeclaredEnums.m_Map.Element(index)->m_pEnumInfo);
|
||||
index = pType->m_DeclaredEnums.m_Map.NextInorder(index);
|
||||
} while (index != pType->m_DeclaredEnums.m_Map.InvalidIndex());
|
||||
|
||||
pType = globals::schemaSystem->GlobalTypeScope();
|
||||
index = pType->m_DeclaredClasses.m_Map.FirstInorder();
|
||||
do
|
||||
{
|
||||
classes.push_back(pType->m_DeclaredClasses.m_Map.Element(index)->m_pClassInfo);
|
||||
index = pType->m_DeclaredClasses.m_Map.NextInorder(index);
|
||||
} while (index != pType->m_DeclaredClasses.m_Map.InvalidIndex());
|
||||
|
||||
index = pType->m_DeclaredEnums.m_Map.FirstInorder();
|
||||
do
|
||||
{
|
||||
enums.push_back(pType->m_DeclaredEnums.m_Map.Element(index)->m_pEnumInfo);
|
||||
index = pType->m_DeclaredEnums.m_Map.NextInorder(index);
|
||||
} while (index != pType->m_DeclaredEnums.m_Map.InvalidIndex());
|
||||
|
||||
json j;
|
||||
j["classes"] = json::object();
|
||||
j["enums"] = json::object();
|
||||
|
||||
for (const auto& line : classNames)
|
||||
for (const auto& pClassInfo : classes)
|
||||
{
|
||||
auto* pClassInfo = pType->FindDeclaredClass(line.c_str()).Get();
|
||||
if (!pClassInfo) continue;
|
||||
|
||||
short fieldsSize = pClassInfo->m_nFieldCount;
|
||||
SchemaClassFieldData_t* pFields = pClassInfo->m_pFields;
|
||||
|
||||
@@ -155,11 +158,8 @@ CON_COMMAND(dump_schema, "dump schema symbols")
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto& line : enumNames)
|
||||
for (const auto& pEnumInfo : enums)
|
||||
{
|
||||
auto* pEnumInfo = pType->FindDeclaredEnum(line.c_str()).Get();
|
||||
if (!pEnumInfo) continue;
|
||||
|
||||
j["enums"][pEnumInfo->m_pszName] = json::object();
|
||||
j["enums"][pEnumInfo->m_pszName]["align"] = pEnumInfo->m_nSize;
|
||||
j["enums"][pEnumInfo->m_pszName]["items"] = json::array();
|
||||
|
||||
208
src/core/managers/usermessage_manager.cpp
Normal file
208
src/core/managers/usermessage_manager.cpp
Normal file
@@ -0,0 +1,208 @@
|
||||
/*
|
||||
* This file is part of CounterStrikeSharp.
|
||||
* CounterStrikeSharp is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* CounterStrikeSharp 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 CounterStrikeSharp. If not, see <https://www.gnu.org/licenses/>. *
|
||||
*/
|
||||
|
||||
#include "core/managers/usermessage_manager.h"
|
||||
|
||||
#include <entity2/entitysystem.h>
|
||||
#include <public/eiface.h>
|
||||
|
||||
#include "core/UserMessage.h"
|
||||
#include "core/log.h"
|
||||
#include "core/managers/player_manager.h"
|
||||
#include "igameeventsystem.h"
|
||||
#include "scripting/callback_manager.h"
|
||||
|
||||
using namespace google;
|
||||
|
||||
SH_DECL_HOOK8_void(IGameEventSystem,
|
||||
PostEventAbstract,
|
||||
SH_NOATTRIB,
|
||||
0,
|
||||
CSplitScreenSlot,
|
||||
bool,
|
||||
int,
|
||||
const uint64*,
|
||||
INetworkMessageInternal*,
|
||||
const CNetMessage*,
|
||||
unsigned long,
|
||||
NetChannelBufType_t)
|
||||
|
||||
namespace counterstrikesharp
|
||||
{
|
||||
UserMessageManager::UserMessageManager() {}
|
||||
|
||||
UserMessageManager::~UserMessageManager() {}
|
||||
|
||||
void UserMessageManager::OnAllInitialized()
|
||||
{
|
||||
SH_ADD_HOOK_MEMFUNC(IGameEventSystem, PostEventAbstract, globals::gameEventSystem, this, &UserMessageManager::Hook_PostEvent,
|
||||
false);
|
||||
}
|
||||
|
||||
void UserMessageManager::OnShutdown()
|
||||
{
|
||||
SH_REMOVE_HOOK_MEMFUNC(IGameEventSystem, PostEventAbstract, globals::gameEventSystem, this, &UserMessageManager::Hook_PostEvent,
|
||||
false);
|
||||
}
|
||||
|
||||
void UserMessageManager::HookUserMessage(int messageId, CallbackT fnCallback, HookMode mode)
|
||||
{
|
||||
UserMessageHook* pHook;
|
||||
|
||||
CSSHARP_CORE_TRACE("Hooking user message: {0} with callback pointer: {1}", messageId, (void*)fnCallback);
|
||||
|
||||
auto search = m_hooksMap.find(messageId);
|
||||
// If hook struct is not found
|
||||
if (search == m_hooksMap.end())
|
||||
{
|
||||
pHook = new UserMessageHook();
|
||||
|
||||
if (mode == HookMode::Post)
|
||||
{
|
||||
pHook->m_pPostHook = globals::callbackManager.CreateCallback("");
|
||||
pHook->m_pPostHook->AddListener(fnCallback);
|
||||
}
|
||||
else
|
||||
{
|
||||
pHook->m_pPreHook = globals::callbackManager.CreateCallback("");
|
||||
pHook->m_pPreHook->AddListener(fnCallback);
|
||||
}
|
||||
|
||||
pHook->m_messageId = messageId;
|
||||
|
||||
m_hooksMap[messageId] = pHook;
|
||||
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
pHook = search->second;
|
||||
}
|
||||
|
||||
if (mode == HookMode::Post)
|
||||
{
|
||||
if (!pHook->m_pPostHook)
|
||||
{
|
||||
pHook->m_pPostHook = globals::callbackManager.CreateCallback("");
|
||||
}
|
||||
|
||||
pHook->m_pPostHook->AddListener(fnCallback);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!pHook->m_pPreHook)
|
||||
{
|
||||
pHook->m_pPreHook = globals::callbackManager.CreateCallback("");
|
||||
}
|
||||
|
||||
pHook->m_pPreHook->AddListener(fnCallback);
|
||||
}
|
||||
}
|
||||
|
||||
void UserMessageManager::UnhookUserMessage(int messageId, CallbackT fnCallback, HookMode mode)
|
||||
{
|
||||
UserMessageHook* pHook;
|
||||
ScriptCallback* pCallback;
|
||||
|
||||
auto search = m_hooksMap.find(messageId);
|
||||
if (search == m_hooksMap.end())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
pHook = search->second;
|
||||
|
||||
if (mode == HookMode::Post)
|
||||
{
|
||||
pCallback = pHook->m_pPostHook;
|
||||
}
|
||||
else
|
||||
{
|
||||
pCallback = pHook->m_pPreHook;
|
||||
}
|
||||
|
||||
pCallback->RemoveListener(fnCallback);
|
||||
|
||||
if (pCallback->GetFunctionCount() == 0)
|
||||
{
|
||||
globals::callbackManager.ReleaseCallback(pCallback);
|
||||
|
||||
if (mode == HookMode::Post)
|
||||
{
|
||||
pHook->m_pPostHook = nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
pHook->m_pPreHook = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
CSSHARP_CORE_TRACE("Unhooking user message: {0} with callback pointer: {1}", messageId, (void*)fnCallback);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void UserMessageManager::Hook_PostEvent(CSplitScreenSlot nSlot, bool bLocalOnly, int nClientCount, const uint64* clients,
|
||||
INetworkMessageInternal* pEvent, const CNetMessage* pData, unsigned long nSize,
|
||||
NetChannelBufType_t bufType)
|
||||
{
|
||||
auto message = UserMessage(pEvent, pData, nClientCount, const_cast<uint64*>(clients));
|
||||
|
||||
auto iMessageID = message.GetMessageID();
|
||||
auto I = m_hooksMap.find(iMessageID);
|
||||
|
||||
HookResult result = HookResult::Continue;
|
||||
|
||||
if (I != m_hooksMap.end())
|
||||
{
|
||||
auto pEventHook = I->second;
|
||||
auto* pCallback = pEventHook->m_pPreHook;
|
||||
|
||||
if (pCallback)
|
||||
{
|
||||
CSSHARP_CORE_TRACE("Pushing user message `{}` pointer: {}, post: {}", iMessageID, (void*)pEvent, false);
|
||||
pCallback->Reset();
|
||||
pCallback->ScriptContext().Push(&message);
|
||||
|
||||
for (auto fnMethodToCall : pCallback->GetFunctions())
|
||||
{
|
||||
if (!fnMethodToCall) continue;
|
||||
fnMethodToCall(&pCallback->ScriptContextStruct());
|
||||
|
||||
auto hookResult = pCallback->ScriptContext().GetResult<HookResult>();
|
||||
|
||||
if (hookResult >= HookResult::Stop)
|
||||
{
|
||||
RETURN_META(MRES_SUPERCEDE);
|
||||
}
|
||||
|
||||
if (hookResult >= HookResult::Handled)
|
||||
{
|
||||
result = hookResult;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (result >= HookResult::Handled)
|
||||
{
|
||||
RETURN_META(MRES_SUPERCEDE);
|
||||
}
|
||||
|
||||
RETURN_META(MRES_IGNORED);
|
||||
}
|
||||
|
||||
} // namespace counterstrikesharp
|
||||
64
src/core/managers/usermessage_manager.h
Normal file
64
src/core/managers/usermessage_manager.h
Normal file
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* This file is part of CounterStrikeSharp.
|
||||
* CounterStrikeSharp is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* CounterStrikeSharp 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 CounterStrikeSharp. If not, see <https://www.gnu.org/licenses/>. *
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "core/global_listener.h"
|
||||
#include "core/globals.h"
|
||||
#include "inetchannel.h"
|
||||
#include "networksystem/inetworkserializer.h"
|
||||
#include "scripting/script_engine.h"
|
||||
|
||||
namespace counterstrikesharp {
|
||||
class ScriptCallback;
|
||||
|
||||
struct UserMessageHook
|
||||
{
|
||||
UserMessageHook()
|
||||
{
|
||||
m_pPreHook = nullptr;
|
||||
m_pPostHook = nullptr;
|
||||
}
|
||||
counterstrikesharp::ScriptCallback* m_pPreHook;
|
||||
counterstrikesharp::ScriptCallback* m_pPostHook;
|
||||
int m_messageId;
|
||||
};
|
||||
|
||||
class UserMessageManager : public GlobalClass
|
||||
{
|
||||
public:
|
||||
UserMessageManager();
|
||||
~UserMessageManager();
|
||||
void OnAllInitialized() override;
|
||||
void OnShutdown() override;
|
||||
void Hook_PostEvent(CSplitScreenSlot nSlot,
|
||||
bool bLocalOnly,
|
||||
int nClientCount,
|
||||
const uint64* clients,
|
||||
INetworkMessageInternal* pEvent,
|
||||
const CNetMessage* pData,
|
||||
unsigned long nSize,
|
||||
NetChannelBufType_t bufType);
|
||||
|
||||
void UnhookUserMessage(int messageId, CallbackT fnCallback, HookMode mode);
|
||||
void HookUserMessage(int messageId, CallbackT fnCallback, HookMode mode);
|
||||
|
||||
private:
|
||||
ScriptCallback* m_on_user_message_callback;
|
||||
std::map<int, UserMessageHook*> m_hooksMap;
|
||||
};
|
||||
|
||||
} // namespace counterstrikesharp
|
||||
84
src/core/recipientfilters.h
Normal file
84
src/core/recipientfilters.h
Normal file
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* This file is part of CounterStrikeSharp.
|
||||
* CounterStrikeSharp is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* CounterStrikeSharp 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 CounterStrikeSharp. If not, see <https://www.gnu.org/licenses/>. *
|
||||
*/
|
||||
|
||||
#include "irecipientfilter.h"
|
||||
|
||||
class CSingleRecipientFilter : public IRecipientFilter
|
||||
{
|
||||
public:
|
||||
CSingleRecipientFilter(CPlayerSlot iRecipient, NetChannelBufType_t nBufType = BUF_RELIABLE, bool bInitMessage = false)
|
||||
: m_iRecipient(iRecipient), m_nBufType(nBufType), m_bInitMessage(bInitMessage)
|
||||
{
|
||||
}
|
||||
|
||||
~CSingleRecipientFilter() override {}
|
||||
|
||||
NetChannelBufType_t GetNetworkBufType(void) const override { return m_nBufType; }
|
||||
bool IsInitMessage(void) const override { return m_bInitMessage; }
|
||||
int GetRecipientCount(void) const override { return 1; }
|
||||
CPlayerSlot GetRecipientIndex(int slot) const override { return m_iRecipient; }
|
||||
|
||||
private:
|
||||
CPlayerSlot m_iRecipient;
|
||||
NetChannelBufType_t m_nBufType;
|
||||
bool m_bInitMessage;
|
||||
};
|
||||
|
||||
class CRecipientFilter : public IRecipientFilter
|
||||
{
|
||||
public:
|
||||
CRecipientFilter()
|
||||
{
|
||||
m_nBufType = BUF_RELIABLE;
|
||||
m_bInitMessage = false;
|
||||
}
|
||||
|
||||
~CRecipientFilter() override {}
|
||||
|
||||
NetChannelBufType_t GetNetworkBufType(void) const override { return m_nBufType; }
|
||||
bool IsInitMessage(void) const override { return m_bInitMessage; }
|
||||
int GetRecipientCount(void) const override { return m_Recipients.Count(); }
|
||||
|
||||
CPlayerSlot GetRecipientIndex(int slot) const override
|
||||
{
|
||||
if (slot < 0 || slot >= GetRecipientCount()) return CPlayerSlot(-1);
|
||||
|
||||
return m_Recipients[slot];
|
||||
}
|
||||
|
||||
void AddRecipient(CPlayerSlot slot)
|
||||
{
|
||||
if (m_Recipients.Find(slot) != m_Recipients.InvalidIndex()) return;
|
||||
|
||||
m_Recipients.AddToTail(slot);
|
||||
}
|
||||
|
||||
void AddRecipientsFromMask(uint64 mask)
|
||||
{
|
||||
for (int i = 0; i < 64; ++i)
|
||||
{
|
||||
if (mask & (uint64)1 << i)
|
||||
{
|
||||
AddRecipient(CPlayerSlot(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
NetChannelBufType_t m_nBufType;
|
||||
bool m_bInitMessage;
|
||||
CUtlVectorFixed<CPlayerSlot, 64> m_Recipients;
|
||||
};
|
||||
@@ -101,6 +101,7 @@ bool CounterStrikeSharpMMPlugin::Load(PluginId id, ISmmAPI* ismm, char* error, s
|
||||
GET_V_IFACE_ANY(GetEngineFactory, globals::schemaSystem, CSchemaSystem, SCHEMASYSTEM_INTERFACE_VERSION);
|
||||
GET_V_IFACE_ANY(GetEngineFactory, globals::gameEventSystem, IGameEventSystem, GAMEEVENTSYSTEM_INTERFACE_VERSION);
|
||||
GET_V_IFACE_ANY(GetEngineFactory, globals::engineServiceManager, IEngineServiceMgr, ENGINESERVICEMGR_INTERFACE_VERSION);
|
||||
GET_V_IFACE_ANY(GetEngineFactory, globals::networkMessages, INetworkMessages, NETWORKMESSAGES_INTERFACE_VERSION);
|
||||
|
||||
auto coreconfig_path = std::string(utils::ConfigsDirectory() + "/core");
|
||||
globals::coreConfig = new CCoreConfig(coreconfig_path);
|
||||
|
||||
@@ -17,17 +17,17 @@
|
||||
#ifndef _INCLUDE_METAMOD_SOURCE_STUB_PLUGIN_H_
|
||||
#define _INCLUDE_METAMOD_SOURCE_STUB_PLUGIN_H_
|
||||
|
||||
// clang-format off
|
||||
#include <ISmmPlugin.h>
|
||||
#include <functional>
|
||||
#include <iserver.h>
|
||||
#include <igameevents.h>
|
||||
#include <iplayerinfo.h>
|
||||
#include <iserver.h>
|
||||
#include <sh_vector.h>
|
||||
|
||||
#include <functional>
|
||||
#include <vector>
|
||||
|
||||
#include "concurrentqueue.h"
|
||||
#include "entitysystem.h"
|
||||
#include "concurrentqueue.h"
|
||||
// clang-format on
|
||||
|
||||
namespace counterstrikesharp {
|
||||
class ScriptCallback;
|
||||
|
||||
@@ -224,6 +224,20 @@ void PrintToServerConsole(ScriptContext& scriptContext)
|
||||
META_CONPRINT(message);
|
||||
}
|
||||
|
||||
void DisconnectClient(ScriptContext& scriptContext)
|
||||
{
|
||||
auto slot = scriptContext.GetArgument<int>(0);
|
||||
auto disconnectReason = scriptContext.GetArgument<ENetworkDisconnectionReason>(1);
|
||||
|
||||
if (!ENetworkDisconnectionReason_IsValid(disconnectReason))
|
||||
{
|
||||
scriptContext.ThrowNativeError("Invalid disconnect reason");
|
||||
return;
|
||||
}
|
||||
|
||||
globals::engineServer2->DisconnectClient(slot, disconnectReason);
|
||||
}
|
||||
|
||||
REGISTER_NATIVES(engine, {
|
||||
ScriptEngine::RegisterNativeHandler("GET_GAME_DIRECTORY", GetGameDirectory);
|
||||
ScriptEngine::RegisterNativeHandler("GET_MAP_NAME", GetMapName);
|
||||
@@ -248,5 +262,6 @@ REGISTER_NATIVES(engine, {
|
||||
ScriptEngine::RegisterNativeHandler("GET_VALVE_INTERFACE", GetValveInterface);
|
||||
ScriptEngine::RegisterNativeHandler("GET_COMMAND_PARAM_VALUE", GetCommandParamValue);
|
||||
ScriptEngine::RegisterNativeHandler("PRINT_TO_SERVER_CONSOLE", PrintToServerConsole);
|
||||
ScriptEngine::RegisterNativeHandler("DISCONNECT_CLIENT", DisconnectClient);
|
||||
})
|
||||
} // namespace counterstrikesharp
|
||||
|
||||
@@ -25,4 +25,5 @@ QUEUE_TASK_FOR_FRAME: tick:int, callback:func -> void
|
||||
QUEUE_TASK_FOR_NEXT_WORLD_UPDATE: callback:func -> void
|
||||
GET_VALVE_INTERFACE: interfaceType:int, interfaceName:string -> pointer
|
||||
GET_COMMAND_PARAM_VALUE: param:string, dataType:DataType_t, defaultValue:any -> any
|
||||
PRINT_TO_SERVER_CONSOLE: msg:string -> void
|
||||
PRINT_TO_SERVER_CONSOLE: msg:string -> void
|
||||
DISCONNECT_CLIENT: slot:int, reason:int -> void
|
||||
|
||||
@@ -5,4 +5,5 @@ UNHOOK_FUNCTION: function:pointer, hook:callback, post:bool -> void
|
||||
EXECUTE_VIRTUAL_FUNCTION: function:pointer,arguments:object[] -> any
|
||||
FIND_SIGNATURE: modulePath:string, signature:string -> pointer
|
||||
GET_NETWORK_VECTOR_SIZE: vec:pointer -> int
|
||||
GET_NETWORK_VECTOR_ELEMENT_AT: vec:pointer, index:int -> pointer
|
||||
GET_NETWORK_VECTOR_ELEMENT_AT: vec:pointer, index:int -> pointer
|
||||
REMOVE_ALL_NETWORK_VECTOR_ELEMENTS: vec:pointer -> void
|
||||
713
src/scripting/natives/natives_usermessages.cpp
Normal file
713
src/scripting/natives/natives_usermessages.cpp
Normal file
@@ -0,0 +1,713 @@
|
||||
/*
|
||||
* This file is part of CounterStrikeSharp.
|
||||
* CounterStrikeSharp is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* CounterStrikeSharp 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 CounterStrikeSharp. If not, see <https://www.gnu.org/licenses/>. *
|
||||
*/
|
||||
// clang-format off
|
||||
|
||||
#include "core/UserMessage.h"
|
||||
#include "core/globals.h"
|
||||
#include "core/log.h"
|
||||
#include "core/managers/usermessage_manager.h"
|
||||
#include "igameeventsystem.h"
|
||||
#include "scripting/autonative.h"
|
||||
|
||||
#include "core/recipientfilters.h"
|
||||
|
||||
// clang-format on
|
||||
|
||||
namespace counterstrikesharp {
|
||||
|
||||
#define GET_MESSAGE_OR_ERR() \
|
||||
auto message = scriptContext.GetArgument<UserMessage*>(0); \
|
||||
if (message == nullptr || message->GetMessageID() < 0) \
|
||||
{ \
|
||||
scriptContext.ThrowNativeError("Invalid message"); \
|
||||
return; \
|
||||
}
|
||||
|
||||
#define GET_FIELD_NAME_OR_ERR() const char* fieldName = scriptContext.GetArgument<const char*>(1);
|
||||
|
||||
std::vector<UserMessage*> managed_usermessages;
|
||||
|
||||
static void HookUserMessage(ScriptContext& script_context)
|
||||
{
|
||||
auto messageId = script_context.GetArgument<int>(0);
|
||||
auto callback = script_context.GetArgument<CallbackT>(1);
|
||||
auto mode = script_context.GetArgument<HookMode>(2);
|
||||
|
||||
globals::userMessageManager.HookUserMessage(messageId, callback, mode);
|
||||
}
|
||||
|
||||
static void UnhookUserMessage(ScriptContext& script_context)
|
||||
{
|
||||
auto messageId = script_context.GetArgument<int>(0);
|
||||
auto callback = script_context.GetArgument<CallbackT>(1);
|
||||
auto mode = script_context.GetArgument<HookMode>(2);
|
||||
|
||||
globals::userMessageManager.UnhookUserMessage(messageId, callback, mode);
|
||||
}
|
||||
|
||||
static void GetInt32OrUnsignedOrEnum(ScriptContext& script_context)
|
||||
{
|
||||
auto message = script_context.GetArgument<UserMessage*>(0);
|
||||
auto fieldName = script_context.GetArgument<const char*>(1);
|
||||
|
||||
int returnValue;
|
||||
if (!message->GetInt32OrUnsignedOrEnum(fieldName, &returnValue))
|
||||
{
|
||||
script_context.ThrowNativeError("Invalid field \"%s\" for message \"%s\"", fieldName,
|
||||
message->GetProtobufMessage()->GetTypeName().c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
script_context.SetResult(returnValue);
|
||||
}
|
||||
|
||||
static void SetInt32OrUnsignedOrEnum(ScriptContext& script_context)
|
||||
{
|
||||
auto message = script_context.GetArgument<UserMessage*>(0);
|
||||
auto fieldName = script_context.GetArgument<const char*>(1);
|
||||
auto value = script_context.GetArgument<int>(2);
|
||||
|
||||
if (!message->SetInt32OrUnsignedOrEnum(fieldName, value))
|
||||
{
|
||||
script_context.ThrowNativeError("Invalid field \"%s\" for message \"%s\"", fieldName,
|
||||
message->GetProtobufMessage()->GetTypeName().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
static void PbReadInt(ScriptContext& scriptContext)
|
||||
{
|
||||
GET_MESSAGE_OR_ERR();
|
||||
GET_FIELD_NAME_OR_ERR();
|
||||
|
||||
int returnValue;
|
||||
|
||||
auto index = scriptContext.GetArgument<int>(2);
|
||||
|
||||
if (index < 0)
|
||||
{
|
||||
if (!message->GetInt32OrUnsignedOrEnum(fieldName, &returnValue))
|
||||
{
|
||||
scriptContext.ThrowNativeError("Invalid field \"%s\" for message \"%s\"", fieldName,
|
||||
message->GetProtobufMessage()->GetTypeName().c_str());
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!message->GetRepeatedInt32OrUnsignedOrEnum(fieldName, index, &returnValue))
|
||||
{
|
||||
scriptContext.ThrowNativeError("Invalid field \"%s\"[%d] for message \"%s\"", fieldName, index,
|
||||
message->GetProtobufMessage()->GetTypeName().c_str());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
scriptContext.SetResult(returnValue);
|
||||
}
|
||||
|
||||
static void PbReadInt64(ScriptContext& scriptContext)
|
||||
{
|
||||
GET_MESSAGE_OR_ERR();
|
||||
GET_FIELD_NAME_OR_ERR();
|
||||
|
||||
int64 returnValue;
|
||||
|
||||
auto index = scriptContext.GetArgument<int>(2);
|
||||
|
||||
if (index < 0)
|
||||
{
|
||||
if (!message->GetInt64OrUnsigned(fieldName, &returnValue))
|
||||
{
|
||||
scriptContext.ThrowNativeError("Invalid field \"%s\" for message \"%s\"", fieldName,
|
||||
message->GetProtobufMessage()->GetTypeName().c_str());
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!message->GetRepeatedInt64OrUnsigned(fieldName, index, &returnValue))
|
||||
{
|
||||
scriptContext.ThrowNativeError("Invalid field \"%s\"[%d] for message \"%s\"", fieldName, index,
|
||||
message->GetProtobufMessage()->GetTypeName().c_str());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
scriptContext.SetResult(returnValue);
|
||||
}
|
||||
|
||||
static void PbReadFloat(ScriptContext& scriptContext)
|
||||
{
|
||||
GET_MESSAGE_OR_ERR();
|
||||
GET_FIELD_NAME_OR_ERR();
|
||||
|
||||
float returnValue;
|
||||
|
||||
auto index = scriptContext.GetArgument<int>(2);
|
||||
|
||||
if (index < 0)
|
||||
{
|
||||
if (!message->GetFloatOrDouble(fieldName, &returnValue))
|
||||
{
|
||||
scriptContext.ThrowNativeError("Invalid field \"%s\" for message \"%s\"", fieldName,
|
||||
message->GetProtobufMessage()->GetTypeName().c_str());
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!message->GetRepeatedFloatOrDouble(fieldName, index, &returnValue))
|
||||
{
|
||||
scriptContext.ThrowNativeError("Invalid field \"%s\"[%d] for message \"%s\"", fieldName, index,
|
||||
message->GetProtobufMessage()->GetTypeName().c_str());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
scriptContext.SetResult(returnValue);
|
||||
}
|
||||
|
||||
static void PbReadBool(ScriptContext& scriptContext)
|
||||
{
|
||||
GET_MESSAGE_OR_ERR();
|
||||
GET_FIELD_NAME_OR_ERR();
|
||||
|
||||
bool returnValue;
|
||||
|
||||
auto index = scriptContext.GetArgument<int>(2);
|
||||
|
||||
if (index < 0)
|
||||
{
|
||||
if (!message->GetBool(fieldName, &returnValue))
|
||||
{
|
||||
scriptContext.ThrowNativeError("Invalid field \"%s\" for message \"%s\"", fieldName,
|
||||
message->GetProtobufMessage()->GetTypeName().c_str());
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!message->GetRepeatedBool(fieldName, index, &returnValue))
|
||||
{
|
||||
scriptContext.ThrowNativeError("Invalid field \"%s\"[%d] for message \"%s\"", fieldName, index,
|
||||
message->GetProtobufMessage()->GetTypeName().c_str());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
scriptContext.SetResult(returnValue);
|
||||
}
|
||||
|
||||
static void PbReadString(ScriptContext& scriptContext)
|
||||
{
|
||||
GET_MESSAGE_OR_ERR();
|
||||
GET_FIELD_NAME_OR_ERR();
|
||||
|
||||
std::string returnValue;
|
||||
|
||||
auto index = scriptContext.GetArgument<int>(2);
|
||||
|
||||
if (index < 0)
|
||||
{
|
||||
if (!message->GetString(fieldName, returnValue))
|
||||
{
|
||||
scriptContext.ThrowNativeError("Invalid field \"%s\" for message \"%s\"", fieldName,
|
||||
message->GetProtobufMessage()->GetTypeName().c_str());
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!message->GetRepeatedString(fieldName, index, returnValue))
|
||||
{
|
||||
scriptContext.ThrowNativeError("Invalid field \"%s\"[%d] for message \"%s\"", fieldName, index,
|
||||
message->GetProtobufMessage()->GetTypeName().c_str());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
scriptContext.SetResult(returnValue.c_str());
|
||||
}
|
||||
|
||||
static void PbGetRepeatedFieldCount(ScriptContext& scriptContext)
|
||||
{
|
||||
GET_MESSAGE_OR_ERR();
|
||||
GET_FIELD_NAME_OR_ERR();
|
||||
|
||||
auto count = message->GetRepeatedFieldCount(fieldName);
|
||||
|
||||
if (count == -1)
|
||||
{
|
||||
return scriptContext.ThrowNativeError("Invalid field \"%s\" for message \"%s\"", fieldName,
|
||||
message->GetProtobufMessage()->GetTypeName().c_str());
|
||||
}
|
||||
|
||||
scriptContext.SetResult(count);
|
||||
}
|
||||
|
||||
static void PbHasField(ScriptContext& scriptContext)
|
||||
{
|
||||
GET_MESSAGE_OR_ERR();
|
||||
GET_FIELD_NAME_OR_ERR();
|
||||
|
||||
scriptContext.SetResult(message->HasField(fieldName));
|
||||
}
|
||||
|
||||
static void PbSetInt(ScriptContext& scriptContext)
|
||||
{
|
||||
GET_MESSAGE_OR_ERR();
|
||||
GET_FIELD_NAME_OR_ERR();
|
||||
|
||||
auto value = scriptContext.GetArgument<int>(2);
|
||||
auto index = scriptContext.GetArgument<int>(3);
|
||||
|
||||
if (index < 0)
|
||||
{
|
||||
if (!message->SetInt32OrUnsignedOrEnum(fieldName, value))
|
||||
{
|
||||
scriptContext.ThrowNativeError("Invalid field \"%s\" for message \"%s\"", fieldName,
|
||||
message->GetProtobufMessage()->GetTypeName().c_str());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!message->SetRepeatedInt32OrUnsignedOrEnum(fieldName, index, value))
|
||||
{
|
||||
scriptContext.ThrowNativeError("Invalid field \"%s\"[%d] for message \"%s\"", fieldName, index,
|
||||
message->GetProtobufMessage()->GetTypeName().c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void PbSetInt64(ScriptContext& scriptContext)
|
||||
{
|
||||
GET_MESSAGE_OR_ERR();
|
||||
GET_FIELD_NAME_OR_ERR();
|
||||
|
||||
auto value = scriptContext.GetArgument<int64>(2);
|
||||
auto index = scriptContext.GetArgument<int>(3);
|
||||
|
||||
if (index < 0)
|
||||
{
|
||||
if (!message->SetInt64OrUnsigned(fieldName, value))
|
||||
{
|
||||
scriptContext.ThrowNativeError("Invalid field \"%s\" for message \"%s\"", fieldName,
|
||||
message->GetProtobufMessage()->GetTypeName().c_str());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!message->SetRepeatedInt64OrUnsigned(fieldName, index, value))
|
||||
{
|
||||
scriptContext.ThrowNativeError("Invalid field \"%s\"[%d] for message \"%s\"", fieldName, index,
|
||||
message->GetProtobufMessage()->GetTypeName().c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void PbSetFloat(ScriptContext& scriptContext)
|
||||
{
|
||||
GET_MESSAGE_OR_ERR();
|
||||
GET_FIELD_NAME_OR_ERR();
|
||||
|
||||
auto value = scriptContext.GetArgument<float>(2);
|
||||
auto index = scriptContext.GetArgument<int>(3);
|
||||
|
||||
if (index < 0)
|
||||
{
|
||||
if (!message->SetFloatOrDouble(fieldName, value))
|
||||
{
|
||||
scriptContext.ThrowNativeError("Invalid field \"%s\" for message \"%s\"", fieldName,
|
||||
message->GetProtobufMessage()->GetTypeName().c_str());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!message->SetRepeatedFloatOrDouble(fieldName, index, value))
|
||||
{
|
||||
scriptContext.ThrowNativeError("Invalid field \"%s\"[%d] for message \"%s\"", fieldName, index,
|
||||
message->GetProtobufMessage()->GetTypeName().c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void PbSetBool(ScriptContext& scriptContext)
|
||||
{
|
||||
GET_MESSAGE_OR_ERR();
|
||||
GET_FIELD_NAME_OR_ERR();
|
||||
|
||||
auto value = scriptContext.GetArgument<bool>(2);
|
||||
auto index = scriptContext.GetArgument<int>(3);
|
||||
|
||||
if (index < 0)
|
||||
{
|
||||
if (!message->SetBool(fieldName, value))
|
||||
{
|
||||
scriptContext.ThrowNativeError("Invalid field \"%s\" for message \"%s\"", fieldName,
|
||||
message->GetProtobufMessage()->GetTypeName().c_str());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!message->SetRepeatedBool(fieldName, index, value))
|
||||
{
|
||||
scriptContext.ThrowNativeError("Invalid field \"%s\"[%d] for message \"%s\"", fieldName, index,
|
||||
message->GetProtobufMessage()->GetTypeName().c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void PbSetString(ScriptContext& scriptContext)
|
||||
{
|
||||
GET_MESSAGE_OR_ERR();
|
||||
GET_FIELD_NAME_OR_ERR();
|
||||
|
||||
auto value = strdup(std::string(scriptContext.GetArgument<const char*>(2)).c_str());
|
||||
auto index = scriptContext.GetArgument<int>(3);
|
||||
|
||||
if (index < 0)
|
||||
{
|
||||
if (!message->SetString(fieldName, value))
|
||||
{
|
||||
scriptContext.ThrowNativeError("Invalid field \"%s\" for message \"%s\"", fieldName,
|
||||
message->GetProtobufMessage()->GetTypeName().c_str());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!message->SetRepeatedString(fieldName, index, value))
|
||||
{
|
||||
scriptContext.ThrowNativeError("Invalid field \"%s\"[%d] for message \"%s\"", fieldName, index,
|
||||
message->GetProtobufMessage()->GetTypeName().c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void PbAddInt(ScriptContext& scriptContext)
|
||||
{
|
||||
GET_MESSAGE_OR_ERR();
|
||||
GET_FIELD_NAME_OR_ERR();
|
||||
|
||||
auto value = scriptContext.GetArgument<int>(2);
|
||||
|
||||
if (!message->AddInt32OrUnsignedOrEnum(fieldName, value))
|
||||
{
|
||||
scriptContext.ThrowNativeError("Invalid field \"%s\" for message \"%s\"", fieldName,
|
||||
message->GetProtobufMessage()->GetTypeName().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
static void PbAddInt64(ScriptContext& scriptContext)
|
||||
{
|
||||
GET_MESSAGE_OR_ERR();
|
||||
GET_FIELD_NAME_OR_ERR();
|
||||
|
||||
auto value = scriptContext.GetArgument<int64>(2);
|
||||
|
||||
if (!message->AddInt64OrUnsigned(fieldName, value))
|
||||
{
|
||||
scriptContext.ThrowNativeError("Invalid field \"%s\" for message \"%s\"", fieldName,
|
||||
message->GetProtobufMessage()->GetTypeName().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
static void PbAddFloat(ScriptContext& scriptContext)
|
||||
{
|
||||
GET_MESSAGE_OR_ERR();
|
||||
GET_FIELD_NAME_OR_ERR();
|
||||
|
||||
auto value = scriptContext.GetArgument<float>(2);
|
||||
|
||||
if (!message->AddFloatOrDouble(fieldName, value))
|
||||
{
|
||||
scriptContext.ThrowNativeError("Invalid field \"%s\" for message \"%s\"", fieldName,
|
||||
message->GetProtobufMessage()->GetTypeName().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
static void PbAddBool(ScriptContext& scriptContext)
|
||||
{
|
||||
GET_MESSAGE_OR_ERR();
|
||||
GET_FIELD_NAME_OR_ERR();
|
||||
|
||||
auto value = scriptContext.GetArgument<bool>(2);
|
||||
|
||||
if (!message->AddBool(fieldName, value))
|
||||
{
|
||||
scriptContext.ThrowNativeError("Invalid field \"%s\" for message \"%s\"", fieldName,
|
||||
message->GetProtobufMessage()->GetTypeName().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
static void PbAddString(ScriptContext& scriptContext)
|
||||
{
|
||||
GET_MESSAGE_OR_ERR();
|
||||
GET_FIELD_NAME_OR_ERR();
|
||||
|
||||
auto value = scriptContext.GetArgument<const char*>(2);
|
||||
|
||||
if (!message->AddString(fieldName, value))
|
||||
{
|
||||
scriptContext.ThrowNativeError("Invalid field \"%s\" for message \"%s\"", fieldName,
|
||||
message->GetProtobufMessage()->GetTypeName().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
static void PbRemoveRepeatedFieldValue(ScriptContext& scriptContext)
|
||||
{
|
||||
GET_MESSAGE_OR_ERR();
|
||||
GET_FIELD_NAME_OR_ERR();
|
||||
|
||||
auto index = scriptContext.GetArgument<int>(2);
|
||||
|
||||
if (!message->RemoveRepeatedFieldValue(fieldName, index))
|
||||
{
|
||||
scriptContext.ThrowNativeError("Invalid field \"%s\"[%d] for message \"%s\"", fieldName, index,
|
||||
message->GetProtobufMessage()->GetTypeName().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
// static void PbReadMessage(ScriptContext& scriptContext)
|
||||
//{
|
||||
// GET_MESSAGE_OR_ERR();
|
||||
// GET_FIELD_NAME_OR_ERR();
|
||||
//
|
||||
// google::protobuf::Message* subMessage = nullptr;
|
||||
//
|
||||
// if (!message->GetMessage(fieldName, &subMessage))
|
||||
// {
|
||||
// scriptContext.ThrowNativeError("Invalid field \"%s\" for message \"%s\"", fieldName,
|
||||
// message->GetProtobufMessage()->GetTypeName().c_str());
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// auto subUserMessage = new UserMessage(subMessage);
|
||||
// managed_usermessages.push_back(subUserMessage);
|
||||
// scriptContext.SetResult(subUserMessage);
|
||||
// }
|
||||
//
|
||||
// static void PbReadRepeatedMessage(ScriptContext& scriptContext)
|
||||
//{
|
||||
// GET_MESSAGE_OR_ERR();
|
||||
// GET_FIELD_NAME_OR_ERR();
|
||||
//
|
||||
// const google::protobuf::Message* subMessage = nullptr;
|
||||
//
|
||||
// auto index = scriptContext.GetArgument<int>(2);
|
||||
//
|
||||
// if (!message->GetRepeatedMessage(fieldName, index, &subMessage))
|
||||
// {
|
||||
// scriptContext.ThrowNativeError("Invalid field \"%s\" for message \"%s\"", fieldName,
|
||||
// message->GetProtobufMessage()->GetTypeName().c_str());
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// auto subUserMessage = new UserMessage(const_cast<google::protobuf::Message*>(subMessage));
|
||||
// managed_usermessages.push_back(subUserMessage);
|
||||
// scriptContext.SetResult(subUserMessage);
|
||||
// }
|
||||
//
|
||||
// static void PbAddMessage(ScriptContext& scriptContext)
|
||||
//{
|
||||
// GET_MESSAGE_OR_ERR();
|
||||
// GET_FIELD_NAME_OR_ERR();
|
||||
//
|
||||
// google::protobuf::Message* subMessage;
|
||||
//
|
||||
// if (!message->AddMessage(fieldName, &subMessage))
|
||||
// {
|
||||
// scriptContext.ThrowNativeError("Invalid field \"%s\" for message \"%s\"", fieldName,
|
||||
// message->GetProtobufMessage()->GetTypeName().c_str());
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// auto subUserMessage = new UserMessage(subMessage);
|
||||
// managed_usermessages.push_back(subUserMessage);
|
||||
// scriptContext.SetResult(subUserMessage);
|
||||
// }
|
||||
|
||||
static void PbGetDebugString(ScriptContext& scriptContext)
|
||||
{
|
||||
GET_MESSAGE_OR_ERR();
|
||||
|
||||
scriptContext.SetResult(message->GetDebugString().c_str());
|
||||
}
|
||||
|
||||
static void UserMessageFindMessageIdByName(ScriptContext& scriptContext)
|
||||
{
|
||||
auto messageName = scriptContext.GetArgument<const char*>(0);
|
||||
auto message = globals::networkMessages->FindNetworkMessagePartial(messageName);
|
||||
|
||||
if (message == nullptr)
|
||||
{
|
||||
scriptContext.ThrowNativeError("Could not find user message: %s", messageName);
|
||||
return;
|
||||
}
|
||||
|
||||
scriptContext.SetResult(message->GetNetMessageInfo()->m_MessageId);
|
||||
}
|
||||
|
||||
static void UserMessageCreate(ScriptContext& scriptContext)
|
||||
{
|
||||
auto messageName = scriptContext.GetArgument<const char*>(0);
|
||||
auto message = new UserMessage(messageName);
|
||||
|
||||
if (message->GetSerializableMessage() == nullptr)
|
||||
{
|
||||
scriptContext.ThrowNativeError("Failed to create user message: %s", messageName);
|
||||
return;
|
||||
}
|
||||
|
||||
managed_usermessages.push_back(message);
|
||||
|
||||
scriptContext.SetResult(message);
|
||||
}
|
||||
|
||||
static void UserMessageCreateById(ScriptContext& scriptContext)
|
||||
{
|
||||
auto messageId = scriptContext.GetArgument<int>(0);
|
||||
auto message = new UserMessage(messageId);
|
||||
|
||||
if (message->GetSerializableMessage() == nullptr)
|
||||
{
|
||||
scriptContext.ThrowNativeError("Failed to create user message: %d", messageId);
|
||||
return;
|
||||
}
|
||||
|
||||
managed_usermessages.push_back(message);
|
||||
|
||||
scriptContext.SetResult(message);
|
||||
}
|
||||
|
||||
static void UserMessageGetRecipients(ScriptContext& scriptContext)
|
||||
{
|
||||
auto message = scriptContext.GetArgument<UserMessage*>(0);
|
||||
|
||||
if (message == nullptr)
|
||||
{
|
||||
scriptContext.ThrowNativeError("Invalid message");
|
||||
return;
|
||||
}
|
||||
|
||||
scriptContext.SetResult(message->GetRecipientMask() ? *message->GetRecipientMask() : 0);
|
||||
}
|
||||
|
||||
static void UserMessageSetRecipients(ScriptContext& scriptContext)
|
||||
{
|
||||
auto message = scriptContext.GetArgument<UserMessage*>(0);
|
||||
auto recipientMask = scriptContext.GetArgument<uint64>(1);
|
||||
|
||||
*message->GetRecipientMask() = recipientMask;
|
||||
}
|
||||
|
||||
static void UserMessageSend(ScriptContext& scriptContext)
|
||||
{
|
||||
auto message = scriptContext.GetArgument<UserMessage*>(0);
|
||||
|
||||
CRecipientFilter filter{};
|
||||
filter.AddRecipientsFromMask(message->GetRecipientMask() ? *message->GetRecipientMask() : 0);
|
||||
|
||||
globals::gameEventSystem->PostEventAbstract(0, false, &filter, message->GetSerializableMessage(), message->GetProtobufMessage(), 0);
|
||||
}
|
||||
|
||||
static void UserMessageDelete(ScriptContext& scriptContext)
|
||||
{
|
||||
auto message = scriptContext.GetArgument<UserMessage*>(0);
|
||||
|
||||
auto it = std::find(managed_usermessages.begin(), managed_usermessages.end(), message);
|
||||
if (it != managed_usermessages.end())
|
||||
{
|
||||
managed_usermessages.erase(it);
|
||||
delete message;
|
||||
}
|
||||
}
|
||||
|
||||
static void UserMessageGetMessageId(ScriptContext& scriptContext)
|
||||
{
|
||||
auto message = scriptContext.GetArgument<UserMessage*>(0);
|
||||
|
||||
if (message == nullptr || message->GetSerializableMessage() == nullptr)
|
||||
{
|
||||
scriptContext.ThrowNativeError("Invalid message");
|
||||
return;
|
||||
}
|
||||
|
||||
scriptContext.SetResult(message->GetMessageID());
|
||||
}
|
||||
|
||||
static void UserMessageGetMessageName(ScriptContext& scriptContext)
|
||||
{
|
||||
auto message = scriptContext.GetArgument<UserMessage*>(0);
|
||||
|
||||
if (message == nullptr || message->GetSerializableMessage() == nullptr)
|
||||
{
|
||||
scriptContext.ThrowNativeError("Invalid message");
|
||||
return;
|
||||
}
|
||||
|
||||
scriptContext.SetResult(message->GetSerializableMessage()->GetUnscopedName());
|
||||
}
|
||||
|
||||
static void UserMessageGetMessageTypeName(ScriptContext& scriptContext)
|
||||
{
|
||||
auto message = scriptContext.GetArgument<UserMessage*>(0);
|
||||
|
||||
if (message == nullptr || message->GetProtobufMessage() == nullptr)
|
||||
{
|
||||
scriptContext.ThrowNativeError("Invalid message");
|
||||
return;
|
||||
}
|
||||
|
||||
scriptContext.SetResult(message->GetProtobufMessage()->GetTypeName().c_str());
|
||||
}
|
||||
|
||||
REGISTER_NATIVES(usermessages, {
|
||||
ScriptEngine::RegisterNativeHandler("HOOK_USERMESSAGE", HookUserMessage);
|
||||
ScriptEngine::RegisterNativeHandler("UNHOOK_USERMESSAGE", UnhookUserMessage);
|
||||
ScriptEngine::RegisterNativeHandler("PB_HASFIELD", PbHasField);
|
||||
ScriptEngine::RegisterNativeHandler("PB_READINT", PbReadInt);
|
||||
ScriptEngine::RegisterNativeHandler("PB_READINT64", PbReadInt64);
|
||||
ScriptEngine::RegisterNativeHandler("PB_READFLOAT", PbReadFloat);
|
||||
ScriptEngine::RegisterNativeHandler("PB_READBOOL", PbReadBool);
|
||||
ScriptEngine::RegisterNativeHandler("PB_READSTRING", PbReadString);
|
||||
ScriptEngine::RegisterNativeHandler("PB_GETREPEATEDFIELDCOUNT", PbGetRepeatedFieldCount);
|
||||
ScriptEngine::RegisterNativeHandler("PB_SETINT", PbSetInt);
|
||||
ScriptEngine::RegisterNativeHandler("PB_SETINT64", PbSetInt64);
|
||||
ScriptEngine::RegisterNativeHandler("PB_SETFLOAT", PbSetFloat);
|
||||
ScriptEngine::RegisterNativeHandler("PB_SETBOOL", PbSetBool);
|
||||
ScriptEngine::RegisterNativeHandler("PB_SETSTRING", PbSetString);
|
||||
ScriptEngine::RegisterNativeHandler("PB_ADDINT", PbAddInt);
|
||||
ScriptEngine::RegisterNativeHandler("PB_ADDINT64", PbAddInt64);
|
||||
ScriptEngine::RegisterNativeHandler("PB_ADDFLOAT", PbAddFloat);
|
||||
ScriptEngine::RegisterNativeHandler("PB_ADDBOOL", PbAddBool);
|
||||
ScriptEngine::RegisterNativeHandler("PB_ADDSTRING", PbAddString);
|
||||
ScriptEngine::RegisterNativeHandler("PB_REMOVEREPEATEDFIELDVALUE", PbRemoveRepeatedFieldValue);
|
||||
// ScriptEngine::RegisterNativeHandler("PB_READMESSAGE", PbReadMessage);
|
||||
// ScriptEngine::RegisterNativeHandler("PB_READREPEATEDMESSAGE", PbReadRepeatedMessage);
|
||||
// ScriptEngine::RegisterNativeHandler("PB_ADDMESSAGE", PbAddMessage);
|
||||
ScriptEngine::RegisterNativeHandler("PB_GETDEBUGSTRING", PbGetDebugString);
|
||||
ScriptEngine::RegisterNativeHandler("USERMESSAGE_FINDMESSAGEIDBYNAME", UserMessageFindMessageIdByName);
|
||||
ScriptEngine::RegisterNativeHandler("USERMESSAGE_CREATE", UserMessageCreate);
|
||||
ScriptEngine::RegisterNativeHandler("USERMESSAGE_CREATEBYID", UserMessageCreateById);
|
||||
ScriptEngine::RegisterNativeHandler("USERMESSAGE_GETRECIPIENTS", UserMessageGetRecipients);
|
||||
ScriptEngine::RegisterNativeHandler("USERMESSAGE_SETRECIPIENTS", UserMessageSetRecipients);
|
||||
ScriptEngine::RegisterNativeHandler("USERMESSAGE_SEND", UserMessageSend);
|
||||
ScriptEngine::RegisterNativeHandler("USERMESSAGE_DELETE", UserMessageDelete);
|
||||
ScriptEngine::RegisterNativeHandler("USERMESSAGE_GETID", UserMessageGetMessageId);
|
||||
ScriptEngine::RegisterNativeHandler("USERMESSAGE_GETNAME", UserMessageGetMessageName);
|
||||
ScriptEngine::RegisterNativeHandler("USERMESSAGE_GETTYPE", UserMessageGetMessageTypeName);
|
||||
})
|
||||
} // namespace counterstrikesharp
|
||||
34
src/scripting/natives/natives_usermessages.yaml
Normal file
34
src/scripting/natives/natives_usermessages.yaml
Normal file
@@ -0,0 +1,34 @@
|
||||
HOOK_USERMESSAGE: messageId:int, callback:func, mode:HookMode -> void
|
||||
UNHOOK_USERMESSAGE: messageId:int, callback:func, mode:HookMode -> void
|
||||
PB_HASFIELD: message:UserMessage, name:string -> bool
|
||||
PB_READINT: message:UserMessage, name:string, index:int -> int
|
||||
PB_READINT64: message:UserMessage, name:string, index:int -> long
|
||||
PB_READFLOAT: message:UserMessage, name:string, index:int -> float
|
||||
PB_READBOOL: message:UserMessage, name:string, index:int -> bool
|
||||
PB_READSTRING: message:UserMessage, name:string, index:int -> string
|
||||
PB_GETREPEATEDFIELDCOUNT: message:UserMessage, name:string -> int
|
||||
PB_SETINT: message:UserMessage, name:string, value:int, index:int -> void
|
||||
PB_SETINT64: message:UserMessage, name:string, value:long, index:int -> void
|
||||
PB_SETFLOAT: message:UserMessage, name:string, value:float, index:int -> void
|
||||
PB_SETBOOL: message:UserMessage, name:string, value:bool, index:int -> void
|
||||
PB_SETSTRING: message:UserMessage, name:string, value:string, index:int -> void
|
||||
PB_ADDINT: message:UserMessage, name:string, value:int -> void
|
||||
PB_ADDINT64: message:UserMessage, name:string, value:int64 -> void
|
||||
PB_ADDFLOAT: message:UserMessage, name:string, value:float -> void
|
||||
PB_ADDBOOL: message:UserMessage, name:string, value:bool -> void
|
||||
PB_ADDSTRING: message:UserMessage, name:string, value:string -> void
|
||||
PB_REMOVEREPEATEDFIELDVALUE: message:UserMessage, name:string, index:int -> void
|
||||
#PB_READMESSAGE: message:UserMessage, name:string -> UserMessage
|
||||
#PB_READREPEATEDMESSAGE: message:UserMessage, name:string, index:int -> UserMessage
|
||||
#PB_ADDMESSAGE: message:UserMessage, name:string -> UserMessage
|
||||
PB_GETDEBUGSTRING: message:UserMessage -> string
|
||||
USERMESSAGE_GETRECIPIENTS: message:UserMessage -> uint64
|
||||
USERMESSAGE_SETRECIPIENTS: message:UserMessage, recipients:uint64 -> void
|
||||
USERMESSAGE_FINDMESSAGEIDBYNAME: name:string -> int
|
||||
USERMESSAGE_CREATE: name:string -> pointer
|
||||
USERMESSAGE_CREATEBYID: id:int -> pointer
|
||||
USERMESSAGE_SEND: message:UserMessage -> void
|
||||
USERMESSAGE_DELETE: message:UserMessage -> void
|
||||
USERMESSAGE_GETID: message:UserMessage -> int
|
||||
USERMESSAGE_GETNAME: message:UserMessage -> string
|
||||
USERMESSAGE_GETTYPE: message:UserMessage -> string
|
||||
@@ -21,55 +21,62 @@
|
||||
|
||||
namespace counterstrikesharp {
|
||||
|
||||
CREATE_GETTER_FUNCTION(Vector, float, Length, Vector *, obj->Length());
|
||||
CREATE_GETTER_FUNCTION(Vector, float, Length2D, Vector *, obj->Length2D());
|
||||
CREATE_GETTER_FUNCTION(Vector, float, LengthSqr, Vector *, obj->LengthSqr());
|
||||
CREATE_GETTER_FUNCTION(Vector, float, Length2DSqr, Vector *, obj->Length2DSqr());
|
||||
CREATE_GETTER_FUNCTION(Vector, float, IsZero, Vector *, obj->IsZero());
|
||||
CREATE_GETTER_FUNCTION(Vector, float, Length, Vector*, obj->Length());
|
||||
CREATE_GETTER_FUNCTION(Vector, float, Length2D, Vector*, obj->Length2D());
|
||||
CREATE_GETTER_FUNCTION(Vector, float, LengthSqr, Vector*, obj->LengthSqr());
|
||||
CREATE_GETTER_FUNCTION(Vector, float, Length2DSqr, Vector*, obj->Length2DSqr());
|
||||
CREATE_GETTER_FUNCTION(Vector, bool, IsZero, Vector*, obj->IsZero());
|
||||
|
||||
CREATE_GETTER_FUNCTION(Vector, float, X, Vector *, obj->x);
|
||||
CREATE_GETTER_FUNCTION(Vector, float, Y, Vector *, obj->y);
|
||||
CREATE_GETTER_FUNCTION(Vector, float, Z, Vector *, obj->z);
|
||||
CREATE_GETTER_FUNCTION(Vector, float, X, Vector*, obj->x);
|
||||
CREATE_GETTER_FUNCTION(Vector, float, Y, Vector*, obj->y);
|
||||
CREATE_GETTER_FUNCTION(Vector, float, Z, Vector*, obj->z);
|
||||
|
||||
CREATE_SETTER_FUNCTION(Vector, float, X, Vector *, obj->x = value);
|
||||
CREATE_SETTER_FUNCTION(Vector, float, Y, Vector *, obj->y = value);
|
||||
CREATE_SETTER_FUNCTION(Vector, float, Z, Vector *, obj->z = value);
|
||||
CREATE_SETTER_FUNCTION(Vector, float, X, Vector*, obj->x = value);
|
||||
CREATE_SETTER_FUNCTION(Vector, float, Y, Vector*, obj->y = value);
|
||||
CREATE_SETTER_FUNCTION(Vector, float, Z, Vector*, obj->z = value);
|
||||
|
||||
// TODO: These need to be cleared out somehow
|
||||
std::vector<Vector *> managed_vectors;
|
||||
std::vector<Vector*> managed_vectors;
|
||||
|
||||
Vector *VectorNew(ScriptContext &script_context) {
|
||||
Vector* VectorNew(ScriptContext& script_context)
|
||||
{
|
||||
auto vec = new Vector();
|
||||
managed_vectors.push_back(vec);
|
||||
return vec;
|
||||
}
|
||||
|
||||
// TODO: These need to be cleared out somehow
|
||||
std::vector<QAngle *> managed_angles;
|
||||
std::vector<QAngle*> managed_angles;
|
||||
|
||||
QAngle *AngleNew(ScriptContext &script_context) {
|
||||
QAngle* AngleNew(ScriptContext& script_context)
|
||||
{
|
||||
auto ang = new QAngle();
|
||||
managed_angles.push_back(ang);
|
||||
return ang;
|
||||
}
|
||||
|
||||
void NativeVectorAngles(ScriptContext &script_context) {
|
||||
auto vec = script_context.GetArgument<Vector *>(0);
|
||||
auto pseudoUpVector = script_context.GetArgument<Vector *>(1);
|
||||
auto outAngle = script_context.GetArgument<QAngle *>(2);
|
||||
void NativeVectorAngles(ScriptContext& script_context)
|
||||
{
|
||||
auto vec = script_context.GetArgument<Vector*>(0);
|
||||
auto pseudoUpVector = script_context.GetArgument<Vector*>(1);
|
||||
auto outAngle = script_context.GetArgument<QAngle*>(2);
|
||||
|
||||
if (!pseudoUpVector) {
|
||||
if (!pseudoUpVector)
|
||||
{
|
||||
VectorAngles(*vec, *outAngle);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
VectorAngles(*vec, *pseudoUpVector, *outAngle);
|
||||
}
|
||||
}
|
||||
|
||||
void NativeAngleVectors(ScriptContext &script_context) {
|
||||
auto vec = script_context.GetArgument<QAngle *>(0);
|
||||
auto fwd = script_context.GetArgument<Vector *>(1);
|
||||
auto right = script_context.GetArgument<Vector *>(2);
|
||||
auto up = script_context.GetArgument<Vector *>(3);
|
||||
void NativeAngleVectors(ScriptContext& script_context)
|
||||
{
|
||||
auto vec = script_context.GetArgument<QAngle*>(0);
|
||||
auto fwd = script_context.GetArgument<Vector*>(1);
|
||||
auto right = script_context.GetArgument<Vector*>(2);
|
||||
auto up = script_context.GetArgument<Vector*>(3);
|
||||
|
||||
AngleVectors(*vec, fwd, right, up);
|
||||
}
|
||||
@@ -92,6 +99,6 @@ REGISTER_NATIVES(vector, {
|
||||
ScriptEngine::RegisterNativeHandler("VECTOR_LENGTH_2D", VectorGetLength2D);
|
||||
ScriptEngine::RegisterNativeHandler("VECTOR_LENGTH_SQR", VectorGetLengthSqr);
|
||||
ScriptEngine::RegisterNativeHandler("VECTOR_LENGTH_2D_SQR", VectorGetLength2DSqr);
|
||||
ScriptEngine::RegisterNativeHandler("VECTOR_IS_ZERO", VectorGetLengthSqr);
|
||||
ScriptEngine::RegisterNativeHandler("VECTOR_IS_ZERO", VectorGetIsZero);
|
||||
})
|
||||
} // namespace counterstrikesharp
|
||||
} // namespace counterstrikesharp
|
||||
|
||||
@@ -54,6 +54,8 @@ public class Mapping
|
||||
return "void";
|
||||
case "uint64":
|
||||
return "ulong";
|
||||
case "long":
|
||||
return "long";
|
||||
case "func":
|
||||
case "callback":
|
||||
return "InputArgument";
|
||||
@@ -69,6 +71,10 @@ public class Mapping
|
||||
return "DataType";
|
||||
case "CommandCallingContext":
|
||||
return "CommandCallingContext";
|
||||
case "UserMessage":
|
||||
return "UserMessage";
|
||||
case "RecipientFilter":
|
||||
return "RecipientFilter";
|
||||
case "any":
|
||||
return "T";
|
||||
}
|
||||
|
||||
@@ -91,7 +91,9 @@ public partial class Generators
|
||||
var result = $@"
|
||||
using System;
|
||||
using CounterStrikeSharp.API.Modules.Memory;
|
||||
using CounterStrikeSharp.API.Modules.UserMessages;
|
||||
using CounterStrikeSharp.API.Modules.Commands;
|
||||
using CounterStrikeSharp.API.Modules.Utils;
|
||||
|
||||
namespace CounterStrikeSharp.API.Core
|
||||
{{
|
||||
@@ -106,4 +108,4 @@ namespace CounterStrikeSharp.API.Core
|
||||
File.WriteAllText(Path.Join(Helpers.GetRootDirectory(), "managed/CounterStrikeSharp.API/Core/API.cs"),
|
||||
result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user