CHECAR DIA E ANO - Woorz - 24/11/2022
Salve familia!
Rapa, a callback não está CHECANDO CORRETAMENTE a DATA, MES, ANO do script.
Exemplo: Setei o DONATER para o player até 01/12/2022 porém quando player conecta ao servidor, na DATA Correta nada acontece. Não funciona. Se ele conecta na data SETADA seria para resetar tudo.
Testei com DATAS ANTERIORES E POSTERIORES a SETADA e também sem resultados.
Código: forward checkvipaut(playerid);
public checkvipaut(playerid)
{
for(new i; i<MAX_PLAYERS; i++) if(IsPlayerConnected(i))
{
if(PlayerData[i][pDoador] != 0)
{
static
date[4];
getdate(date[0], date[1], date[2]);
new Dia = PlayerData[i][pDiaDoacao];
new Mes = PlayerData[i][pMesDoacao];
new Ano = PlayerData[i][pAnoDoacao];
if(date[2] > Dia && date[1] > Mes)
{
SendServerMessage(i, "Seu Donater foi expirado (%d/%d/%d).", Dia, Mes, Ano);
PlayerData[i][pDoador] = 0;
PlayerData[i][pDNamecUs] = 0;
PlayerData[i][pDTrocanUs] = 0;
PlayerData[i][pDiaDoacao] = 0; PlayerData[i][pMesDoacao] = 0; PlayerData[i][pAnoDoacao] = 0;
return 1;
}
}
}
return 1;
}
RE: CHECAR DIA E ANO - Woorz - 24/11/2022
Alguém??
RE: CHECAR DIA E ANO - xbruno1000x - 24/11/2022
Essa função getdate é nativa? creio que não. Quando for assim, envie a função juntamente para analisarmos também.
Partindo do pressuposto que getdate retorna corretamente, a condicional tem um erro. Por exemplo, se você analisa a data 24/11(doação) e 25/01(encerramento) irá notar que o mês 11 é maior que o mês 1.
date[2] maior que 24? Verdadeiro.
date[1] maior que 11? Falso, pois 1 é menor que 11.
Logo a condicional inteira retornaria falsa e o que está ali não seria executado.
Pode ser que esse nem seja o problema do código, mas futuramente vai te gerar um "bug do milênio". Eu recomendo que pegue um daqueles sistemas de vip que usam a função gettime() e tente adaptar para o seu sistema, será mais fácil.
RE: CHECAR DIA E ANO - Woorz - 29/11/2022
(24/11/2022 19:02)xbruno1000x Escreveu: Essa função getdate é nativa? creio que não. Quando for assim, envie a função juntamente para analisarmos também.
Partindo do pressuposto que getdate retorna corretamente, a condicional tem um erro. Por exemplo, se você analisa a data 24/11(doação) e 25/01(encerramento) irá notar que o mês 11 é maior que o mês 1.
date[2] maior que 24? Verdadeiro.
date[1] maior que 11? Falso, pois 1 é menor que 11.
Logo a condicional inteira retornaria falsa e o que está ali não seria executado.
Pode ser que esse nem seja o problema do código, mas futuramente vai te gerar um "bug do milênio". Eu recomendo que pegue um daqueles sistemas de vip que usam a função gettime() e tente adaptar para o seu sistema, será mais fácil.
https://open.mp/docs/scripting/functions/getdate - Essa no caso eu uso para checar a data atual, dia, mes, ano.
Sobre a função: gettime() . Ela faz a contagem mesmo com Player estando OFF?
Queria que a contagem você mesmo com ele OFF, saca?
Pensei nessa função também: `VarialvelTempo` = DATE_ADD(NOW(), INTERVAL 1 MONTH)
Na primeira opção que Iniciei, na parte de setar a doacao, ocorre da seguinte maneira:
Código: PlayerData[userid][pDiaDoacao] = dia; PlayerData[userid][pMesDoacao] = mes; PlayerData[userid][pAnoDoacao] = ano;
RE: CHECAR DIA E ANO - Carlos Victor - 29/11/2022
"Sobre a função: gettime() . Ela faz a contagem mesmo com Player estando OFF?"
R: Sim e não, não sei como explico isso, mas basicamente a função gettime retorna o timestamp, ou seja o atual segundo que estamos desde 01/01/1970, que é mais ou menos 1669744360 (14:53:20 29/11/2022) atualmente, ou seja, a variável vai só armazenar esses segundos todos, vou dar um exemplo:
Código: enum PlayerInfo
{
pName[MAX_PLAYER_NAME],
pDonation
};
new PlayerData[MAX_PLAYERS][PlayerInfo];
Supondo que o jogador ganhou 30 dias de VIP, sei lá só um exeplo...
CMD:darvip(playerid, params[])
{
//...
PlayerData[id][pDonation] = gettime() + (days * 86400); // Como o gettime retorna segundos, temos que trabalhar em segundos, eu multiplico os dias de VIP dele por 86400 que é o equivalente a 1 dia em segundos, então sei lá se eu der 30 dias de VIP, vai ser 30 * 86400 = 2592000
// ^^ Ai, basicamente vai ser gettime() + 2592000; que vai ficar armazenado na variável, sabemos que daqui a 2592000 segundos, o VIP dele irá se expirar
return 1;
}
Para uma verificação é simples, faz assim:
if((PlayerData[playerid][pDonation] - gettime()) <= 0)
{
//Caso os 2592000 segundos tenham passado, vai negativar, menor que zero por conta da regra da subtração, o maior número primeiro e depois o menor, enfim...
} else {
SendClientMessage(playerid, -1, "* Você possui %s de VIP.", ConvertDate(PlayerData[playerid][pDonation] - gettime()));
}
stock ConvertTime(number) // Função que "formata" os segundos em datas, ou seja se for +60 segundos, 1 minuto, +3600 segundos = 1 hora e assim vai...
{
new hours, mins, secs, string[64], days = 0;
hours = floatround(number / 3600.0, floatround_floor);
mins = floatround((number / 60.0) - (hours * 60.0), floatround_floor);
secs = floatround((number % 60));
if(hours >= 24)
{
days = floatround((hours/24.0), floatround_floor);
hours = hours % 24;
}
if(days > 0)
format(string, 64, "%d dia(s) e %d hora(s)", days, hours);
else if(hours > 0)
format(string, 64, "%d hora(s) e %d minuto(s)", hours, mins);
else if(mins > 0)
format(string, 64, "%d minuto(s)", mins, secs);
else
format(string, 64, "%d segundo(s)", secs);
return string;
}
Qualquer dúvida, só avisar, mas basicamente é assim que funciona, não sei se expliquei bem.
Eu talvez faria dessa forma:
Código: #include <a_samp>
#include <sscanf2>
#include <zcmd>
#include <foreach>
public OnGameModeInit()
{
SetTimer("OnUpdateAllPlayers", 1000, true);
return 1;
}
forward OnUpdateAllPlayers();
public OnUpdateAllPlayers()
{
foreach(new i : Player)
{
if(PlayerData[i][pDonate] != -1 && (PlayerData[i][pDonate] - gettime()) <= 0)
{
SendClientMessage(playerid, -1, "* Seus privilégios de doação acabou.");
PlayerData[i][pDonate] = -1;
}
}
return 1;
}
CMD:setdonate(playerid, params[])
{
new
id,
days;
if(sscanf(params, "uD(31)", id, days))
return SendClientMessage(playerid, -1, "* /setdonate [id] [days (optional)]");
if(!IsPlayerConnected(id))
return SendClientMessage(playerid, -1, "* Jogador não está conectado.");
new
string[128];
PlayerData[id][pDonate] = gettime() + (days * 86400);
format(string, sizeof(string), "* Você recebeu %s de privilégios de doador.", ConvertTime(PlayerData[playerid][pDonate] - gettime()));
SendClientMessage(id, -1, string);
return 1;
}
stock ConvertTime(number)
{
new hours, mins, secs, string[64], days = 0;
hours = floatround(number / 3600.0, floatround_floor);
mins = floatround((number / 60.0) - (hours * 60.0), floatround_floor);
secs = floatround((number % 60));
if(hours >= 24)
{
days = floatround((hours/24.0), floatround_floor);
hours = hours % 24;
}
if(days > 0)
format(string, 64, "%d dia(s) e %d hora(s)", days, hours);
else if(hours > 0)
format(string, 64, "%d hora(s) e %d minuto(s)", hours, mins);
else if(mins > 0)
format(string, 64, "%d minuto(s)", mins, secs);
else
format(string, 64, "%d segundo(s)", secs);
return string;
}
RE: CHECAR DIA E ANO - Woorz - 29/11/2022
(29/11/2022 15:01)Carlos Victor Escreveu: "Sobre a função: gettime() . Ela faz a contagem mesmo com Player estando OFF?"
R: Sim e não, não sei como explico isso, mas basicamente a função gettime retorna o timestamp, ou seja o atual segundo que estamos desde 01/01/1970, que é mais ou menos 1669744360 (14:53:20 29/11/2022) atualmente, ou seja, a variável vai só armazenar esses segundos todos, vou dar um exemplo:
Código: enum PlayerInfo
{
pName[MAX_PLAYER_NAME],
pDonation
};
new PlayerData[MAX_PLAYERS][PlayerInfo];
Supondo que o jogador ganhou 30 dias de VIP, sei lá só um exeplo...
CMD:darvip(playerid, params[])
{
//...
PlayerData[id][pDonation] = gettime() + (days * 86400); // Como o gettime retorna segundos, temos que trabalhar em segundos, eu multiplico os dias de VIP dele por 86400 que é o equivalente a 1 dia em segundos, então sei lá se eu der 30 dias de VIP, vai ser 30 * 86400 = 2592000
// ^^ Ai, basicamente vai ser gettime() + 2592000; que vai ficar armazenado na variável, sabemos que daqui a 2592000 segundos, o VIP dele irá se expirar
return 1;
}
Para uma verificação é simples, faz assim:
if((PlayerData[playerid][pDonation] - gettime()) <= 0)
{
//Caso os 2592000 segundos tenham passado, vai negativar, menor que zero por conta da regra da subtração, o maior número primeiro e depois o menor, enfim...
} else {
SendClientMessage(playerid, -1, "* Você possui %s de VIP.", ConvertDate(PlayerData[playerid][pDonation] - gettime()));
}
stock ConvertTime(number) // Função que "formata" os segundos em datas, ou seja se for +60 segundos, 1 minuto, +3600 segundos = 1 hora e assim vai...
{
new hours, mins, secs, string[64], days = 0;
hours = floatround(number / 3600.0, floatround_floor);
mins = floatround((number / 60.0) - (hours * 60.0), floatround_floor);
secs = floatround((number % 60));
if(hours >= 24)
{
days = floatround((hours/24.0), floatround_floor);
hours = hours % 24;
}
if(days > 0)
format(string, 64, "%d dia(s) e %d hora(s)", days, hours);
else if(hours > 0)
format(string, 64, "%d hora(s) e %d minuto(s)", hours, mins);
else if(mins > 0)
format(string, 64, "%d minuto(s)", mins, secs);
else
format(string, 64, "%d segundo(s)", secs);
return string;
}
Qualquer dúvida, só avisar, mas basicamente é assim que funciona, não sei se expliquei bem.
Eu talvez faria dessa forma:
Código: #include <a_samp>
#include <sscanf2>
#include <zcmd>
#include <foreach>
public OnGameModeInit()
{
SetTimer("OnUpdateAllPlayers", 1000, true);
return 1;
}
forward OnUpdateAllPlayers();
public OnUpdateAllPlayers()
{
foreach(new i : Player)
{
if(PlayerData[i][pDonate] != -1 && (PlayerData[i][pDonate] - gettime()) <= 0)
{
SendClientMessage(playerid, -1, "* Seus privilégios de doação acabou.");
PlayerData[i][pDonate] = -1;
}
}
return 1;
}
CMD:setdonate(playerid, params[])
{
new
id,
days;
if(sscanf(params, "uD(31)", id, days))
return SendClientMessage(playerid, -1, "* /setdonate [id] [days (optional)]");
if(!IsPlayerConnected(id))
return SendClientMessage(playerid, -1, "* Jogador não está conectado.");
new
string[128];
PlayerData[id][pDonate] = gettime() + (days * 86400);
format(string, sizeof(string), "* Você recebeu %s de privilégios de doador.", ConvertTime(PlayerData[playerid][pDonate] - gettime()));
SendClientMessage(id, -1, string);
return 1;
}
stock ConvertTime(number)
{
new hours, mins, secs, string[64], days = 0;
hours = floatround(number / 3600.0, floatround_floor);
mins = floatround((number / 60.0) - (hours * 60.0), floatround_floor);
secs = floatround((number % 60));
if(hours >= 24)
{
days = floatround((hours/24.0), floatround_floor);
hours = hours % 24;
}
if(days > 0)
format(string, 64, "%d dia(s) e %d hora(s)", days, hours);
else if(hours > 0)
format(string, 64, "%d hora(s) e %d minuto(s)", hours, mins);
else if(mins > 0)
format(string, 64, "%d minuto(s)", mins, secs);
else
format(string, 64, "%d segundo(s)", secs);
return string;
}
Top demais meu amigo. irei testar ele.
E por curiosidade, mesmo o player estando OFFLINE ele faz essa contagem?
RE: CHECAR DIA E ANO - Carlos Victor - 29/11/2022
Sim, o tempo não para, mesmo o jogador offline, na vida real o tempo vai continuar contando.
Como eu disse, a função gettime retorna o Unix Timestamp, que é um método de data universal, ele se mede por segundos(algo padrão e nível global), e toda vez que você chama a função gettime, vai perceber que vai aumentando por conta dos segundos, que sempre avança a cada segundo(obviamente) qualquer coisa só dar uma pesquisada, alguns meses atrás eu estava na mesma dúvida publicando meu primeiro tópico aqui no portal.
|