initial release of almost completely automatic event rewarder
This commit is contained in:
parent
398ec27aa5
commit
f0951685d4
38
event_rewards/php/bootstrap_user_upgrade.php
Normal file
38
event_rewards/php/bootstrap_user_upgrade.php
Normal file
@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
$startTime = microtime(true);
|
||||
|
||||
// we have to figure out XenForo path
|
||||
// dirname(dirname(__FILE__)) should work most of the time
|
||||
// as it was the way XenForo's index.php does
|
||||
// however, sometimes it may not work...
|
||||
// so we have to be creative
|
||||
$parentOfDirOfFile = dirname(dirname(__FILE__));
|
||||
$scriptFilename = (isset($_SERVER['SCRIPT_FILENAME']) ? $_SERVER['SCRIPT_FILENAME'] : '');
|
||||
$pathToCheck = '/src/XF.php';
|
||||
$fileDir = false;
|
||||
if (file_exists($parentOfDirOfFile . $pathToCheck))
|
||||
{
|
||||
$fileDir = $parentOfDirOfFile;
|
||||
}
|
||||
if ($fileDir === false AND !empty($scriptFilename))
|
||||
{
|
||||
$parentOfDirOfScriptFilename = dirname(dirname($scriptFilename));
|
||||
if (file_exists($parentOfDirOfScriptFilename . $pathToCheck))
|
||||
{
|
||||
$fileDir = $parentOfDirOfScriptFilename;
|
||||
}
|
||||
}
|
||||
if ($fileDir === false)
|
||||
{
|
||||
die('XenForo path could not be figured out...');
|
||||
}
|
||||
|
||||
require ($fileDir . '/src/XF.php');
|
||||
|
||||
XF::start($dir);
|
||||
$app = XF::setupApp('XF\Pub\App');
|
||||
|
||||
// Get Upgrade Repository
|
||||
$app->repository('XF:UserUpgrade');
|
||||
|
156
event_rewards/php/private_user_upgrade_api.php
Normal file
156
event_rewards/php/private_user_upgrade_api.php
Normal file
@ -0,0 +1,156 @@
|
||||
<?php
|
||||
/*
|
||||
Usage
|
||||
Endpoint: https://unloze.com/api/private_user_upgrade_api.php
|
||||
Query strings:
|
||||
api_key - Required: Should be set to the secret API key
|
||||
provider - Optional: Should be set to the wanted provider. Defaults to a default provider.
|
||||
<id query> - Required: A respective ID query string should be set. E.g. the Steam provider requires a "steam_id" query string.
|
||||
days_amount - Required: The amount of days to give as userUpgrade. this is related to event rewards.
|
||||
*/
|
||||
|
||||
// --- CONFIG START ---
|
||||
// API key for authorization
|
||||
$api_key = "k9Mk2lA3mF9Sk0FoaD";
|
||||
|
||||
// Provider name with given query string
|
||||
$provider_config = array(
|
||||
"th_cap_steam" => "steam_id",
|
||||
"minecraft" => "uuid"
|
||||
);
|
||||
|
||||
// For backwards compatibility
|
||||
$default_provider = "th_cap_steam";
|
||||
|
||||
// Responses
|
||||
$response_error_apikey = 'API KEY INVALID';
|
||||
$response_no_account_associated = 'NOACCOUNT';
|
||||
$response_group_none = 'NOGROUP';
|
||||
$response_error_id = 'MISSING ID';
|
||||
|
||||
|
||||
|
||||
// --- CONFIG END ---
|
||||
|
||||
// TODO: Use single query string for ID?
|
||||
|
||||
// Prints the reason and exits.
|
||||
function quitWithReason($reason, $status_code = 200){
|
||||
|
||||
http_response_code($status_code);
|
||||
echo $reason;
|
||||
die;
|
||||
}
|
||||
|
||||
function debug_to_console($data) {
|
||||
$output = $data;
|
||||
if (is_array($output))
|
||||
$output = implode(',', $output);
|
||||
echo "<script>console.log('Debug Objects: " . $output . "' );</script>";
|
||||
}
|
||||
|
||||
|
||||
// Check the API key
|
||||
if(!isset($_GET['api_key']) || $_GET['api_key'] !== $api_key){
|
||||
quitWithReason($response_error_apikey, 401);
|
||||
}
|
||||
|
||||
|
||||
// Load XenForo stuffs
|
||||
require ('bootstrap_user_upgrade.php');
|
||||
|
||||
// Fetch provider from query string. If none is found, use the default provider.
|
||||
$provider = isset($_GET['provider']) ? $_GET['provider'] : $default_provider;
|
||||
|
||||
|
||||
$days_reward = $_GET['days_reward'];
|
||||
|
||||
//debug_to_console("$days_reward"); //will always be set.
|
||||
|
||||
// Check if the given provider has been configured
|
||||
if(!array_key_exists($provider, $provider_config)){
|
||||
quitWithReason($response_error_provider, 404);
|
||||
}
|
||||
|
||||
// Check if the ID is set.
|
||||
if(!isset($_GET[$provider_config[$provider]])){
|
||||
quitWithReason($response_error_id, 404);
|
||||
}
|
||||
|
||||
|
||||
// Fetch the respective ID query string.
|
||||
$provider_key = $_GET[$provider_config[$provider]];
|
||||
|
||||
// Use finder for external accounts
|
||||
$connectedAccountFinder = \XF::finder('XF:UserConnectedAccount');
|
||||
|
||||
// Search for external accounts with the given provider and ID
|
||||
$stAssoc = $connectedAccountFinder->where('provider', $provider)->where('provider_key', $provider_key)->fetchOne();
|
||||
|
||||
// If no account is associated to the steam account return NOACCOUNT
|
||||
if(empty($stAssoc)){
|
||||
quitWithReason($response_no_account_associated, 500);
|
||||
}
|
||||
|
||||
// Load XenForo model for users
|
||||
$userFinder = \XF::finder('XF:User');
|
||||
|
||||
// Fetch the user from the external account entry
|
||||
$user = $userFinder->where('user_id', $stAssoc->user_id)->fetchOne();
|
||||
|
||||
// (This should not happen) If no user is found, assign no group.
|
||||
if(empty($user)){
|
||||
// Push error to XenForo error log.
|
||||
trigger_error("External account association exists for non-existing user ID (" . $stAssoc->user_id . ").");
|
||||
quitWithReason($response_group_none, 500);
|
||||
}
|
||||
|
||||
//debug_to_console("$stAssoc->user_id");
|
||||
|
||||
// Get UserUpgrade Information
|
||||
$upgradeFinder = \XF::finder('XF:UserUpgrade');
|
||||
$userUpgrade = $upgradeFinder->where('user_upgrade_id', 1)->fetchOne(); //its 1 because it should not matter which userupgrade we pick. its actually 1 month vip.
|
||||
|
||||
//debug_to_console("$user");
|
||||
|
||||
//before upgrading the user lets confirm if they already have a running vip duration. if they do we update it instead of creating a new one.
|
||||
// Get Active Upgrade Information
|
||||
$userUpgradeActiveFinder = \XF::Finder('XF:UserUpgradeActive');
|
||||
$activeUserUpgrades = $userUpgradeActiveFinder->where('user_id', $stAssoc->user_id)->fetchOne();
|
||||
//debug_to_console("$activeUserUpgrades");
|
||||
|
||||
if (isset($activeUserUpgrades))
|
||||
{
|
||||
debug_to_console("has user upgrade");
|
||||
$userUpgrade_new = $activeUserUpgrades->Upgrade;
|
||||
$expireDate = $activeUserUpgrades->end_date;
|
||||
//debug_to_console("$userUpgrade_new");
|
||||
//debug_to_console("$expireDate");
|
||||
|
||||
$dateObject = date_create_from_format('U', $expireDate);
|
||||
$intervalString = "P{$days_reward}D";
|
||||
$interval = new DateInterval($intervalString);
|
||||
$dateObject->add($interval);
|
||||
$newTimestamp = $dateObject->getTimestamp();
|
||||
|
||||
//debug_to_console("$newTimestamp");
|
||||
$upgradeService = $app->service('XF:User\Upgrade', $userUpgrade_new, $user);
|
||||
$upgradeService->setEndDate($newTimestamp);
|
||||
$upgradeService->ignoreUnpurchasable(true);
|
||||
$upgradeService->upgrade();
|
||||
}
|
||||
else
|
||||
{
|
||||
debug_to_console("no user upgrade so far");
|
||||
// add days to current date
|
||||
$date = strtotime("+$days_reward day");
|
||||
|
||||
// Upgrade User
|
||||
$upgradeService = $app->service('XF:User\Upgrade', $userUpgrade, $user);
|
||||
$upgradeService->setEndDate($date);
|
||||
$upgradeService->ignoreUnpurchasable(true);
|
||||
$upgradeService->upgrade();
|
||||
}
|
||||
|
||||
quitWithReason(" end ", 200);
|
||||
|
7
event_rewards/python/README.md
Normal file
7
event_rewards/python/README.md
Normal file
@ -0,0 +1,7 @@
|
||||
this is meant to automatically give event rewards through some xenforo API call
|
||||
|
||||
mysql-connector-python
|
||||
requests
|
||||
|
||||
|
||||
|
71
event_rewards/python/main.py
Normal file
71
event_rewards/python/main.py
Normal file
@ -0,0 +1,71 @@
|
||||
#!/home/nonroot/handle_event_rewards/venv/bin/python3
|
||||
from settings import (get_connection_events, api_key)
|
||||
import requests
|
||||
|
||||
unloze_user_upgrade_api = f"https://unloze.com/api/private_user_upgrade_api.php?api_key={api_key}&steam_id="
|
||||
|
||||
def get_all_pending_event_rewards():
|
||||
with get_connection_events() as conn:
|
||||
with conn.cursor(buffered=True) as cur:
|
||||
sql_statement = """
|
||||
select steamid, event_reward_days
|
||||
from unloze_event.rewards
|
||||
where is_processed is false
|
||||
"""
|
||||
cur.execute(sql_statement)
|
||||
res = cur.fetchall()
|
||||
conn.close()
|
||||
return res
|
||||
|
||||
def update_is_procssed():
|
||||
with get_connection_events() as conn:
|
||||
with conn.cursor(buffered=True) as cur:
|
||||
sql_statement = """
|
||||
update unloze_event.rewards set is_processed = true where is_processed is false
|
||||
"""
|
||||
cur.execute(sql_statement)
|
||||
conn.commit() #pretty gay how contextmanager cant commit and close itself like in psycopg2
|
||||
conn.close()
|
||||
|
||||
def steamid_to_commid(steamid):
|
||||
steamid64ident = 76561197960265728
|
||||
sid_split = steamid.split(':')
|
||||
commid = int(sid_split[2]) * 2
|
||||
if sid_split[1] == '1':
|
||||
commid += 1
|
||||
commid += steamid64ident
|
||||
return commid
|
||||
|
||||
def update_steam_id_has_no_forum_account_with_steam(steamid):
|
||||
with get_connection_events() as conn:
|
||||
with conn.cursor(buffered=True) as cur:
|
||||
sql_statement = """
|
||||
update unloze_event.rewards
|
||||
set has_no_forum_account_with_associated_steam = true
|
||||
where has_no_forum_account_with_associated_steam is not true
|
||||
and steamid = %s
|
||||
"""
|
||||
cur.execute(sql_statement, [steamid])
|
||||
conn.commit() #pretty gay how contextmanager cant commit and close itself like in psycopg2
|
||||
conn.close()
|
||||
|
||||
def reward_vip_to_event_winners(res):
|
||||
for result in res:
|
||||
steamid = result[0]
|
||||
days_rewarded = result[1]
|
||||
steam_community_id = steamid_to_commid(steamid)
|
||||
|
||||
r = requests.get(f"{unloze_user_upgrade_api}{steam_community_id}&days_reward={days_rewarded}")
|
||||
#print("r.url: ", r.url)
|
||||
if r.content.decode('utf8').startswith("NOACCOUNT"): #not registed with associated steam account
|
||||
update_steam_id_has_no_forum_account_with_steam(steamid)
|
||||
|
||||
def main():
|
||||
res = get_all_pending_event_rewards()
|
||||
#send request to xenforo for giving vip time
|
||||
reward_vip_to_event_winners(res)
|
||||
update_is_procssed() #we took them all out so we just update all rows where is_processed is false.
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
118
event_rewards/scripting/trackwinners.sp
Normal file
118
event_rewards/scripting/trackwinners.sp
Normal file
@ -0,0 +1,118 @@
|
||||
#pragma semicolon 1
|
||||
#define PLUGIN_AUTHOR "jenz"
|
||||
#define PLUGIN_VERSION "1.0"
|
||||
#include <sourcemod>
|
||||
#include <cstrike>
|
||||
|
||||
Database g_hDatabase;
|
||||
int g_ireward_days = 0;
|
||||
char g_cadmin_sid[64];
|
||||
char g_cadmin_escaped_name[256];
|
||||
|
||||
public Plugin myinfo =
|
||||
{
|
||||
name = "unloze track event winners",
|
||||
author = PLUGIN_AUTHOR,
|
||||
description = "during events it tracks through the admin command if people won the event",
|
||||
version = PLUGIN_VERSION,
|
||||
url = "www.unloze.com"
|
||||
};
|
||||
|
||||
|
||||
public void OnPluginStart()
|
||||
{
|
||||
if (!g_hDatabase)
|
||||
{
|
||||
Database.Connect(SQL_OnDatabaseConnect, "Event_notifier");
|
||||
}
|
||||
RegAdminCmd("sm_trackwinners", Cmd_trackwinners, ADMFLAG_GENERIC, "Use this each round where humans can win VIP. the alive humans on that round will have their steam IDs stored. Also specify a day as the number.");
|
||||
HookEvent("round_start", Event_RoundStart);
|
||||
HookEvent("round_end", Event_RoundEnd);
|
||||
}
|
||||
|
||||
public void Event_RoundStart(Handle event, const char[] name, bool dontBroadcast)
|
||||
{
|
||||
g_ireward_days = 0;
|
||||
Format(g_cadmin_sid, sizeof(g_cadmin_sid), "");
|
||||
Format(g_cadmin_escaped_name, sizeof(g_cadmin_escaped_name), "");
|
||||
}
|
||||
|
||||
public void Event_RoundEnd(Handle event, const char[] name, bool dontBroadcast)
|
||||
{
|
||||
int winner_team = GetEventInt(event, "winner");
|
||||
if (winner_team == 3 && g_ireward_days > 0) //ct won the round and are supposed to get vip for it.
|
||||
{
|
||||
char current_map[128];
|
||||
GetCurrentMap(current_map, sizeof(current_map));
|
||||
for (int i = 1; i <= MaxClients; i++)
|
||||
{
|
||||
if (IsValidClient(i) && !IsFakeClient(i) && IsPlayerAlive(i) && GetClientTeam(i) == CS_TEAM_CT)
|
||||
{
|
||||
write_reward_entry(i, current_map);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void write_reward_entry(int client, char[] event_map)
|
||||
{
|
||||
char sQuery[512];
|
||||
char sName[MAX_NAME_LENGTH];
|
||||
GetClientName(client, sName, sizeof(sName));
|
||||
int size2 = 2 * strlen(sName) + 1;
|
||||
char[] sEscapedName = new char[size2 + 1];
|
||||
g_hDatabase.Escape(sName, sEscapedName, size2 + 1);
|
||||
|
||||
char SID[64];
|
||||
GetClientAuthId(client, AuthId_Steam2, SID, sizeof(SID));
|
||||
Format(sQuery, sizeof(sQuery), "INSERT INTO `rewards` (`steamid`, `username`, `event_map`, `event_reward_days`, `admin_created_reward_steamid`, `admin_created_reward_name`) VALUES ('%s', '%s', '%s', '%i', '%s', '%s')", SID, sEscapedName, event_map, g_ireward_days, g_cadmin_sid, g_cadmin_escaped_name);
|
||||
g_hDatabase.Query(DummyCallback, sQuery, DBPrio_Normal);
|
||||
PrintToChat(client, "Your %i days VIP were stored for winning this round. They will be awarded in the next 2-3 hours if you have a forum account.", g_ireward_days);
|
||||
}
|
||||
|
||||
public void DummyCallback(Handle hOwner, Handle hChild, const char[] err, any data)
|
||||
{
|
||||
if (hOwner == null || hChild == null)
|
||||
LogError("Query error. (%s)", err);
|
||||
}
|
||||
|
||||
public Action Cmd_trackwinners(int client, int args)
|
||||
{
|
||||
if (!IsValidClient(client))
|
||||
return Plugin_Handled;
|
||||
if (args != 1)
|
||||
{
|
||||
ReplyToCommand(client, "[SM] sm_trackwinners <amount of days>");
|
||||
return Plugin_Handled;
|
||||
}
|
||||
char sDays[65];
|
||||
GetCmdArg(1, sDays, sizeof(sDays));
|
||||
g_ireward_days = StringToInt(sDays);
|
||||
|
||||
GetClientAuthId(client, AuthId_Steam2, g_cadmin_sid, sizeof(g_cadmin_sid));
|
||||
|
||||
char sName[MAX_NAME_LENGTH];
|
||||
GetClientName(client, sName, sizeof(sName));
|
||||
int size2 = 2 * strlen(sName) + 1;
|
||||
g_hDatabase.Escape(sName, g_cadmin_escaped_name, size2 + 1);
|
||||
|
||||
PrintToChatAll("Admin %N set a VIP reward of %i days for winning this round", client, g_ireward_days);
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
public void SQL_OnDatabaseConnect(Database db, const char[] error, any data)
|
||||
{
|
||||
if(!db || strlen(error))
|
||||
{
|
||||
LogError("Database error: %s", error);
|
||||
return;
|
||||
}
|
||||
g_hDatabase = db;
|
||||
}
|
||||
|
||||
stock bool IsValidClient(int client)
|
||||
{
|
||||
if (client > 0 && client <= MaxClients && IsClientConnected(client) && IsClientInGame(client))
|
||||
return true;
|
||||
return false;
|
||||
}
|
13
event_rewards/sql/rewards_table.sql
Normal file
13
event_rewards/sql/rewards_table.sql
Normal file
@ -0,0 +1,13 @@
|
||||
CREATE TABLE unloze_event.rewards (
|
||||
`rowid` int auto_increment NOT NULL,
|
||||
`steamid` varchar(64) not NULL,
|
||||
`username` varchar(256) DEFAULT NULL,
|
||||
`event_map` varchar(512) DEFAULT NULL,
|
||||
`event_reward_days` int not NULL,
|
||||
`created_on` datetime DEFAULT current_timestamp(),
|
||||
`admin_created_reward_steamid` varchar(64) not NULL,
|
||||
`admin_created_reward_name` varchar(64) not NULL,
|
||||
`is_processed` bool default false,
|
||||
`has_no_forum_account_with_associated_steam` bool default null,
|
||||
PRIMARY KEY (`rowid`)
|
||||
)
|
10
event_rewards/systemctl/handle_event_rewards.service
Normal file
10
event_rewards/systemctl/handle_event_rewards.service
Normal file
@ -0,0 +1,10 @@
|
||||
[Unit]
|
||||
Description=runs python script to check if there are missing event rewards to hand out.
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=nonroot
|
||||
Environment=PYTHONUNBUFFERED=1
|
||||
Environment=PATH=/home/nonroot/handle_event_rewards/venv/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games:/snap/bin
|
||||
WorkingDirectory=/home/nonroot/handle_event_rewards
|
||||
ExecStart=/home/nonroot/handle_event_rewards/main.py
|
9
event_rewards/systemctl/handle_event_rewards.timer
Normal file
9
event_rewards/systemctl/handle_event_rewards.timer
Normal file
@ -0,0 +1,9 @@
|
||||
[Unit]
|
||||
Description=Checks every 3 hours if there are event rewards to hand out.
|
||||
|
||||
[Timer]
|
||||
OnCalendar=0/3:00:00
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
|
Loading…
Reference in New Issue
Block a user