@@ -108,14 +108,45 @@ enum PropFieldType
108
108
{ \
109
109
case type: \
110
110
{ \
111
- if (element > 0 ) \
111
+ if (element != 0 ) \
112
112
{ \
113
113
return pContext->ThrowNativeError (" SendProp %s is not an array. Element %d is invalid." , \
114
114
prop, \
115
115
element); \
116
116
} \
117
117
break ; \
118
118
} \
119
+ case DPT_Array: \
120
+ { \
121
+ int elementCount = pProp->GetNumElements (); \
122
+ int elementStride = pProp->GetElementStride (); \
123
+ if (element < 0 || element >= elementCount) \
124
+ { \
125
+ return pContext->ThrowNativeError (" Element %d is out of bounds (Prop %s has %d elements)." , \
126
+ element, \
127
+ prop, \
128
+ elementCount); \
129
+ } \
130
+ \
131
+ pProp = pProp->GetArrayProp (); \
132
+ if (!pProp) { \
133
+ return pContext->ThrowNativeError (" Error looking up ArrayProp for prop %s" , \
134
+ prop); \
135
+ } \
136
+ \
137
+ if (pProp->GetType () != type) \
138
+ { \
139
+ return pContext->ThrowNativeError (" SendProp %s type is not " type_name " ([%d,%d] != %d)" , \
140
+ prop, \
141
+ pProp->GetType (), \
142
+ pProp->m_nBits , \
143
+ type); \
144
+ } \
145
+ \
146
+ offset += pProp->GetOffset () + (elementStride * element); \
147
+ bit_count = pProp->m_nBits ; \
148
+ break ; \
149
+ } \
119
150
case DPT_DataTable: \
120
151
{ \
121
152
FIND_PROP_SEND_IN_SENDTABLE (info, pProp, element, type, type_name); \
@@ -142,7 +173,7 @@ enum PropFieldType
142
173
} \
143
174
\
144
175
int elementCount = pTable->GetNumProps (); \
145
- if (element >= elementCount) \
176
+ if (element < 0 || element >= elementCount) \
146
177
{ \
147
178
return pContext->ThrowNativeError (" Element %d is out of bounds (Prop %s has %d elements)." , \
148
179
element, \
@@ -507,6 +538,13 @@ static cell_t GameRules_GetPropString(IPluginContext *pContext, const cell_t *pa
507
538
{
508
539
char *prop;
509
540
int offset;
541
+ int bit_count;
542
+
543
+ int element = 0 ;
544
+ if (params[0 ] >= 4 )
545
+ {
546
+ element = params[4 ];
547
+ }
510
548
511
549
void *pGameRules = GameRules ();
512
550
@@ -515,56 +553,43 @@ static cell_t GameRules_GetPropString(IPluginContext *pContext, const cell_t *pa
515
553
516
554
pContext->LocalToString (params[1 ], &prop);
517
555
518
- sm_sendprop_info_t info;
519
- if (!gamehelpers->FindSendPropInfo (g_szGameRulesProxy, prop, &info))
520
- {
521
- return pContext->ThrowNativeError (" Property \" %s\" not found on the gamerules proxy" , prop);
522
- }
523
-
524
- offset = info.actual_offset ;
525
-
526
- if (info.prop ->GetType () != DPT_String)
527
- {
528
- return pContext->ThrowNativeError (" SendProp %s type is not a string (%d != %d)" ,
529
- prop,
530
- info.prop ->GetType (),
531
- DPT_String);
532
- }
556
+ FIND_PROP_SEND (DPT_String, " string" );
533
557
534
- size_t len;
535
558
const char *src;
536
-
537
- src = (char *)((intptr_t )pGameRules + offset);
538
-
539
- pContext->StringToLocalUTF8 (params[2 ], params[3 ], src, &len);
540
-
541
- return len;
542
- }
543
-
544
- // From sm_stringutil
545
- inline int strncopy (char *dest, const char *src, size_t count)
546
- {
547
- if (!count)
559
+ if (pProp->GetProxyFn ())
560
+ {
561
+ DVariant var;
562
+ pProp->GetProxyFn ()(pProp, pGameRules, (const void *)((intptr_t )pGameRules + offset), &var, element, 0 /* TODO */ );
563
+ src = var.m_pString ;
564
+ }
565
+ else
548
566
{
549
- return 0 ;
567
+ src = *( char **)(( uint8_t *)pGameRules + offset) ;
550
568
}
551
569
552
- char *start = dest;
553
- while ((*src) && (--count))
570
+ if (src)
554
571
{
555
- *dest++ = *src++;
572
+ size_t len;
573
+ pContext->StringToLocalUTF8 (params[2 ], params[3 ], src, &len);
574
+ return len;
556
575
}
557
- *dest = ' \0 ' ;
558
576
559
- return (dest - start);
577
+ pContext->StringToLocal (params[2 ], params[3 ], " " );
578
+ return 0 ;
560
579
}
561
- //
562
580
563
581
static cell_t GameRules_SetPropString (IPluginContext *pContext, const cell_t *params)
564
582
{
565
583
char *prop;
566
584
int offset;
567
585
int maxlen;
586
+ int bit_count;
587
+
588
+ int element = 0 ;
589
+ if (params[0 ] >= 4 )
590
+ {
591
+ element = params[4 ];
592
+ }
568
593
569
594
void *pGameRules = GameRules ();
570
595
@@ -577,29 +602,46 @@ static cell_t GameRules_SetPropString(IPluginContext *pContext, const cell_t *pa
577
602
578
603
pContext->LocalToString (params[1 ], &prop);
579
604
580
- sm_sendprop_info_t info;
581
- if (!gamehelpers-> FindSendPropInfo (g_szGameRulesProxy, prop, &info ))
605
+ # if SOURCE_ENGINE == SE_CSGO
606
+ if (!g_SdkTools. CanSetCSGOEntProp ( prop))
582
607
{
583
- return pContext->ThrowNativeError (" Property \" %s \" not found on the gamerules proxy " , prop);
608
+ return pContext->ThrowNativeError (" Cannot set ent prop %s with core.cfg option \" FollowCSGOServerGuidelines \" enabled. " , prop);
584
609
}
585
-
586
- offset = info.actual_offset ;
587
-
588
- if (info.prop ->GetType () != DPT_String)
610
+ #endif
611
+
612
+ FIND_PROP_SEND (DPT_String, " string" );
613
+
614
+ bool bIsStringIndex = false ;
615
+ if (pProp->GetProxyFn ())
589
616
{
590
- return pContext->ThrowNativeError (" SendProp %s type is not a string (%d != %d)" ,
591
- prop,
592
- info.prop ->GetType (),
593
- DPT_String);
617
+ DVariant var;
618
+ pProp->GetProxyFn ()(pProp, pGameRules, (const void *)((intptr_t )pGameRules + offset), &var, element, 0 /* TODO */ );
619
+ if (var.m_pString == ((string_t *)((intptr_t )pGameRules + offset))->ToCStr ())
620
+ {
621
+ bIsStringIndex = true ;
622
+ }
594
623
}
595
624
625
+ // Only used if not string index.
626
+ // TODO: If we're writing to a DPT_Array, we should use the element stride here.
596
627
maxlen = DT_MAX_STRING_BUFFERSIZE;
597
628
598
629
char *src;
599
- char *dest = (char *)((intptr_t )pGameRules + offset);
600
-
630
+ size_t len;
601
631
pContext->LocalToString (params[2 ], &src);
602
- size_t len = strncopy (dest, src, maxlen);
632
+
633
+ if (bIsStringIndex)
634
+ {
635
+ return pContext->ThrowNativeError (" Setting string_t gamerules prop %s not supported yet." , prop);
636
+
637
+ // *(string_t *)((intptr_t)pGameRules + offset) = g_HL2.AllocPooledString(src);
638
+ // len = strlen(src);
639
+ }
640
+ else
641
+ {
642
+ char *dest = (char *)((uint8_t *)pGameRules + offset);
643
+ len = ke::SafeStrcpy (dest, maxlen, src);
644
+ }
603
645
604
646
edict_t *proxyEdict = gamehelpers->EdictOfIndex (gamehelpers->EntityToBCompatRef (pProxy));
605
647
if (proxyEdict != NULL )
0 commit comments