#include <amxmisc>
#include <engine>
#include <fakemeta>
#include <geoip>
#define PLUGIN "Mutasd az időt!"
#define VERSION "1.1"
#define AUTHOR "Doondook, RaZ_HU"
#define SetUserBot(%1) gIsBot |= 1<<(%1 & (MAX_PLAYERS - 1))
#define ClearUserBot(%1) gIsBot &= ~(1<<(%1 & (MAX_PLAYERS - 1)))
#define IsUserBot(%1) gIsBot & 1<<(%1 & (MAX_PLAYERS - 1))
#define SetUserConnected(%1) gIsConnected |= 1<<(%1 & (MAX_PLAYERS - 1))
#define ClearUserConnected(%1) gIsConnected &= ~(1<<(%1 & (MAX_PLAYERS - 1)))
#define IsUserConnected(%1) gIsConnected & 1<<(%1 & (MAX_PLAYERS - 1))
//#define ReplaceTimer // Felül írja-e vagy sem a köridő jelzőt
#if AMXX_VERSION_NUM < 183
#define MAX_PLAYERS 32
#endif
new gIsBot, gIsConnected
#if defined ReplaceTimer
new gMsgRoundTime
#else
new gMsgHudSync
#endif
new gMaxPlayers
new gUserUTC[MAX_PLAYERS + 1]
new Trie:gTrieUTC
new gTimer, gIterations
public plugin_init() {
register_plugin(PLUGIN, VERSION, AUTHOR)
#if AMXX_VERSION_NUM < 183
gMaxPlayers = get_maxplayers()
#else
gMaxPlayers = MaxClients
#endif
#if defined ReplaceTimer
gMsgRoundTime = get_user_msgid("RoundTime")
#endif
// Create timezones trie map of UTC offsets.
getUTCbase()
// Get server's UTC offset.
// If server's timezone is not recognized by <geoip> databases,
// you can set it manually, +/- integer in minutes:
// - for UTC 3:00
// gUserUTC[0] = 180
// - for UTC -1:30
// gUserUTC[0] = -90
// Comment the line below if you set it manually.
gUserUTC[0] = getUserUTC(0)
// Get server's current time without UTC offset.
new szTime[9], szHours[3], szMinutes[3], szSeconds[3]
get_time("%H %M %S", szTime, charsmax(szTime))
parse(szTime, szHours, charsmax(szHours), szMinutes, charsmax(szMinutes), szSeconds, charsmax(szSeconds))
// Using timer counter instead of calling get_time().
gTimer = str_to_num(szHours) * 60 + str_to_num(szMinutes) - gUserUTC[0]
// Amount of the timer entity iterations to increment minutes.
// Double up current seconds, because the timer entity thinks every 0.5 seconds.
gIterations = str_to_num(szSeconds) * 2
// Create entity for using as permanent task.
new szEntity = create_entity("info_target")
if(szEntity) {
register_think("Timer", "showTime")
set_pev(szEntity, pev_classname, "Timer")
set_pev(szEntity, pev_nextthink, get_gametime() + 0.01)
} else {
set_fail_state("Cannot create timer entity.")
}
#if !defined ReplaceTimer
// Create sync object for hudmessage
gMsgHudSync = CreateHudSyncObj()
#endif
}
public showTime(szEntity) {
new szTime
for(new id = 1; id <= gMaxPlayers; id++) {
if(~IsUserConnected(id) || IsUserBot(id)) {
continue
}
szTime = gTimer + gUserUTC[id]
// Check for midnight limit
if(szTime >= 1440) {
szTime -= 1440
} else if (szTime < 0) {
szTime += 1440
}
#if defined ReplaceTimer
// Replace round time with server's UTC 0 time + user's UTC offset = user's time in his timezone.
message_begin(MSG_ONE_UNRELIABLE, gMsgRoundTime, _, id)
write_short(szTime + 1) // +1 because of round timer implementation (60 will be 0:59)
message_end()
#else
// HUD üzenet kiíratása
displayTime(id, szTime)
#endif
}
// Count iterations of the entity think
gIterations++
// Increment timer every 120 iterations (1 minute)
if(gIterations == 120) {
gTimer++
gIterations = 0
}
// Set counter to zero at midnight
if(gTimer >= 1440) {
gTimer = 0
}
// Lets make it infinite
set_pev(szEntity, pev_nextthink, get_gametime() + 0.5)
}
#if !defined ReplaceTimer
public displayTime(id, theTime) {
new iMinutes = theTime % 60
new iHours = floatround( ( theTime - iMinutes ) / 60.0 )
new iTimeText[8]
// Szépítés
if(iMinutes < 10)
formatex(iTimeText, charsmax(iTimeText), "%d: 0%d", iHours, iMinutes)
else
formatex(iTimeText, charsmax(iTimeText), "%d: %d", iHours, iMinutes)
// Az idő kijelzése a HUD-ra
set_hudmessage(30, 30, 30, 0.488, 0.94, 0, 0.3, 1.0, 0.0, 0.0, -1)
ShowSyncHudMsg(id, gMsgHudSync, iTimeText )
}
#endif
getUserUTC(id) {
// Get user's timezone by IP.
new szTimezone[64], szIP[20]
get_user_ip(id, szIP, charsmax(szIP), 1)
// Helyi szerver esetén használjon egyénileg megadott időzónát
// Példákhoz lásd a GeoTimezones.txt tartalmát!
if( equal(szIP, "192",3) || equal(szIP, "127", 3) )
{
formatex(szTimezone, charsmax(szTimezone), "Europe/Budapest")
}
else
{
get_user_ip(id, szIP, charsmax(szIP), 1)
geoip_timezone(szIP, szTimezone, charsmax(szTimezone))
}
// Check for determined timezone in trie map
if(TrieKeyExists(gTrieUTC, szTimezone)) {
// Get UTC offset by user's timezone
new szUTC
TrieGetCell(gTrieUTC, szTimezone, szUTC)
return szUTC
}
return 0
}
getUTCbase() {
// Convert file's information to trie map
gTrieUTC = TrieCreate()
new szPath[128]
get_datadir(szPath, charsmax(szPath))
formatex(szPath, charsmax(szPath), "%s/%s", szPath, "GeoTimezones.txt")
if (!file_exists(szPath)) {
log_amx("Cannot open %s", szPath)
} else {
new szLine[81], szKey[64], szValue[16]
new szFile = fopen(szPath, "r")
while(!feof(szFile)) {
fgets(szFile, szLine, charsmax(szLine))
strtok(szLine, szKey, charsmax(szKey), szValue, charsmax(szValue), '@')
// Convert UTC offset value to seconds and save it in trie map
new szHours[4], szMinutes[3]
strtok(szValue, szHours, charsmax(szHours), szMinutes, charsmax(szMinutes), ':')
TrieSetCell(gTrieUTC, szKey, str_to_num(szHours) * 60 + str_to_num(szMinutes))
}
fclose(szFile)
}
}
public client_putinserver(id) {
SetUserConnected(id)
if(is_user_bot(id) || is_user_hltv(id)) {
SetUserBot(id)
}
else
gUserUTC[id] = getUserUTC(id)
}
#if AMXX_VERSION_NUM < 183
public client_disconnect(id) {
#else
public client_disconnected(id) {
#endif
ClearUserBot(id)
ClearUserConnected(id)
}
public plugin_end() {
TrieDestroy(gTrieUTC)
}