Anúncio
[Resolvido] Como por o "Relog" para a Seleção de Personagem estilo BPT

Vamos lá, vou trazer mais um tutorial nesse tutorial venho trazer um relog estilo bpt, pode conter bugs é mais para estudos vamos no tutorial.
Fase 1: Preparação - Criando o Comando de Comunicação
Tudo começa com a criação de um novo "comando" (Opcode) para que o cliente e o servidor possam "conversar" sobre a ação de relog.
Passo 1: Definir o Novo Opcode
-
-
Localize o Ficheiro de Opcodes: Abra o ficheiro de cabeçalho (
NetType.h
) onde todos os códigos de operação da rede são definidos. Geralmente, este ficheiro é partilhado entre o servidor e o cliente. -
Adicione o Novo Comando: No final da lista de
enum
de opcodes, antes doOPCODE_END
, adicione a nova linha para o nosso comando de relog.// --- INÍCIO DA NOSSA ADIÇÃO --- OPCODE_CHAR_RELOG_REQUEST, // Comando para solicitar o retorno à seleção de personagem // --- FIM DA NOSSA ADIÇÃO ---
Agora, vamos ensinar o servidor a reagir quando receber o novo comando. A tarefa do servidor é crucial: salvar o progresso do jogador com segurança e autorizar o cliente a prosseguir.
Passo 2: Processar o Pedido de Relog
-
Localize o Processador de Pacotes: Abra o ficheiro principal do servidor que lida com os pacotes recebidos dos jogadores.
-
Ficheiro:
SrcServer/src/Server/OnSever.cpp
Encontre a Função Principal: Dentro deste ficheiro, encontre a função que contém um grande
switch
para tratar os opcodes.Função:
RecvUserPacket()
-
Adicione o Novo
case
: Dentro doswitch
, adicione o bloco de código para tratar o nosso novo opcode.Código em
OnSever.cpp
:// Dentro da função RecvUserPacket(int conn, ...), dentro do switch... // --- INÍCIO DA NOSSA ADIÇÃO --- case OpCode::OPCODE_CHAR_RELOG_REQUEST: { // Primeiro, obtemos um ponteiro para as informações do jogador que enviou o pedido. rsPLAYINFO* lpPlayInfo = &rsPlayInfo[conn]; // Verificação de segurança: garantimos que o jogador está válido e no jogo. if (lpPlayInfo->lpsmSock && lpPlayInfo->smCharInfo.State == smCHAR_STATE_USER) { // Passo MAIS IMPORTANTE: Chamamos a função existente para salvar o personagem no DB. // Isto garante que nenhum progresso seja perdido. // Os parâmetros podem variar, mas a ideia é salvar sem desconectar. DBSaveCharacter(lpPlayInfo, TRUE, FALSE); // Preparamos um pacote de resposta para enviar de volta ao cliente. smTRANS_COMMAND smTransCommand; smTransCommand.code = OpCode::OPCODE_CHAR_RELOG_REQUEST; // Usamos o mesmo opcode smTransCommand.size = sizeof(smTRANS_COMMAND); // Enviamos a confirmação para o cliente, autorizando-o a prosseguir. lpPlayInfo->lpsmSock->Send((char*)&smTransCommand, smTransCommand.size, TRUE); } } break; // --- FIM DA NOSSA ADIÇÃO ---
Agora o servidor agora sabe o que fazer. Ele recebe o pedido, salva o personagem e dá a "luz verde" para o cliente.
agora seguimos para a parte no game:
Fase 3: Implementando a Lógica no Cliente (
SrcGame
)Finalmente, vamos fazer as alterações no cliente para que o jogador possa iniciar o processo e para que o cliente saiba como reagir à "luz verde" do servidor.
Passo 3.1: Adicionar o Botão "Selecionar Personagem" na UI
-
Contexto: Esta parte depende de como a sua interface de utilizador (UI) foi construída. Você precisará de adicionar um novo botão à janela do menu do jogo (a que tem "Sair", "Opções", etc.).
-
Ação: Na função que é chamada quando este novo botão é clicado, adicione o código para enviar o nosso opcode para o servidor.
Código na Função de Clique do Botão:
void OnClick_Button_GoToCharSelect() { // Cria um pacote simples de comando. smTRANS_COMMAND smTransCommand; smTransCommand.code = OpCode::OPCODE_CHAR_RELOG_REQUEST; // Define o nosso novo comando smTransCommand.size = sizeof(smTRANS_COMMAND); // Envia o pacote para o servidor. // g_Socket é o nome provável do socket global de conexão. send(g_Socket, (char*)&smTransCommand, smTransCommand.size, 0); }
Passo 3.2: Lidar com a Resposta do Servidor
Agora, a parte final e mais importante no cliente. Precisamos de dizer ao jogo o que fazer quando o servidor enviar a confirmação.
-
Localize o Processador de Pacotes do Cliente: Abra o ficheiro do cliente que recebe e trata os pacotes vindos do servidor.
-
Ficheiro:
SrcGame/src/netplay.cpp
-
-
Encontre a Função e o
switch
: Assim como no servidor, encontre a função que contém oswitch
dos opcodes. -
Adicione o Novo
case
:Código em
netplay.cpp
:// Dentro do switch que processa os pacotes... // --- INÍCIO DA NOSSA ADIÇÃO --- case OpCode::OPCODE_CHAR_RELOG_REQUEST: { // Esta é a ação chave que muda tudo. // 1. Limpamos os recursos do mundo do jogo atual. // Esta função deve remover monstros, NPCs e outros jogadores da memória. ReleaseField(); // 2. Mudamos o estado do jogo. // Em vez de chamar a função para fechar o jogo (como PostQuitMessage), // nós chamamos a função que define o "modo" do jogo. // O nome exato pode variar (ex: GAME_STATE_SELECT_CHAR, GAME_STATE_ID). SetGameState(GAME_STATE_CHAR_SEL); } break; // --- FIM DA NOSSA ADIÇÃO ---
Com isso a função a função vai funcionar, agora é com vocês!
-
-
-
-
-

Seja bem-vindo! Ótimo guia e muito bem organizado. 😉
Apenas criando um legado 😊
- 15 Fóruns
- 83 Tópicos
- 307 Posts
- 0 Online
- 102 Membros