fixes and improvements :^)

This commit is contained in:
BotoX 2021-05-10 22:48:48 +02:00
parent cc5c945b4c
commit e2b31d00ac
5 changed files with 146 additions and 8 deletions

View File

@ -83,7 +83,7 @@ namespace GameEvents
} break; } break;
case GameEvents::EventValueType::Byte: case GameEvents::EventValueType::Byte:
{ {
std::cout << d.second.u8Value << "\n"; std::cout << unsigned(d.second.u8Value) << "\n";
} break; } break;
case GameEvents::EventValueType::Bool: case GameEvents::EventValueType::Bool:
{ {

View File

@ -14,6 +14,7 @@ Logic::Logic(SourceGameContext* context):
{"header", {}}, {"header", {}},
{"serverinfo", {}}, {"serverinfo", {}},
{"players", {}}, {"players", {}},
{"events", {}},
{"chat", {}}, {"chat", {}},
{"voice", {}} {"voice", {}}
}); });
@ -117,13 +118,27 @@ void Logic::OnClientConnected(int client)
player = json({ player = json({
{"names", {}}, {"names", {}},
{"sprays", {}}, {"sprays", {}},
{"disconnect_reasons", {}},
{"playtime", 0}, {"playtime", 0},
{"voicetime", 0.0f} {"voicetime", 0.0f},
{"kills", 0},
{"deaths", 0},
{"chats", 0}
}); });
} }
clients[client].connected = curTick; clients[client].connected = curTick;
clients[client].kills = 0;
clients[client].deaths = 0;
clients[client].chats = 0;
clients[client].voiceTime = 0.0f;
json player_connect = {
{"event", "player_connect"},
{"tick", curTick},
{"steamid", info.guid},
{"name", info.name}
};
data["events"] += player_connect;
OnClientSettingsChanged(client); OnClientSettingsChanged(client);
} }
@ -146,7 +161,28 @@ void Logic::OnClientDisconnected(int client, const char* reason)
voicetime += player["voicetime"].get<float>(); voicetime += player["voicetime"].get<float>();
player["voicetime"] = voicetime; player["voicetime"] = voicetime;
player["disconnect_reasons"] += reason; // cumulative kills
int kills = clients[client].kills;
kills += player["kills"].get<int>();
player["kills"] = kills;
// cumulative deaths
int deaths = clients[client].deaths;
deaths += player["deaths"].get<int>();
player["deaths"] = deaths;
// cumulative chats
int chats = clients[client].chats;
chats += player["chats"].get<int>();
player["chats"] = chats;
json player_disconnect = {
{"event", "player_disconnect"},
{"tick", curTick},
{"steamid", info.guid},
{"reason", reason}
};
data["events"] += player_disconnect;
clients[client].connected = -1; clients[client].connected = -1;
} }
@ -173,11 +209,40 @@ void Logic::OnClientSettingsChanged(int client)
} }
} }
void Logic::OnClientDeath(int client, int attacker, bool headshot, const char* weapon)
{
assert(client >= 0 && client < MAX_PLAYERS);
assert(clients[client].connected != -1);
const char *victim_guid = context->players[client].info.guid;
const char *attacker_guid = "";
clients[client].deaths++;
if(attacker >= 0 && attacker < MAX_PLAYERS)
{
clients[attacker].kills++;
attacker_guid = context->players[attacker].info.guid;
}
json player_death = {
{"tick", curTick},
{"event", "player_death"},
{"victim", victim_guid},
{"attacker", attacker_guid},
{"headshot", headshot},
{"weapon", weapon}
};
data["events"] += player_death;
}
void Logic::OnClientChat(int client, bool bWantsToChat, const char* msgName, const char* msgSender, const char* msgText) void Logic::OnClientChat(int client, bool bWantsToChat, const char* msgName, const char* msgSender, const char* msgText)
{ {
assert(client >= 0 && client < MAX_PLAYERS); assert(client >= 0 && client < MAX_PLAYERS);
assert(clients[client].connected != -1); assert(clients[client].connected != -1);
clients[client].chats++;
const auto& info = context->players[client].info; const auto& info = context->players[client].info;
json chat = { json chat = {
{"tick", curTick}, {"tick", curTick},
@ -193,7 +258,8 @@ void Logic::OnClientChat(int client, bool bWantsToChat, const char* msgName, con
void Logic::OnClientVoiceChat(int client, float length) void Logic::OnClientVoiceChat(int client, float length)
{ {
assert(client >= 0 && client < MAX_PLAYERS); assert(client >= 0 && client < MAX_PLAYERS);
assert(clients[client].connected != -1); if (clients[client].connected == -1)
return;
clients[client].voiceTime += length; clients[client].voiceTime += length;
voiceTotalTime += length; voiceTotalTime += length;
@ -220,3 +286,27 @@ void Logic::OnVoiceCodec(const char* codec, int quality, int sampleRate)
{"sampleRate", sampleRate} {"sampleRate", sampleRate}
}); });
} }
void Logic::OnRoundStart(int timelimit)
{
json round_start = {
{"event", "round_start"},
{"tick", curTick},
{"timelimit", timelimit},
};
data["events"] += round_start;
}
void Logic::OnRoundEnd(const char *message, int reason, int winner)
{
json round_end = {
{"event", "round_end"},
{"tick", curTick},
{"message", message},
{"reason", reason},
{"winner", winner}
};
data["events"] += round_end;
}

View File

@ -22,6 +22,9 @@ struct Logic
struct struct
{ {
int32_t connected = -1; int32_t connected = -1;
int kills = 0;
int deaths = 0;
int chats = 0;
float voiceTime = 0.0f; float voiceTime = 0.0f;
} clients[MAX_PLAYERS]; } clients[MAX_PLAYERS];
@ -29,9 +32,12 @@ struct Logic
void OnClientConnected(int client); void OnClientConnected(int client);
void OnClientDisconnected(int client, const char* reason); void OnClientDisconnected(int client, const char* reason);
void OnClientSettingsChanged(int client); void OnClientSettingsChanged(int client);
void OnClientDeath(int client, int attacker, bool headshot, const char* weapon);
void OnClientChat(int client, bool bWantsToChat, const char* msgName, const char* msgSender, const char* msgText); void OnClientChat(int client, bool bWantsToChat, const char* msgName, const char* msgSender, const char* msgText);
void OnClientVoiceChat(int client, float length); void OnClientVoiceChat(int client, float length);
void OnVoiceCodec(const char* codec, int quality, int sampleRate); void OnVoiceCodec(const char* codec, int quality, int sampleRate);
void OnRoundStart(int timelimit);
void OnRoundEnd(const char *message, int reason, int winner);
int32_t curTick = 0; int32_t curTick = 0;
float voiceTotalTime = 0.0f; float voiceTotalTime = 0.0f;

View File

@ -10,6 +10,7 @@
#include "game/logic.h" #include "game/logic.h"
#include "io/voicewriter/voicedatawriter.h" #include "io/voicewriter/voicedatawriter.h"
#include <iostream> #include <iostream>
#include <limits.h>
#include "netmessages/svc_voiceinit.h" #include "netmessages/svc_voiceinit.h"
#include "netmessages/svc_voicedata.h" #include "netmessages/svc_voicedata.h"
@ -19,6 +20,8 @@ SourceGameContext::SourceGameContext(std::string outputDir, std::string outputDi
outputDirVoice(outputDirVoice) outputDirVoice(outputDirVoice)
{ {
stringTables = new StringTableContainer(this); stringTables = new StringTableContainer(this);
userIdLookUp = new uint8_t[USHRT_MAX+1];
memset(userIdLookUp, 0xFF, USHRT_MAX+1);
} }
SourceGameContext::~SourceGameContext() SourceGameContext::~SourceGameContext()
@ -33,6 +36,8 @@ SourceGameContext::~SourceGameContext()
gameEventList = nullptr; gameEventList = nullptr;
delete stringTables; delete stringTables;
stringTables = nullptr; stringTables = nullptr;
delete userIdLookUp;
userIdLookUp = nullptr;
fclose(outputFp); fclose(outputFp);
} }
@ -130,16 +135,46 @@ void SourceGameContext::OnGameEvent(const char *name, GameEvents::EventDataMap &
if (strcmp(name, "player_disconnect") == 0) if (strcmp(name, "player_disconnect") == 0)
{ {
int userid = data["userid"].i16Value; int userid = data["userid"].i16Value;
for (int client = 0; client < MAX_PLAYERS; client++) int client = userIdLookUp[userid];
// player_disconnect can fire for clients which never connected
// (ESC during mapchange)
if(client != 0xFF)
{ {
auto& p = players[client]; auto& p = players[client];
if (!p.connected || p.info.userID != userid) assert(p.connected && p.info.userID == userid);
continue;
p.connected = false; p.connected = false;
logic->OnClientDisconnected(client, data["reason"].strValue.c_str()); logic->OnClientDisconnected(client, data["reason"].strValue.c_str());
userIdLookUp[userid] = 0xFF;
} }
} }
else if (strcmp(name, "player_death") == 0)
{
int client = userIdLookUp[data["userid"].i16Value];
assert(client >= 0 && client < MAX_PLAYERS);
int attacker = data["attacker"].i16Value;
if(attacker > 0)
{
attacker = userIdLookUp[attacker];
assert(attacker >= 0 && attacker < MAX_PLAYERS);
}
else
attacker = -1;
logic->OnClientDeath(client, attacker, data["headshot"].bValue, data["weapon"].strValue.c_str());
}
else if (strcmp(name, "round_start") == 0)
{
logic->OnRoundStart(data["timelimit"].i32Value);
}
else if (strcmp(name, "round_end") == 0)
{
logic->OnRoundEnd(data["message"].strValue.c_str(), data["reason"].u8Value, data["winner"].u8Value);
}
} }
void SourceGameContext::OnStringtable(StringTable* table) void SourceGameContext::OnStringtable(StringTable* table)
@ -155,16 +190,21 @@ void SourceGameContext::UserInfoChanged(int tableIdx, int entryIdx)
StringTableEntry &entry = stringTables->tables[tableIdx].entries[entryIdx]; StringTableEntry &entry = stringTables->tables[tableIdx].entries[entryIdx];
int client = std::stoi(entry.string); int client = std::stoi(entry.string);
assert(client >= 0 && client < MAX_PLAYERS);
player_info_t *info = (player_info_t *)entry.data.data(); player_info_t *info = (player_info_t *)entry.data.data();
if (entry.data.size() != sizeof(player_info_t)) if (entry.data.size() != sizeof(player_info_t))
{ {
if(players[client].connected)
userIdLookUp[players[client].info.userID] = 0xFF;
memset(&players[client].info, 0, sizeof(player_info_t)); memset(&players[client].info, 0, sizeof(player_info_t));
players[client].connected = false; players[client].connected = false;
return; return;
} }
memcpy(&players[client].info, info, sizeof(player_info_t)); memcpy(&players[client].info, info, sizeof(player_info_t));
userIdLookUp[info->userID] = client;
if (!players[client].connected) if (!players[client].connected)
logic->OnClientConnected(client); logic->OnClientConnected(client);

View File

@ -108,4 +108,6 @@ struct SourceGameContext
bool connected = false; bool connected = false;
player_info_t info; player_info_t info;
} players[MAX_PLAYERS]; } players[MAX_PLAYERS];
uint8_t *userIdLookUp = nullptr;
}; };