This patch contains 3 enhancements for clientset:
- Provides GetArenaOverride and GetPlayerOverride in the interface
- The checksum returned by GetChecksum is based on the last settings packet sent instead of the current arena settings + override values. Aka no security warnings if you decide to set overrides and delay calling SendClientSettings()
- Provides the global config settings clientset:DetectConfigChange. This disables sending settings packets after a ?quickfix.
Diff bases on clientset.c r1117:
#!C
38,40d37
<
< unsigned char lastSettingsPacket_hasData;
< struct ClientSettings lastSettingsPacket;
313d309
<
350,395d345
< int get_override(overridedata *od, override_key_t key, i32 *val)
< {
< int len = (key >> 16) & 0xffffu;
< int offset = key & 0xffffu;
<
< *val = 0;
<
< /* don't override type byte */
< if (offset < 8)
< return 0;
<
< if (len <= 32 && ((offset & 31) + len) <= 32)
< {
< /* easier case: a bunch of bits that fit within a word boundary */
< int wordoff = offset >> 5;
< int bitoff = offset & 31;
< u32 mask = (0xffffffffu >> (32 - len)) << bitoff;
<
< if ((((u32*)od->mask)[wordoff] & mask) == mask)
< {
< *val = ((u32*)od->bits)[wordoff];
< *val &= mask;
< *val = *val >> bitoff;
<
<
< return 1;
< }
< else
< {
< return 0;
< }
<
< }
< #if 0
< else if (len <= 32 && ((offset & 31) + len) <= 64)
< {
< #error "Not implemented"
< }
< #endif
< else
< {
< lm->Log(L_WARN, "<clientset> illegal override key: %x", key);
< return 0;
< }
< }
<
433,461d382
< local int GetArenaOverride(Arena *arena, override_key_t key, i32 *value)
< {
< int ret;
< adata *ad = P_ARENA_DATA(arena, adkey);
< LOCK();
< ret = get_override(&ad->od, key, value);
< UNLOCK();
< return ret;
<
< }
<
< local int GetPlayerOverride(Player *p, override_key_t key, i32 *value)
< {
< int ret;
< pdata *data = PPDATA(p, pdkey);
< LOCK();
< if (data->od)
< {
< ret = get_override(data->od, key, value);
< }
< else
< {
< *value = 0;
< ret = 0;
< }
< UNLOCK();
< return ret;
< }
<
464d384
< /* call with lock held */
495a416
> struct ClientSettings tosend;
497,500c418,420
< do_mask(&data->lastSettingsPacket, &ad->cs, &ad->od, data->od);
< data->lastSettingsPacket_hasData = 1;
< if (data->lastSettingsPacket.bit_set.type == S2C_SETTINGS)
< net->SendToOne(p, (byte*)&data->lastSettingsPacket, sizeof(data->lastSettingsPacket), NET_RELIABLE);
---
> do_mask(&tosend, &ad->cs, &ad->od, data->od);
> if (tosend.bit_set.type == S2C_SETTINGS)
> net->SendToOne(p, (byte*)&tosend, sizeof(tosend), NET_RELIABLE);
512c432
< else if (action == AA_CONFCHANGED && cfg->GetInt(GLOBAL, "clientset", "DetectConfigChange", 1))
---
> else if (action == AA_CONFCHANGED)
565c485,486
< u32 *bits = (u32*)&data->lastSettingsPacket;
---
> struct ClientSettings tochecksum;
> u32 *bits = (u32*)&tochecksum;
573,577c494
< if (!data->lastSettingsPacket_hasData)
< {
< do_mask(&data->lastSettingsPacket, &ad->cs, &ad->od, data->od);
< data->lastSettingsPacket_hasData = 1;
< }
---
> do_mask(&tochecksum, &ad->cs, &ad->od, data->od);
clientset.h:
#!C
/* dist: public */
#ifndef __CLIENTSET_H
#define __CLIENTSET_H
/* Iclientset
*
* this is the interface to the module that manages the client-side
* settings. it loads them from disk when the arena is loaded and when
* the config files change change. arenaman calls SendClientSettings as
* part of the arena response procedure.
*/
typedef u32 override_key_t;
#define I_CLIENTSET "clientset-6"
typedef struct Iclientset
{
INTERFACE_HEAD_DECL
void (*SendClientSettings)(Player *p);
u32 (*GetChecksum)(Player *p, u32 key);
int (*GetRandomPrize)(Arena *arena);
override_key_t (*GetOverrideKey)(const char *section, const char *key);
/* zero return means failure */
void (*ArenaOverride)(Arena *arena, override_key_t key, i32 val);
void (*ArenaUnoverride)(Arena *arena, override_key_t key);
int (*GetArenaOverride)(Arena *arena, override_key_t key, i32 *value); // returns 1 if set
void (*PlayerOverride)(Player *p, override_key_t key, i32 val);
void (*PlayerUnoverride)(Player *p, override_key_t key);
int (*GetPlayerOverride)(Player *p, override_key_t key, i32 *value);
} Iclientset;
#endif