13.09.2013, 01:57
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:
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:
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.
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;
}
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;
}
Abraзos.