Com mais de 10 anos de experiência no SA:MP, já entrei em diversos projetos, fiz centenas de trabalhos e hoje anuncio este servidor que foi projetado do absoluto zero em 4 meses de desenvolvimento e estamos na reta final.
A maioria dos projetos anunciados não vão pra frente. Isso é um fato e acompanhamos isto desde o Fórum SAMP oficial.
Apenas quem sabe o quão difícil é tirar um projeto do papel, sabe o trabalho que temos até lançá-lo.
Ideia de projeto:
O BERP surgiu a partir de dois ex-jogadores de um grande servidor, que me contrataram para desenvolver um servidor com uma proposta parecida com a do servidor que jogavam, pois gostavam da gameplay, porém não tanto da quantia de regras que o servidor possuia e como cada errinho podia custar suas contas.
Eu nunca joguei neste servidor em particular, mas já ouvi coisas parecidas de nossos jogadores.
Desenvolvimento:
Apesar de lançado e aberto ao público, o servidor está em constante desenvolvimento e para que nossos membros possam acompanhar de perto, temos o canal "changelog" onde todos podem ver o que foi alterado no servidor.
Há também o canal de sugestões onde discutimos a viabilidade de aplicar o que foi sugerido.
E também há a área de Previews, que foi recentemente adicionada para mostrar ao público mídia em vídeo ou imagem de forma antecipada sobre futuros updates que estão ou já foram desenvolvidos.
Recursos:
Whitelist (via Discord)
Anti-cheat com aproximadamente 30 mecanismos de detecções
O projeto tem como objetivo fornecer instaladores seguros e confiáveis para diferentes versões do mod SA:MP. Cada instalador é desenvolvido em C# usando Windows Forms, oferecendo uma interface moderna e amigável com suporte a múltiplos idiomas e uma janela com as redes sociais.
Eae pessoal estou usando o sistema do rootcause e está ocorrendo um erro que quando solta a mercadoria em cima do checkpoint fala que 'O pacote não caiu na área marcada'. tentei aumentar a distancia e nada.
public OnPlayerExitVehicle(playerid, vehicleid)
{
if(InDelivery[playerid])
{
SendClientMessage(playerid, 0xE74C3CFF, "DELIVERY FAILED: {FFFFFF}You left your plane.");
ResetDelivery(playerid);
}
return 1;
}
public OnPlayerKeyStateChange(playerid, newkeys, oldkeys)
{
if(IsATraffickingPlane(GetVehicleModel(GetPlayerVehicleID(playerid))) && PRESSED(KEY_SUBMISSION))
{
if(!InDelivery[playerid]) {
if(GetPVarInt(playerid, "DeliveryCooldown") > tickcount()) return SendClientMessage(playerid, 0xE74C3CFF, "DELIVERY: {FFFFFF}Please wait to start another delivery mission again.");
new id = random(sizeof(DropLocations)), string[144];
TraffickingObjects[playerid][OBJECT_ZONE] = CreatePlayerObject(playerid, 19946, DropLocations[id][dropX], DropLocations[id][dropY], DropLocations[id][dropZ], 0.0, 0.0, 0.0, 1200.0);
SetPlayerMapIcon(playerid, MAPICON_INDEX, DropLocations[id][dropX], DropLocations[id][dropY], DropLocations[id][dropZ], 24, 0, MAPICON_GLOBAL);
SendClientMessage(playerid, 0x2ECC71FF, "DELIVERY: {FFFFFF}You've started a delivery mission.");
format(string, sizeof(string), "DELIVERY: {FFFFFF}Drop the package in the marked area at {3498DB}%s {FFFFFF}and you'll get your money.", DropLocations[id][dropLocation]);
SendClientMessage(playerid, 0x2ECC71FF, string);
SendClientMessage(playerid, 0x2ECC71FF, "DELIVERY: {FFFFFF}You can drop a crate using H/CAPS LOCK.");
SendClientMessage(playerid, 0x2ECC71FF, "DELIVERY: {FFFFFF}You can cancel the delivery mission using 2 or by leaving your plane.");
InDelivery[playerid] = true;
PackageCount[playerid] = 5;
}else{
SendClientMessage(playerid, 0xE74C3CFF, "DELIVERY CANCELLED: {FFFFFF}You've cancelled the delivery mission.");
ResetDelivery(playerid);
}
}
if(InDelivery[playerid] && PRESSED(KEY_CROUCH))
{
if(IsValidObject(TraffickingObjects[playerid][OBJECT_PACKAGE])) return 1;
if(PackageCount[playerid] == 0) return SendClientMessage(playerid, 0xE74C3CFF, "DELIVERY: {FFFFFF}You don't have any more packages.");
new Float: x, Float: y, Float: z, Float: z2;
GetPlayerPos(playerid, x, y, z);
GetPointZPos(x, y, z2);
TraffickingObjects[playerid][OBJECT_PACKAGE] = CreateObject(PACKAGE_MODEL, x, y, z-1.5, 0.0, 0.0, 0.0);
MoveObject(TraffickingObjects[playerid][OBJECT_PACKAGE], x, y, z2, 20.0);
PackageCount[playerid]--;
}
return 1;
}
public OnObjectMoved(objectid)
{
if(GetObjectModel(objectid) == PACKAGE_MODEL)
{
new owner = INVALID_PLAYER_ID;
for(new i, p = GetPlayerPoolSize(); i <= p; ++i)
{
if(objectid == TraffickingObjects[i][OBJECT_PACKAGE])
{
owner = i;
break;
}
}
new id = random(sizeof(DropLocations)), string[144];
format(string, sizeof(string), "DELIVERY: {FFFFFF}You've delivered a package and earned {2ECC71}$%d{FFFFFF}.", money);
SendClientMessage(owner, 0x2ECC71FF, string);
DestroyPlayerObject(owner, TraffickingObjects[owner][OBJECT_ZONE]);
TraffickingObjects[owner][OBJECT_ZONE] = CreatePlayerObject(owner, 19946, DropLocations[id][dropX], DropLocations[id][dropY], DropLocations[id][dropZ], 0.0, 0.0, 0.0, 1200.0);
SetPlayerMapIcon(owner, 69, DropLocations[id][dropX], DropLocations[id][dropY], DropLocations[id][dropZ], 24, 0, MAPICON_GLOBAL);
format(string, sizeof(string), "DELIVERY: {FFFFFF}Drop the package in the marked area at {3498DB}%s{FFFFFF}.", DropLocations[id][dropLocation]);
SendClientMessage(owner, 0x2ECC71FF, string);
format(string, sizeof(string), "DELIVERY: {FFFFFF}Packages left: {3498DB}%d{FFFFFF}.", PackageCount[owner]);
SendClientMessage(owner, 0x2ECC71FF, string);
}else{
SendClientMessage(owner, 0xE74C3CFF, "DELIVERY: {FFFFFF}Package didn't land in the marked area, better luck next time.");
}
DestroyObject(TraffickingObjects[owner][OBJECT_PACKAGE]);
TraffickingObjects[owner][OBJECT_PACKAGE] = INVALID_OBJECT_ID;
if(PackageCount[owner] == 0)
{
SendClientMessage(owner, 0x2ECC71FF, "DELIVERY: {FFFFFF}You're out of packages.");
ResetDelivery(owner);
}
}
qual a funcao do samp de quando colocamos um objeto em um player o objeto gruda e se move junto com o player ?
porq eu fiz um codigo e ao anex o objeto em que o player escolhe o objeto gruda no player mas o player mesmo se movendo o objeto fica grudado nele fixo sem se mover eu usei o attachobjecttoplayer se tem outros eu nao conheco me ajudem nao e a questao do codigo e sim anexar o objeto ao jogador e o objeto grudar no player e se mover conforme o player se mexe e nao do jeito que fiz que ao player se mover o objeto gruda e fixa fixo sem movimento desculpe sou horrivel explicando esse foi o codigo que ate um script daqui me ajudou
eu so mudei uma coisa foi isso AttachObjectToPlayer(playerid, objetos[playerid] assim o objeto nao tava grudando entao inverti para assim AttachObjectToPlayer(objetos[playerid],playerid ai o objeto agora gruda mas nao acompanha o movimento do player ele so acompanha o player ficando fixo sem movimento , mais uma vez obg pela ajuda e desculpa qualqur aborrecimento que eu possa esta causando
new objectList = mS_INVALID_LISTID; // ID da lista de seleção de objetos
new objetos[MAX_PLAYERS]; // Objeto temporário exibido para cada jogador
// Offsets para objetos de jogadores
new Float:objectOffsets[MAX_PLAYERS][6]; // Armazena offsets (X, Y, Z, RotX, RotY, RotZ)
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)
{
// Obtém a posição do jogador
new Float:x, Float:y, Float:z;
GetPlayerPos(playerid, x, y, z);
// Cria o objeto na posição do jogador
objetos[playerid] = CreateObject(modelid, x, y, z, 0.0, 0.0, 0.0);
if (!IsValidObject(objetos[playerid]))
{
SendClientMessage(playerid, -1, "Erro: Objeto não foi criado!");
return 0;
}
// Inicializa os offsets para o objeto
objectOffsets[playerid][0] = 0.0; // Offset X
objectOffsets[playerid][1] = 0.0; // Offset Y
objectOffsets[playerid][2] = 0.5; // Offset Z (altura inicial padrão)
objectOffsets[playerid][3] = 0.0; // Rotação X
objectOffsets[playerid][4] = 0.0; // Rotação Y
objectOffsets[playerid][5] = 0.0; // Rotação Z
// Anexa o objeto ao jogador usando os offsets iniciais
AttachObjectToPlayer(playerid, objetos[playerid],
objectOffsets[playerid][0], objectOffsets[playerid][1], objectOffsets[playerid][2],
objectOffsets[playerid][3], objectOffsets[playerid][4], objectOffsets[playerid][5]);
// Edita o objeto para o jogador ajustá-lo
EditObject(playerid, objetos[playerid]);
}
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)
{
// Obtém a posição do jogador
new Float:playerX, Float:playerY, Float:playerZ;
GetPlayerPos(playerid, playerX, playerY, playerZ);
// Calcula os novos offsets baseados na posição do jogador
objectOffsets[playerid][0] = fX - playerX; // Offset X
objectOffsets[playerid][1] = fY - playerY; // Offset Y
objectOffsets[playerid][2] = fZ - playerZ; // Offset Z
objectOffsets[playerid][3] = fRotX; // Rotação X
objectOffsets[playerid][4] = fRotY; // Rotação Y
objectOffsets[playerid][5] = fRotZ; // Rotação Z
// Reanexa o objeto ao jogador com os novos offsets
AttachObjectToPlayer(objetos[playerid],playerid,
objectOffsets[playerid][0], objectOffsets[playerid][1], objectOffsets[playerid][2],
objectOffsets[playerid][3], objectOffsets[playerid][4], objectOffsets[playerid][5]);
}
else if (response == EDIT_RESPONSE_CANCEL)
{
SendClientMessage(playerid, -1, "edicao do objeto foi cancelada.");
}
return 1;
}
public OnPlayerDisconnect(playerid, reason)
{
// Remove o objeto associado ao jogador ao desconectar
if (IsValidObject(objetos[playerid]))
{
DestroyObject(objetos[playerid]);
objetos[playerid] = INVALID_OBJECT_ID; // Reseta o ID para evitar problemas futuros
}
return 1;
}
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.