?? packets.cpp
字號:
/* by My Destiny Team */
#include "server.h"
#include "packets.h"
// Funcoes para o tratamento dos pacotes
cPacket Packet;
cPacket::cPacket()
{
}
cPacket::~cPacket()
{
}
// Verifica se o pacote eh valido
//
// Retorna false se o pacote eh invalido
// Retorna true se o pacote eh valido
bool cPacket::PacketControl(sSocket &sSock, pHeader *pServer)
{
switch(pServer->opCode)
{
case 0x001: /* Login Packet */ break; case 0x002: /* Ping */ break; case 0x003: RequestLogin(sSock, (pDB_3h*)pServer); break; case 0x004: RequestSaveAccount(sSock, (pDB_4h*)pServer); break; case 0x005: RequestCreateChar(sSock, (pDB_5h*)pServer); break; case 0x006: RequestDeleteChar(sSock, (pDB_6h*)pServer); break; case 0x007: RequestEnterGame(sSock, (pDB_7h*)pServer); break;
case 0x008: RequestSaveCharacter(sSock, (pDB_8h*)pServer); break;
case 0x009: RequestSaveAccountAndCharacter(sSock, (pDB_9h*)pServer); break;
default: Log(NORMAL, "[PacketControl] Unknown Packet 0x%03X.",
pServer->opCode); break;
}
return true;
}// Faz o login do client no servidorvoid cPacket::RequestLogin(sSocket &sSock, pDB_3h *pServer){ pGS_4h *pPacket = (pGS_4h*)buf; // Preven??o contra crash na leitura das strings pServer->username[15] = '\0'; pServer->password[11] = '\0'; FILE *fp = Server.OpenFile(pServer->username, "r+b", ACCOUNT); if(fp != NULL) { // Abriu a conta do client com sucesso fread(&pPacket->account, sizeof(sAccount), 1, fp); if(pPacket->account.bantime <= time(NULL)) { // Verifica a senha do client if(pPacket->account.errorLogin >= 3 && pPacket->account.lasterror >= time(NULL)) { // Client errou a senha 3 vezes ou mais em menos de 5 minutos pPacket->account.lasterror += 10; // Conta banida por mais 10 segundos SendServerMessage(sSock, pServer->Header.clientID, Server.GetMessage(PASS3TIMES)); } else if(strcmp(pServer->password, pPacket->account.Password) == 0) { // Verifica se o client ja esta online sAccountList *acc = Server.ContainsAccount(pServer->username); if(acc != NULL) { // Conta ja esta online sSocket &sServer = Server.Get(acc->gsIndex); // Envia mensagem e desconecta o client que esta na conta SendServerMessage(sServer, acc->clientID, Server.GetMessage(BANNED2LOGIN)); SendDisconnectClient(sServer, acc->clientID); // Envia a mensagem para o client que tentou conectar SendServerMessage(sSock, pServer->Header.clientID, Server.GetMessage(BANNED2LOGIN)); // Banido por 10 minutos por conexao simultanea pPacket->account.bantime = time(NULL) + 600; } else { // Envia os pacotes de resposta para o servidor // Header pPacket->Header.packetSize = sizeof(pGS_4h); pPacket->Header.opCode = 0x004; pPacket->Header.clientID = pServer->Header.clientID; // Zera o numero de erros de senha pPacket->account.errorLogin = 0; // Atualiza o arquivo da conta fseek(fp, 0, SEEK_SET); fwrite(&pPacket->account, sizeof(sAccount), 1, fp); // Envia o pacote para atualizar a conta do client cClient::Send(sSock, pPacket, sizeof(pGS_4h)); // Header pGS_5h *charPacket = (pGS_5h*)buf; charPacket->Header.packetSize = sizeof(pGS_5h); charPacket->Header.opCode = 0x005; charPacket->Header.clientID = pServer->Header.clientID; charPacket->isReSend = false; // Le todos os personagens do client fread(charPacket->Character, sizeof(sCharacter), 4, fp); fclose(fp); // Envia o pacote para mandar o client para o char list cClient::Send(sSock, charPacket, sizeof(pGS_5h)); // Adiciona o client na lista dos conectados acc = new sAccountList; strncpy(acc->name, pServer->username, 16); acc->gsIndex = sSock.clientID; acc->clientID = pServer->Header.clientID; Server.AddAccount(acc); return ; } } else { // Aumenta o numero de vezes que o client errou a senha pPacket->account.errorLogin++; pPacket->account.lasterror = time(NULL) + 300; SendServerMessage(sSock, pServer->Header.clientID, Server.GetMessage(PASSWORDWRONG)); } // Atualiza a conta do usuario fseek(fp, 0, SEEK_SET); fwrite(&pPacket->account, sizeof(sAccount), 1, fp); } else { // Envia a mensagem pro client do ban da conta SendServerMessage(sSock, pServer->Header.clientID, Server.GetMessage(ACCOUNTBANNED)); } fclose(fp); } else { // Envia a mensagem de conta nao encontrada para o client SendServerMessage(sSock, pServer->Header.clientID, Server.GetMessage(ACCOUNT_NOTFOUND)); } // Desconecta o client SendDisconnectClient(sSock, pServer->Header.clientID);}// Salva a conta do clientvoid cPacket::RequestSaveAccount(sSocket &sSock, pDB_4h *pServer){ FILE *fp = Server.OpenFile(pServer->account.Username, "r+b", ACCOUNT); if(fp != NULL) { // Escreve a conta no arquivo do client fwrite(&pServer->account, sizeof(sAccount), 1, fp); fclose(fp); // Deleta a conta dos usuarios conectados Server.DeleteAccount(sSock.clientID, pServer->Header.clientID);
Log(INFO, "Save Account [%s].", pServer->account.Username); } else { // Nao foi possivel abrir o arquivo da conta Log(INFO, "check INVALID USERNAME: \"%s\"", pServer->account.Username); }}// Cria um personagem na conta do clientvoid cPacket::RequestCreateChar(sSocket &sSock, pDB_5h *pServer){ // Preven?ao contra o crash pServer->charclass &= 3; pServer->charindex &= 3; // Verifica se ja existe um personagem neste slot if(pServer->charinfo & (1 << pServer->charindex)) { // Existe um personagem neste slot SendServerMessage(sSock, pServer->Header.clientID, Server.GetMessage(ERRORCREATESLOT)); return ; } // Abre o arquivo do personagem FILE *fp = Server.OpenFile(pServer->charname, "rb", CHARACTER); if(fp != NULL) { // Ja existe um personagem com este nome fclose(fp); // Envia a mensagem de erro pro client SendServerMessage(sSock, pServer->Header.clientID, Server.GetMessage(ERRORCREATECHAR), pServer->charname); return ; } fp = Server.OpenFile(pServer->charname, "wb", CHARACTER); if(fp == NULL) { // N?o foi possivel criar o arquivo SendServerMessage(sSock, pServer->Header.clientID, Server.GetMessage(ERRORCREATEFILE), pServer->charname); return ; } // Escreve o nome da conta fwrite(pServer->username, 16, 1, fp); fclose(fp); // Pega o ponteiro das informacoes do char base sCharacter *bchar = &charBase[pServer->charclass]; // Abre o arquivo da conta fp = Server.OpenFile(pServer->username, "r+b", ACCOUNT); if(fp == NULL) { // Arquivo da conta nao foi encontrado SendServerMessage(sSock, pServer->Header.clientID, Server.GetMessage(ERRORCREATEACC), pServer->username); return ; } // Guarda o valor real da cidadania do personagem base u32 bCitizen = bchar->Equip[0].EFV3; if(bCitizen == 16) { // Edita a cidadania do personagem bchar->Equip[0].EFV3 = sSock.clientID; } // Troca o nome do personagem strncpy(bchar->Name, pServer->charname, 12); // Vai para o offset do personagem que sera criado fseek(fp, sizeof(sAccount) + (sizeof(sCharacter) * pServer->charindex), SEEK_SET); // Escreve o personagem na conta fwrite(bchar, sizeof(sCharacter), 1, fp); fseek(fp, sizeof(sAccount), SEEK_SET); // Registra o personagem nas informacoes da conta pServer->charinfo |= (1 << pServer->charindex);
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -