diff options
Diffstat (limited to 'src/server.cpp')
| -rw-r--r-- | src/server.cpp | 35 |
1 files changed, 32 insertions, 3 deletions
diff --git a/src/server.cpp b/src/server.cpp index 1313f00..af0a8ff 100644 --- a/src/server.cpp +++ b/src/server.cpp | |||
| @@ -58,6 +58,8 @@ static int g_srv_mapname = -1; | |||
| 58 | static int g_srv_armor = -1; | 58 | static int g_srv_armor = -1; |
| 59 | static int g_srv_detonate = -1; | 59 | static int g_srv_detonate = -1; |
| 60 | static int g_srv_grenade_radius = -1; | 60 | static int g_srv_grenade_radius = -1; |
| 61 | static int g_srv_ammo = -1; | ||
| 62 | static int g_srv_myweapons = -1; | ||
| 61 | static bool g_srv_ready = false; | 63 | static bool g_srv_ready = false; |
| 62 | static bool g_srv_checked = false; | 64 | static bool g_srv_checked = false; |
| 63 | 65 | ||
| @@ -97,7 +99,7 @@ static int datamap_offset(const char *name, int want_type, int min_off = 0x40, | |||
| 97 | continue; | 99 | continue; |
| 98 | if (foff < min_off || foff > max_off) | 100 | if (foff < min_off || foff > max_off) |
| 99 | continue; | 101 | continue; |
| 100 | if (fsize < 1 || fsize > 128) | 102 | if (fsize < 1 || fsize > 512) |
| 101 | continue; | 103 | continue; |
| 102 | // DEFINE_KEYFIELD entries have an external name ("health"); plain | 104 | // DEFINE_KEYFIELD entries have an external name ("health"); plain |
| 103 | // DEFINE_FIELD entries have none. Either way it must be in server.so. | 105 | // DEFINE_FIELD entries have none. Either way it must be in server.so. |
| @@ -160,17 +162,22 @@ bool resolve_server_netvars() { | |||
| 160 | // CBaseGrenade fuse / blast radius (m_flDetonateTime is not networked). | 162 | // CBaseGrenade fuse / blast radius (m_flDetonateTime is not networked). |
| 161 | g_srv_detonate = datamap_offset("m_flDetonateTime", FIELD_TIME); | 163 | g_srv_detonate = datamap_offset("m_flDetonateTime", FIELD_TIME); |
| 162 | g_srv_grenade_radius = datamap_offset("m_DmgRadius", FIELD_FLOAT); | 164 | g_srv_grenade_radius = datamap_offset("m_DmgRadius", FIELD_FLOAT); |
| 165 | // CBaseCombatCharacter arrays: ammo counts and the weapon handle list. | ||
| 166 | g_srv_ammo = datamap_offset("m_iAmmo", FIELD_INTEGER, 0x40, 0x4000); | ||
| 167 | g_srv_myweapons = datamap_offset("m_hMyWeapons", FIELD_EHANDLE); | ||
| 163 | g_srv_ready = g_srv_health > 0; | 168 | g_srv_ready = g_srv_health > 0; |
| 164 | if (g_srv_ready) { | 169 | if (g_srv_ready) { |
| 165 | logf("server datamap (%s): health=%d maxhealth=%d lifeste=%d " | 170 | logf("server datamap (%s): health=%d maxhealth=%d lifeste=%d " |
| 166 | "modelindex=%d absvel=%d vel=%d activeweapon=%d relationship=%d " | 171 | "modelindex=%d absvel=%d vel=%d activeweapon=%d relationship=%d " |
| 167 | "followtarget=%d spawnflags=%d hacked=%d npcstate=%d " | 172 | "followtarget=%d spawnflags=%d hacked=%d npcstate=%d " |
| 168 | "takedamage=%d mapname=%d armor=%d detonate=%d dmgradius=%d", | 173 | "takedamage=%d mapname=%d armor=%d detonate=%d dmgradius=%d " |
| 174 | "ammo=%d myweapons=%d", | ||
| 169 | g_server.path.c_str(), g_srv_health, g_srv_maxhealth, g_srv_lifestate, | 175 | g_server.path.c_str(), g_srv_health, g_srv_maxhealth, g_srv_lifestate, |
| 170 | g_srv_modelindex, g_srv_absvelocity, g_srv_velocity, | 176 | g_srv_modelindex, g_srv_absvelocity, g_srv_velocity, |
| 171 | g_srv_activeweapon, g_srv_relationship, g_srv_followtarget, | 177 | g_srv_activeweapon, g_srv_relationship, g_srv_followtarget, |
| 172 | g_srv_spawnflags, g_srv_hacked, g_srv_npcstate, g_srv_takedamage, | 178 | g_srv_spawnflags, g_srv_hacked, g_srv_npcstate, g_srv_takedamage, |
| 173 | g_srv_mapname, g_srv_armor, g_srv_detonate, g_srv_grenade_radius); | 179 | g_srv_mapname, g_srv_armor, g_srv_detonate, g_srv_grenade_radius, |
| 180 | g_srv_ammo, g_srv_myweapons); | ||
| 174 | fail_logged = false; | 181 | fail_logged = false; |
| 175 | } else if (!fail_logged) { | 182 | } else if (!fail_logged) { |
| 176 | fail_logged = true; | 183 | fail_logged = true; |
| @@ -475,6 +482,28 @@ float server_grenade_radius(int idx) { | |||
| 475 | return *(float *)((uintptr_t)base + g_srv_grenade_radius); | 482 | return *(float *)((uintptr_t)base + g_srv_grenade_radius); |
| 476 | } | 483 | } |
| 477 | 484 | ||
| 485 | // Server-side CBaseCombatCharacter::m_iAmmo array (reserve ammo). | ||
| 486 | int server_player_ammo(int idx, int type) { | ||
| 487 | if (!g_srv_ready || g_srv_ammo < 0 || type < 0 || type >= 32) | ||
| 488 | return -1; | ||
| 489 | void *base = nullptr; | ||
| 490 | server_entity_health(idx, nullptr, nullptr, &base); | ||
| 491 | if (!base) | ||
| 492 | return -1; | ||
| 493 | return *(int *)((uintptr_t)base + g_srv_ammo + type * 4); | ||
| 494 | } | ||
| 495 | |||
| 496 | // Server-side m_hMyWeapons[48] handle for one inventory slot (0 if empty). | ||
| 497 | uint32_t server_player_weapon(int idx, int slot) { | ||
| 498 | if (!g_srv_ready || g_srv_myweapons < 0 || slot < 0 || slot >= 48) | ||
| 499 | return 0; | ||
| 500 | void *base = nullptr; | ||
| 501 | server_entity_health(idx, nullptr, nullptr, &base); | ||
| 502 | if (!base) | ||
| 503 | return 0; | ||
| 504 | return *(uint32_t *)((uintptr_t)base + g_srv_myweapons + slot * 4); | ||
| 505 | } | ||
| 506 | |||
| 478 | // Entity index of the player's active weapon from the authoritative server | 507 | // Entity index of the player's active weapon from the authoritative server |
| 479 | // entity. Used as a fallback if the client m_hActiveWeapon netvar is missing. | 508 | // entity. Used as a fallback if the client m_hActiveWeapon netvar is missing. |
| 480 | int server_active_weapon(int idx) { | 509 | int server_active_weapon(int idx) { |
