[Plugin] Sistema de salvamento
#1

E ai galera, eu decidi compartilhar com quem estiver interessado uma ideia que eu particularmente usaria no meu GM se fosse o caso de eu estar montando um...

Espero que gostem, nгo espero receber crнticas porque nгo й algo que eu vб levar pra frente, mas se alguйm estiver interessado em dar continuidade e usar a ideia em cуdigos pessoais, a vontade.


O povo normalmente costuma usar esses sistemas de salvamentos gerais, que salva as tags relacionadas com um valor constante e etc, com extensгo .ini, mas eu particularmente nunca gostei muito da ideia, as ultimas coisas que desenvolvi em pawn se me lembro bem eu utilizava este meu plug-in para salvar e etc, porйm ele estava mais bem feito e redirecionado para oque eu precisava para manter os cуdigos funcionando.

A ideia й aproveitar a facilidade que a extensгo .dat trбs entre a escrita e a leitura utilizando C++(plug-ins)

Exemplo:
pawn Код:
#include "tryinclude.h"
#include "Invoke.h"

#include <string>
#include <vector>
#include <cstdlib>
#include <ctime>

using namespace std;

typedef void (*logprintf_t)(char* format, ...);

#define PATTERN_LOCATION    "scriptfiles/"
#define MAX_PLAYER_NAME     (24)
#define MAX_PLAYER_PASS     (16)
#define SLOTS               (500)

struct iPlayer // Estrutura para armazenar nome e senha
{
    char E_ACCOUNT_NAME[MAX_PLAYER_NAME];
    char E_ACCOUNT_PASS[MAX_PLAYER_PASS];
};
FILE *file[500]; //Arquivo vetor do tamanho de slots do servidor.

logprintf_t logprintf;
extern void *pAMXFunctions;

//================================================
//            WJ/IO, By Willian Luigi.
//================================================

cell AMX_NATIVE_CALL CreateAccount(AMX* amx, cell* params)
{
    cell *addr;
    int szFile = -1;
    char file_name[128], tmp[50];

    amx_GetAddr(amx, params[2], &addr);
    amx_StrLen(addr, &szFile);
    amx_GetString(tmp, addr, 0, szFile + 1);
    sprintf(file_name, "%s%s.dat", PATTERN_LOCATION, tmp);
    file[params[1]] = fopen(file_name, "ab+");
}

cell AMX_NATIVE_CALL InsertValues(AMX* amx, cell* params)
{
    cell *addr[2] = {NULL, NULL};
    int
        sLength_name,
        sLength_pass;
    char arq_name[60];
    iPlayer a;

    amx_GetAddr(amx, params[2], &addr[0]);
    amx_GetAddr(amx, params[3], &addr[1]);
    amx_StrLen(addr[0], &sLength_name);
    amx_StrLen(addr[1], &sLength_pass);
    amx_GetString(a.E_ACCOUNT_NAME, addr[0], 0, sLength_name+1);
    amx_GetString(a.E_ACCOUNT_PASS, addr[1], 0, sLength_pass+1);

    if (file[params[1]] == NULL) logprintf("Erro ao criar o arquivo.(By Willian Luigi)");

    fwrite(&a, sizeof(iPlayer), 1, file[params[1]]);
    return 1;
}

cell AMX_NATIVE_CALL ReadAccount(AMX* amx, cell* params)
{
    char *arq_name;
    int sz;
    cell *addr;
    FILE *arq;
    iPlayer
            a,
            b;

    amx_GetAddr(amx, params[1], &addr);
    amx_StrLen(addr, &sz);
    amx_GetString(a.E_ACCOUNT_NAME, addr, 0, sz+1);
    arq_name = new char[60];
    sprintf(arq_name, "%s%s.dat", PATTERN_LOCATION, a.E_ACCOUNT_NAME);
    arq = fopen(arq_name, "rb");


    do
    {
        fread(&b, sizeof(iPlayer), 1, arq);
        if (!strcmp(a.E_ACCOUNT_NAME,b.E_ACCOUNT_NAME))
        {
            logprintf("Nome: %s\nSenha: %s\n", b.E_ACCOUNT_NAME, b.E_ACCOUNT_PASS);
            break;
        }
    } while (!feof(arq));
    if (feof(arq))
    {
        logprintf("\nDADOS NГO CADASTRADOS!(By Willian Luigi)");
    }
    fclose(arq);
    return 1;
}

//================================================
//            WJ/IO, By Willian Luigi.
//================================================


PLUGIN_EXPORT unsigned int PLUGIN_CALL Supports()
{
    return SUPPORTS_VERSION | SUPPORTS_AMX_NATIVES | SUPPORTS_PROCESS_TICK;
}

PLUGIN_EXPORT bool PLUGIN_CALL Load(void **ppData)
{
    pAMXFunctions = ppData[PLUGIN_DATA_AMX_EXPORTS];
    logprintf = (logprintf_t) ppData[PLUGIN_DATA_LOGPRINTF];

    logprintf("\n==============================\n");
    logprintf(" * StrJobs loaded.\n");
    logprintf(" © - 2011 Willian Luigi");
    logprintf("\n==============================\n");
    return true;
}

PLUGIN_EXPORT void PLUGIN_CALL Unload()
{
    logprintf("\n==============================\n");
    logprintf(" * StrJobs loaded.\n");
    logprintf(" © - 2011 Willian Luigi");
    logprintf("\n==============================\n");
}

AMX_NATIVE_INFO PluginNatives[] =
{
    {"CreateAccount", CreateAccount},
    {"ReadAccount", ReadAccount},
    {"InsertValues", InsertValues},
    {0, 0}
};

PLUGIN_EXPORT int PLUGIN_CALL AmxLoad( AMX *amx )
{
    return amx_Register(amx, PluginNatives, -1);
}


PLUGIN_EXPORT int PLUGIN_CALL AmxUnload( AMX *amx )
{
    return AMX_ERR_NONE;
}
Nesse exemplo ele tб bem simples(cуdigo velho), reduzido apenas a criar um arquivo de 'conta' por exemplo, com Nome e senha...
Existem vбrias formas de melhorar e deixar isto um cуdigo mais agradбvel para o scripter, se for o caso, o interessante mesmo й entender a ideia do funcionamento do .dat...
Quando vocк trabalha desta forma, a sua estrutura iPlayer(struct) estabelece uma conexгo com o arquivo.dat, ou seja vocк nгo precisou se preocupar em referenciar tags e valores, vocк apenas inseriu valores e as tags foram impostas pela struct, e isso se torna um beneficio na parte que vocк consegue escrever seu prуprio sistema de salvamento com facilidade e com melhorias ao seu gosto, sem tirar que se torna uma maneira diferente das demais.

Exemplo no GM:
pawn Код:
//TOPO
native CreateAccount(playerid, nome[]);
native InsertValues(playerid, nome[], senha[]);
native ReadAccount(nome[]);

public OnPlayerConnect(playerid)
{
    new str[30], nome[24];
    GetPlayerName(playerid, nome, sizeof(nome));
    format(str, sizeof(str), "%s.dat", nome);
    if (fexist(str))
    {
        ReadAccount(nome); // Caso exista o arquivo com o nome do jogador que se conectou, ele lк...
    }
    else
    {
        CreateAccount(playerid, nome); //Caso nгo exista, ele cria o arquivo com o nome do jogador.
        SendClientMessage("Digite /senha [senha] para confirmar cadastro.");
    }
    return 1;
}

CMD:senha(playerid, params[])
{
    new senha[16]; //16 = tamanho mбximo de senha
    sscanf(params, "s[16]", senha);
    InsertValues(nome, senha); //E inseri o nome e a 'senha'
    return 1;
}
Como esse cуdigo tб ultrapassado e algumas pessoas(muitas) talvez nгo entendam muito de C++ e/ou desenvolvimento para plug-ins, eu posso acabar por fazer um tutorial para desenvolvimento de plug-ins se for o caso do interesse de muitos...

Abraзos.
Reply
#2

So falta compilar isso agr rs

muito bom mesmo, C++ e muito bom usar no SA-MP para nao falar que a velocidade e muito mais rapido.

Muito boa iniciativa, parabes +REP

traga mais disso para o forum que e muito bom mesmo
Reply
#3

A maioria do povo nгo vai conseguir compilar o plugin kkk ...


Mais parabйns willian , como eu to comeзando no C++ , tentarei estudar esse cуdigo.

E sim faзa um tutorial para a galera
Reply
#4

Otimo cara. Iniciativa exemplar. Testarei quando possivel.
Reply
#5

Й sempre bom ter algo diferentes das postagens rotineiras, quem sabe com um tutorial de criaзгo de plugins as pessoas (editores de gf), se interessem por outra linguagem e ao menos tente fazer algo diferente nos servidores...
Reply
#6

Otimo Plugin deve ajudar muitos ae, tenho uma duvida aq , tentei ver oque era Assembly mais vi que e dificil demais :/ , mais eai e melhor aprender C ou C++ ou C# ?
Reply
#7

parabйns, vc jб tinha mostrado este plug-in por sinal tem уtima utilidade ! (:
abrз, +REP
Reply
#8

Quote:
Originally Posted by shittt
Посмотреть сообщение
Otimo Plugin deve ajudar muitos ae, tenho uma duvida aq , tentei ver oque era Assembly mais vi que e dificil demais :/ , mais eai e melhor aprender C ou C++ ou C# ?
Primeiro C --> C++ --> C#
Reply
#9

Mais rбpido, menos lag.

Parabйns, bom trabalho.
Reply
#10

Grande uilian ... muito ph0ds parabйns mano : )
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)