Senior Member
|
01-23-2019
, 14:26
Re: TF2 Stats - Beginning questions
|
#3
|
Thx Whai this is what i needed ;)
Ok so I think i reached my first step.
There I my assumptions: - Sample statisticks that insert to DB player kills, deaths and suicides
To achieve it my plugin create 3 tables: - servers structure: |id|ip|port|created_at|updated_at|
- players structure: |id|steam_id|name|created_at|updated_at|
- players_stats structure: |id|player_id|server_id|kills|deaths|suicides |created_at|updated_at|
Here is full code:
PHP Code:
#define DEBUG
#define PLUGIN_NAME "TF2 Pro Stats"
#define PLUGIN_AUTHOR "Szkalownik"
#define PLUGIN_DESCRIPTION ""
#define PLUGIN_VERSION "1.0"
#define PLUGIN_URL ""
#pragma semicolon 1
#include <sourcemod>
#include <sdktools>
#include <SteamWorks>
char dbconfig[] = "tf2_pro_stats";
Database databaseHandler;
enum struct PlayerData {
int id[11];
char steamId[32];
char name[256];
}
PlayerData playersData[MAXPLAYERS+1];
enum struct ServerData {
int id[11];
char ip[64];
char port[16];
}
ServerData serverData;
public Plugin:myinfo =
{
name = PLUGIN_NAME,
author = PLUGIN_AUTHOR,
description = PLUGIN_DESCRIPTION,
version = PLUGIN_VERSION,
url = PLUGIN_URL
};
public OnPluginStart()
{
connectToDatabase();
createDatabaseTables();
setServer();
HookEvents();
}
public void connectToDatabase()
{
if(!SQL_CheckConfig(dbconfig)) {
LogError("Could not find %s database configuration.", dbconfig);
return;
}
decl String:error[256];
databaseHandler = SQL_Connect(dbconfig, true, error, sizeof(error));
if (databaseHandler == INVALID_HANDLE) {
LogError("Could not connect to database. Error: %s", error);
}
}
public void createDatabaseTables()
{
if(databaseHandler == INVALID_HANDLE) {
return;
}
char queries[3][] =
{
"CREATE TABLE IF NOT EXISTS `servers` (`id` int(11) NOT NULL AUTO_INCREMENT, `ip` int(11) NOT NULL, `port` int(11) NOT NULL, `updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=latin1",
"CREATE TABLE IF NOT EXISTS `players` (`id` int(11) NOT NULL AUTO_INCREMENT, `steam_id` varchar(255) NOT NULL, `name` varchar(255) NOT NULL, `updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=latin1",
"CREATE TABLE IF NOT EXISTS `players_stats` (`id` int(11) NOT NULL AUTO_INCREMENT,`player_id` int(11) NOT NULL,`server_id` int(11) NOT NULL,`kills` int(11) NOT NULL DEFAULT '0',`deaths` int(11) NOT NULL DEFAULT '0',`suicides` int(11) NOT NULL DEFAULT '0',`updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=latin1;"
};
decl String:error[256];
for (int i = 0; i < 3; i++) {
if (!SQL_FastQuery(databaseHandler, queries[i])) {
SQL_GetError(databaseHandler, error, sizeof(error));
LogError("Database query: %s error: %s",queries[i], error);
}
}
}
public void setServer()
{
decl String:query[1500];
char serverIp[64];
char serverPort[10];
int ipaddr[4];
SteamWorks_GetPublicIP(ipaddr);
Format(serverIp, sizeof(serverIp), "%d.%d.%d.%d",ipaddr[0], ipaddr[1], ipaddr[2], ipaddr[3]);
strcopy(serverData.ip, sizeof(serverData.ip), serverIp);
GetConVarString(FindConVar("hostport"), serverPort, sizeof(serverPort));
strcopy(serverData.port, sizeof(serverData.port), serverPort);
Format(query, sizeof(query), "SELECT id FROM servers WHERE ip = '%s' AND port='%s' LIMIT 1;", serverIp, serverPort);
SQL_TQuery(databaseHandler, SQLServerCallback, query);
}
public void SQLServerCallback(Handle owner, Handle hndl, const char[] error, any data)
{
if (!StrEqual("", error)) {
LogMessage("SQL Error: %s", error);
return;
}
if(SQL_FetchRow(hndl)) {
serverData.id = SQL_FetchInt(hndl, 0);
return;
}
decl String:query[1500];
Format(query, sizeof(query), "INSERT INTO servers (ip, port) VALUES ( '%s', '%s');", serverData.ip, serverData.port);
SQL_TQuery(databaseHandler, SQLAddServerCallback, query);
}
public void SQLAddServerCallback(Handle owner, Handle hndl, const char[] error, any data)
{
if (!StrEqual("", error)) {
LogMessage("SQL Error: %s", error);
return;
}
serverData.id = SQL_GetInsertId(owner);
}
public void OnClientAuthorized(int client)
{
if(databaseHandler == INVALID_HANDLE) {
return;
}
char clientSteamId[32];
char clientName[256];
decl String:query[1500];
GetClientAuthId(client, AuthId_Steam2, clientSteamId, sizeof(clientSteamId));
GetClientName(client, clientName, sizeof(clientName));
strcopy(playersData[client].steamId, sizeof(playersData[].steamId), clientSteamId);
strcopy(playersData[client].name, sizeof(playersData[].name), clientName);
if(StrEqual(clientSteamId, "BOT", true)) {
Format(query, sizeof(query), "SELECT id,name FROM players WHERE steam_id = '%s' and name='%s' LIMIT 1;", clientSteamId, clientName);
}else{
Format(query, sizeof(query), "SELECT id,name FROM players WHERE steam_id = '%s' LIMIT 1;", clientSteamId);
}
SQL_TQuery(databaseHandler, SQLPlayerCallback, query, GetClientSerial(client));
}
public void SQLPlayerCallback(Handle owner, Handle hndl, const char[] error, any data)
{
int client = GetClientFromSerial(data);
if (client == 0) {
return;
}
decl String:query[1500];
char clientName[256];
if (!StrEqual("", error)) {
LogMessage("SQL Error: %s", error);
return;
}
if(SQL_FetchRow(hndl)) {
playersData[client].id = SQL_FetchInt(hndl,0);
SQL_FetchString(hndl,1,clientName,256);
if(!StrEqual(playersData[client].name, clientName, true)) {
Format(query, sizeof(query), "UPDATE players SET name='%s' WHERE id=%d);", playersData[client].name, playersData[client].id);
SQL_TQuery(databaseHandler, SQLUpdateCallback, query);
}
return;
}
Format(query, sizeof(query), "INSERT INTO players (steam_id, name) VALUES ( '%s', '%s');", playersData[client].steamId, playersData[client].name);
SQL_TQuery(databaseHandler, SQLAddPlayerCallback, query, data);
}
public void SQLAddPlayerCallback(Handle owner, Handle hndl, const char[] error, any data)
{
int client = GetClientFromSerial(data);
if (client == 0) {
return;
}
if (!StrEqual("", error)) {
LogMessage("SQL Error: %s", error);
return;
}
playersData[client].id = SQL_GetInsertId(owner);
}
public void HookEvents()
{
HookEvent("player_death", Event_PlayerDeath);
}
public Event_PlayerDeath(Handle:event, const String:name[], bool:dontBroadcast)
{
if(databaseHandler == INVALID_HANDLE) {
return;
}
new attackerId = GetClientOfUserId(GetEventInt(event, "attacker"));
new victimId = GetClientOfUserId(GetEventInt(event, "userid"));
if(attackerId == 0 || victimId == 0) {
return;
}
if(victimId == attackerId) {
addPlayerStat(attackerId, "suicide");
return;
}
addPlayerStat(attackerId, "kill");
addPlayerStat(victimId, "death");
}
public void addPlayerStat(int client, String:type[])
{
decl String:query[1500];
Format(query, sizeof(query), "SELECT player_id, server_id, kills, deaths, suicides FROM players_stats WHERE player_id = %d AND server_id=%d LIMIT 1;", playersData[client].id, serverData.id);
if(StrEqual(type, "suicide")){
SQL_TQuery(databaseHandler, SQLAddPlayerSuicideCallback, query, GetClientSerial(client));
return;
}
if(StrEqual(type, "kill")){
SQL_TQuery(databaseHandler, SQLAddPlayerKillCallback, query, GetClientSerial(client));
return;
}
if(StrEqual(type, "death")){
SQL_TQuery(databaseHandler, SQLAddPlayerDeathCallback, query, GetClientSerial(client));
return;
}
}
public void SQLAddPlayerSuicideCallback(Handle owner, Handle hndl, const char[] error, any data)
{
int client = GetClientFromSerial(data);
if (client == 0) {
return;
}
decl String:query[1500];
if (!StrEqual("", error)) {
LogMessage("SQL Error: %s", error);
return;
}
if(SQL_FetchRow(hndl)) {
Format(query, sizeof(query), "UPDATE players_stats SET suicides = suicides+1 WHERE player_id=%d AND server_id=%d;", SQL_FetchInt(hndl,0), SQL_FetchInt(hndl,1));
SQL_TQuery(databaseHandler, SQLUpdateCallback, query);
return;
}
Format(query, sizeof(query), "INSERT INTO players_stats (player_id, server_id, kills, deaths, suicides) VALUES (%d, %d, %d, %d, %d);", playersData[client].id, serverData.id, 0, 0, 1);
SQL_TQuery(databaseHandler, SQLInsertCallback, query);
}
public void SQLAddPlayerKillCallback(Handle owner, Handle hndl, const char[] error, any data)
{
int client = GetClientFromSerial(data);
if (client == 0) {
return;
}
decl String:query[1500];
if (!StrEqual("", error)) {
LogMessage("SQL Error: %s", error);
return;
}
if(SQL_FetchRow(hndl)) {
Format(query, sizeof(query), "UPDATE players_stats SET kills = kills+1 WHERE player_id=%d AND server_id=%d;", SQL_FetchInt(hndl,0), SQL_FetchInt(hndl,1));
SQL_TQuery(databaseHandler, SQLUpdateCallback, query);
return;
}
Format(query, sizeof(query), "INSERT INTO players_stats (player_id, server_id, kills, deaths, suicides) VALUES (%d, %d, %d, %d, %d);", playersData[client].id, serverData.id, 1, 0, 0);
SQL_TQuery(databaseHandler, SQLInsertCallback, query);
}
public void SQLAddPlayerDeathCallback(Handle owner, Handle hndl, const char[] error, any data)
{
int client = GetClientFromSerial(data);
if (client == 0) {
return;
}
decl String:query[1500];
if (!StrEqual("", error)) {
LogMessage("SQL Error: %s", error);
return;
}
if(SQL_FetchRow(hndl)) {
Format(query, sizeof(query), "UPDATE players_stats SET deaths = deaths+1 WHERE player_id=%d AND server_id=%d;", SQL_FetchInt(hndl,0), SQL_FetchInt(hndl,1));
SQL_TQuery(databaseHandler, SQLUpdateCallback, query);
return;
}
Format(query, sizeof(query), "INSERT INTO players_stats (player_id, server_id, kills, deaths, suicides) VALUES (%d, %d, %d, %d, %d);", playersData[client].id, serverData.id, 1, 0, 0);
SQL_TQuery(databaseHandler, SQLInsertCallback, query);
}
public void SQLUpdateCallback(Handle owner, Handle hndl, const char[] error, any data)
{
if (!StrEqual("", error)) {
LogMessage("SQL Error: %s", error);
return;
}
}
public void SQLInsertCallback(Handle owner, Handle hndl, const char[] error, any data)
{
if (!StrEqual("", error)) {
LogMessage("SQL Error: %s", error);
return;
}
}
Can you give me guys some feedback what else should be checked , some bugs etc.
Thi is my first steps in source and i wanna get good practice acknowledge of writing plugins from start
__________________
|
|