fiz esse comando que ao usar ele procura a lista de objetos que fiz na scriptfiles objects.txt entao o problema e que nao esta attachando o objeto ao jogador acho q fiz algo errado e nao sei resolver a outra coisa e que ao editar o objeto coloco na coordenada em que quero mas nao salva o objeto fica como se tivesse um ponto fixo acho que deve ser o problema aqui nisso if (response == EDIT_RESPONSE_FINAL) { // Atualiza a posição e rotação do objeto após edição AttachObjectToPlayer(playerid, objetos[playerid], fX, fY, fZ, fRotX, fRotY, fRotZ); nao sei como fazer para o objeto ser salvo no corpo do jogador na maneira em que eu editei e usei o if (response == EDIT_RESPONSE_FINAL) talvez fiz algo errado e nao sei onde resolver
new objectList = mS_INVALID_LISTID; // ID da lista de seleção de objetos
new objetos[MAX_PLAYERS]; // Objeto temporário exibido para cada jogador
public OnFilterScriptInit()
{
// Carrega a lista de objetos a partir de um arquivo "objects.txt"
objectList = LoadModelSelectionMenu("objects.txt");
return 1;
}
CMD:objetos(playerid, params[])
{
// Mostra o menu para selecionar um objeto
ShowModelSelectionMenu(playerid, objectList, "Selecionar Objeto");
return 1;
}
public OnPlayerModelSelection(playerid, response, listid, modelid)
{
if (response)
{
new Float:x, Float:y, Float:z;
GetPlayerPos(playerid, x, y, z);
// Cria o objeto e salva a referência no array
objetos[playerid] = CreateObject(modelid, x, y, z, 0.0, 0.0, 0.0);
// Edita o objeto (isso pode ser opcional dependendo do que você deseja fazer)
EditObject(playerid, objetos[playerid]);
// Anexa o objeto ao jogador com a rotação inicial
AttachObjectToPlayer(playerid, objetos[playerid], x, y, z, 0.0, 0.0, 0.0);
}
return 1;
}
public OnPlayerEditObject(playerid, playerobject, objectid, response, Float:fX, Float:fY, Float:fZ, Float:fRotX, Float:fRotY, Float:fRotZ)
{
if (response == EDIT_RESPONSE_FINAL)
{
// Atualiza a posição e rotação do objeto após edição
AttachObjectToPlayer(playerid, objetos[playerid], fX, fY, fZ, fRotX, fRotY, fRotZ);
}
return 1;
}
public OnPlayerDisconnect(playerid, reason)
{
// Remove o objeto temporário do jogador ao sair
if (IsValidObject(objetos[playerid]))
{
DestroyObject(objetos[playerid]);
}
return 1;
}
opa pessoal estou com problema de erro de salvamento que é o seguinte
ele está dando esse erro:
Código:
ftp:\\192.304.131.1\SERVIDOR\gamesmodes\GM.pwn(114288) : warning 202: number of arguments does not match definition
ftp:\\192.304.131.1\SERVIDOR\gamesmodes\GM.pwn(114288) : error 001: expected token: ";", but found ")"
ftp:\\192.304.131.1\SERVIDOR\gamesmodes\GM.pwn(114288) : error 029: invalid expression, assumed zero
ftp:\\192.304.131.1\SERVIDOR\gamesmodes\GM.pwn(114288) : warning 215: expression has no effect
ftp:\\192.304.131.1\SERVIDOR\gamesmodes\GM.pwn(114289) : warning 202: number of arguments does not match definition
ftp:\\192.304.131.1\SERVIDOR\gamesmodes\GM.pwn(114289) : error 001: expected token: ";", but found ")"
ftp:\\192.304.131.1\SERVIDOR\gamesmodes\GM.pwn(114289) : error 029: invalid expression, assumed zero
ftp:\\192.304.131.1\SERVIDOR\gamesmodes\GM.pwn(114289) : warning 215: expression has no effect
ftp:\\192.304.131.1\SERVIDOR\gamesmodes\GM.pwn(114290) : warning 202: number of arguments does not match definition
ftp:\\192.304.131.1\SERVIDOR\gamesmodes\GM.pwn(114290) : error 001: expected token: ";", but found ")"
OBS: quando troco o function: por stock os erros somem. mas não chama funciona o salvamento..
Codigo completo:
Código:
/*--- Produção de Armas ---*/
enum hq_producao_armas {
gHQ_PRODUCAO,
gMATERIAS_PRIMAS,
gWEAPON_COLT45,
gWEAPON_SILENCED,
gWEAPON_DEAGLE,
gWEAPON_SHOTGUN,
gWEAPON_SAWEDOFF,
gWEAPON_SHOTGSPA,
gWEAPON_UZI,
gWEAPON_MP5,
gWEAPON_TEC9,
gWEAPON_AK47,
gWEAPON_M4,
gWEAPON_RIFLE,
gWEAPON_SNIPER,
gDINAMITES,
gMUNICOES
}
new INFO_ARMAS_HQ[hq_producao_armas];
public OnGameModeInit() {
new Query[200];
mysql_format(Conexao, Query, sizeof(Query2), "SELECT * FROM producao_armas WHERE HQ_PRODUCAO='1'");
mysql_tquery(Conexao, Query, "carregar_sql_hq_armas");
Estou usando o TogglePlayerSpectating(playerid, true) no OnPlayerRequestClass, para que na tela login apareça o mapa que eu criei.
Porém já tentei colocar o TogglePlayerSpectating(playerid, false) antes e depois do SetSpawnInfo, o que funciona corretamente ( O player dá spawn no lugar desejado ), mas ele morre sempre antes de ir para a posição.
Alguma ideia do que será? Desde já agradeço toda a ajuda.
samp-argon2: A Solução para Hashing de Senhas no SAMP
Se você está em busca de uma solução segura e eficiente para o hashing de senhas no San Andreas Multiplayer (SAMP), o samp-argon2 é a escolha ideal. Baseado no poderoso Argon2, vencedor da Password Hashing Competition (PHC) de 2013-2015, o samp-argon2 oferece a mais avançada tecnologia de criptografia de senhas, proporcionando segurança de alto nível para seus jogadores e servidores.
O que é o Argon2?
Criado por Alex Biryukov e Dmitry Khovratovich, o Argon2 é um algoritmo de hash resistente a ataques de diversos tipos, projetado para ser memory-hard. Ou seja, ele exige grande uso de memória durante o processo de hash, tornando-o resistente a ataques de força bruta e de paralelismo, como aqueles realizados por hardware especializado, como ASICs ou GPUs. O Argon2 é dividido em três variantes:
Argon2d: Protege contra ataques de GPU.
Argon2i: Ideal para proteger contra ataques de canais laterais.
Argon2id: Um equilíbrio entre segurança em tempo e memória, a escolha mais recomendada.
Essa flexibilidade, juntamente com a possibilidade de ajustar os parâmetros de memória, tempo e paralelismo, garante que você tenha o controle total sobre a segurança de suas senhas, sem comprometer a performance do seu servidor.
Por que Escolher samp-argon2?
Segurança Incomparável: O Argon2 é amplamente considerado o algoritmo mais seguro e robusto para hashing de senhas. Integrando o samp-argon2 no seu servidor SAMP, você garante uma camada extra de proteção para as senhas dos seus jogadores.
Facilidade de Implementação: O samp-argon2 foi projetado para ser simples de instalar e usar. Com apenas alguns passos, você pode integrar a criptografia de senhas no seu servidor, aumentando a segurança sem esforço.
Desempenho Otimizado: O samp-argon2 oferece configuração de parâmetros como mem_cost (custo de memória), time_cost (custo de tempo) e lanes (número de lanes de processamento). Isso permite otimizar o desempenho conforme suas necessidades, ajustando a segurança sem sacrificar a performance do servidor.
Compatibilidade Total: Compatível com Windows e Linux, você pode facilmente baixar os arquivos binários adequados para o seu sistema operacional, adicionar ao diretório de plugins e começar a usar imediatamente.
Como Funciona?
Integrar o samp-argon2 ao seu servidor SAMP é fácil. Aqui está um exemplo básico de como usar a função
forward OnPasswordHash(playerid); public OnPasswordHash(playerid) { // O hash da senha foi gerado com sucesso }
Com o argon2_get_hash, você pode recuperar o hash gerado e utilizá-lo para armazenar a senha de forma segura:
Código PHP:
new hash[85]; argon2_get_hash(hash); printf("Hash gerado: %s", hash);
Além disso, com a função argon2_verify, você pode comparar a senha fornecida pelo jogador com o hash armazenado, garantindo que apenas senhas corretas sejam aceitas:
O samp-argon2 oferece suporte a diferentes variantes de Argon2 (Argon2i, Argon2d e Argon2id), permitindo que você escolha a opção mais adequada para o seu caso de uso, seja priorizando a segurança contra ataques por hardware ou contra ataques de canais laterais.
Além disso, ao configurar o mem_cost, time_cost, lanes e o hash_length, você pode adaptar o algoritmo para atender a diferentes necessidades de desempenho, garantindo que o seu servidor continue rápido e eficiente sem abrir mão da segurança.
boa noite pessoal estou perdido criei um comando para attachar o objeto no player estou usando a include mselection para facilitar entao fiz esse comando mas o problema e que nao esta attachando o objeto no player nao sei oq esta errado dentro da pasta scriptfiles criei tambem objects.txt e coloque os id de alguns objetos para escolher o objeto os ids dos objetos
resumindo meu codigo ta todo funcional menos oq eu queria que e anexar o objeto ao player so isso
new objectList = mS_INVALID_LISTID; // ID da lista de seleção de objetos
new playerObjects[MAX_PLAYERS]; // Objeto temporário exibido para cada jogador
public OnFilterScriptInit()
{
// Carrega a lista de objetos a partir de um arquivo "objects.txt"
objectList = LoadModelSelectionMenu("objects.txt");
return 1;
}
CMD:objeto(playerid, params[])
{
// Mostra o menu para selecionar um objeto
ShowModelSelectionMenu(playerid, objectList, "Selecionar Objeto");
return 1;
}
public OnPlayerModelSelection(playerid, response, listid, modelid)
{
if (listid == objectList)
{
// Remove o objeto temporário anterior, se existir
if (IsValidObject(playerObjects[playerid]))
{
DestroyObject(playerObjects[playerid]);
}
if (response)
{
// Obtém a posição do jogador
new Float:x, Float:y, Float:z;
GetPlayerPos(playerid, x, y, z);
// Cria o objeto diretamente no jogador (posição ajustada pelo offset)
playerObjects[playerid] = CreatePlayerObject(playerid, modelid, x, y, z, 0.0, 0.0, 0.0);
// Anexa o objeto ao jogador (com o offset de posição)
AttachObjectToPlayer(playerid, playerObjects[playerid], 0.0, 0.0, 0.5, 0.0, 0.0, 0.0);
EditPlayerObject(playerid, playerObjects[playerid]);
// Mensagem confirmando que o objeto foi anexado
SendClientMessage(playerid, -1, "Objeto selecionado e fixado ao jogador!");
}
else
{
SendClientMessage(playerid, -1, "Você cancelou a seleção de objeto.");
}
}
return 1;
}
public OnPlayerDisconnect(playerid, reason)
{
// Remove o objeto temporário do jogador ao sair
if (IsValidObject(playerObjects[playerid]))
{
DestroyObject(playerObjects[playerid]);
}
return 1;
}
Guia Definitivo para Armazenamento Seguro de Senhas no SA-MP/Open-MP
Por xBruno1000x
Introdução
O armazenamento seguro de senhas é uma responsabilidade fundamental para qualquer desenvolvedor. Quando pedimos que os usuários criem uma senha, estamos lidando com a confiança deles, e é nosso dever proteger essas informações contra acessos não autorizados.
Embora o ambiente de SA-MP/Open-MP possa parecer um cenário menos sério, devemos lembrar que, segundo um estudo realizado pelo Google em parceria com a Harris Poll em 2019, 65% dos americanos reutilizam suas senhas em várias contas. Isso significa que uma falha de segurança no seu servidor pode comprometer outras contas importantes de seus usuários, como e-mails, redes sociais e serviços financeiros.
Este guia aborda as melhores práticas para armazenar senhas no SA-MP/Open-MP de maneira segura, dificultando ataques e protegendo seus jogadores.
O que NÃO fazer
1. Nunca armazene senhas em texto simples
Armazenar senhas em texto simples é um erro grave e comum. Caso o banco de dados seja acessado por um atacante, todas as senhas estarão disponíveis de forma legível, causando problemas de segurança em cadeia para os usuários. Sempre use um método de hash para proteger as senhas assim que recebê-las.
No SA-MP, desde a versão 0.3.7 R2-1, existe a função `SHA256_PassHash`, que permite criar hashes diretamente no script. Alternativamente, plugins como SampBcrypt e samp-crypto adicionam suporte ao algoritmo bcrypt, que oferece segurança ainda maior.
2. Não use apenas hashing simples
Embora criar um hash seja melhor do que armazenar a senha em texto simples, isso não é suficiente. Ataques com rainbow tables podem comprometer senhas fracas (como "123456" ou "password") em segundos. Solução: Adicione salt à senha antes de criar o hash.
Melhores Práticas para Armazenamento de Senhas
1. Use Salt
O salt é uma sequência aleatória única para cada usuário, adicionada à senha antes de ser transformada em hash. Ele dificulta ataques baseados em rainbow tables e força o atacante a realizar ataques de força bruta.
No SA-MP, você pode gerar um salt aleatório ao registrar o jogador, armazená-lo no banco de dados e utilizá-lo sempre que precisar verificar a senha.
Código:
new salt[64];
SHA256_PassHash("senhaDoUsuario", "saltAleatorio", salt, sizeof(salt));
Armazene o salt e o hash em colunas separadas no banco de dados.
2. Use Bcrypt
O bcrypt é um algoritmo de hash projetado para ser lento e resistente a ataques modernos. Sua principal vantagem é que ele inclui o salt automaticamente e é capaz de aumentar o custo computacional, dificultando ataques de força bruta.
Exemplo básico com bcrypt: 1. Geração do hash no registro:
Código:
new hash[72];
bcrypt_hash("senhaDoUsuario", hash, sizeof(hash));
2. Verificação no login:
Código:
if (bcrypt_verify("senhaDigitada", hash)) {
// Login com sucesso
} else {
// Senha incorreta
}
3. Adicione Pepper
O pepper é uma string secreta, definida no código do servidor, adicionada antes do hash. Diferentemente do salt, o pepper é compartilhado entre todos os usuários, mas não é armazenado no banco de dados. Caso o banco seja acessado, o atacante precisará conhecer o pepper para reconstruir os hashes.
Código:
#define PEPPER "minhaChaveSecreta123!"
new senhaComPepper[128];
format(senhaComPepper, sizeof(senhaComPepper), "%s%s", PEPPER, senhaDoUsuario);
4. Implemente Limites de Login
Bloqueie temporariamente usuários que falharem ao tentar logar várias vezes consecutivas. Isso dificulta ataques de força bruta diretamente no servidor.
Exemplo básico:
Código:
if (tentativasDeLogin >= 5) {
Kick(playerid);
SendClientMessage(playerid, -1, "Muitas tentativas falhas. Tente novamente mais tarde.");
}
5. Ofereça uma Interface Segura para Alteração de Senha
Permita que os usuários alterem suas senhas de forma segura e gere um novo salt a cada alteração. Isso evita que hashes antigos sejam reutilizados.
Dicas Extras
1. Senhas Fortes: Incentive os usuários a usarem senhas longas, com letras, números e caracteres especiais.
2. Confirmação de Senha: Peça ao usuário que digite a senha duas vezes ao registrar ou alterar.
3. Avisos de Segurança: Explique claramente que a senha não deve ser compartilhada ou reutilizada.
//{#} Salvar Profissao Experiencia/Level
new saveXP[400], saveLV[400], string[500];
// Construa as strings de atualização
for (new i = 0; i < E_WORKS; i++) {
format(saveXP, 400, "%s%d,", saveXP, Player[playerid][Player_Emperiencia_Job][i]);
format(saveLV, 400, "%s%d,", saveLV, Player[playerid][Player_Level_Job][i]);
}
mysql_format(ConnectionMysql, string, sizeof(string),"UPDATE `contas` SET `NivelEmprego` = '%s', `ExperienciaEmprego` = '%s' WHERE `pID` = '%d'",saveLV, saveXP, Player[playerid][Player_Experience]);
mysql_tquery(ConnectionMysql, string);
//{#}Carregar Profissao Experiencia/Level
new maximum[400];
@Loop(i, E_WORKS){
switch(i){
case 0:{
cache_get_value_name(0, "ExperienciaEmprego", maximum, 400);
sscanf(maximum, "p<,>a<i>[2]", Player[playerid][Player_Emperiencia_Job]);
}
case 1:{
cache_get_value_name(0, "NivelEmprego", maximum, 400);
sscanf(maximum, "p<,>a<i>[2]", Player[playerid][Player_Level_Job]);
}
}
}
Qual é a melhor forma de salvar e carregar múltiplas variáveis de um jogador , considerando desempenho ? Fiz esse metodo aqui mais não sei, estudo mysql a pouco tempo
Olá, estou tentando hookar a public OnPlayerClickPlayerTextDraw, porém ela excede os 31 caracteres suportados pelo compilador, como proceder?
#if defined _ALS_OnPlayerClickPlayerTextDraw #undef OnPlayerClickPlayerTextDraw #else #define _ALS_OnPlayerClickPlayerTextDraw #endif #define OnPlayerClickPlayerTextDraw HOOK2_OnPlayerClickPlayerTextDraw #if defined HOOK2_OnPlayerClickPlayerTextDraw forward HOOK2_OnPlayerClickPlayerTextDraw(playerid, PlayerText:playertextid); #endif
includes/../modules/gameplay/login.pwn(88) : error 200: symbol "HOOK2_OnPlayerClickPlayerTextDr" is truncated to 31 characters includes/../modules/gameplay/login.pwn(154) : error 200: symbol "_ALS_OnPlayerClickPlayerTextDra" is truncated to 31 characters includes/../modules/gameplay/login.pwn(160) : error 200: symbol "HOOK2_OnPlayerClickPlayerTextDr" is truncated to 31 characters
Termux Pawn é um repositório APT otimizado para o desenvolvimento de scripts em PAWN, com foco no SA-MP, Open.MP, e plataformas relacionadas. Simplifique o setup do ambiente no Termux e instale pacotes `.deb` necessários para desenvolver, compilar e testar seus scripts de forma ágil e eficiente.