Sie sind auf Seite 1von 26

RFC 20191 TetriNet April 2019

Network Working Group C. Fernando


Request for Comments: 20191 J. Julio
Updates: J. Ismael
Category: Informational S. João
Goias Federal University
April 2019

TetriNet Game Protocol

Resumo
Status deste Memorando
Este documento especifica um protocolo de rastreamento de padrões da Internet para
a comunidade da Internet e solicita discussão e sugestões de melhorias. Por favor,
consulte a edição atual da documentação do desenvolvedor jetrix e o código fonte do
GTetrinet para o estado de padronização e status deste protocolo. A distribuição
deste memorando é ilimitado.

Resumo
Abstract
O protocolo TetriNET define o modo multiplayer do Game Tetris. É um protocolo
genérico, que pode ser usado em sistemas distribuı́dos. Define as regras de comunicação
e jogo do cliente e servidor.
Tetrinet foi originalmente desenvolvido pela St0rmCat em 1997. A última versão
oficial é 1.14. O jogo foi originalmente desenvolvido para o Windows e posteriormente
foi portado para outros sistemas. O St0rmCat lançou o TetriNET 2 em 2000, que apresenta
gráficos aprimorados, mais tipos de blocos especiais, recursos adicionais (como reter
a peça e bloquear sombras) e um servidor mestre.
Esta informação faz referência ˋ
a página não oficial do protocolo TetriNET hospedada
por tetrinet.us, a documentação do desenvolvedor jetrix e o código fonte do GTetrinet.

C. Fernando, et al. Informational [Page 1]


RFC 20191 TetriNet April 2019

Tabela de Conteúdo
1 Introdução 4
1.1 Propósito . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.2 Requerimentos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.3 Terminologia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.4 Visão Geral do Protocolo . . . . . . . . . . . . . . . . . . . . . . . . . 6

2 Servidor - Mensagens 7
2.1 Jogadores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
2.1.1 Numero de Jogador . . . . . . . . . . . . . . . . . . . . . . . . . 7
2.1.2 Ingresso de Jogador . . . . . . . . . . . . . . . . . . . . . . . . 7
2.1.3 Saı́da de Jogador . . . . . . . . . . . . . . . . . . . . . . . . . 7
2.1.4 Equipe de Jogadores . . . . . . . . . . . . . . . . . . . . . . . . 8
2.1.5 Ranking . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
2.2 Comunicação entre Jogadores . . . . . . . . . . . . . . . . . . . . . . . 8
2.2.1 Mensagem de bate-papo da partida . . . . . . . . . . . . . . . . . 8
2.2.2 Ações de bate-papo da Partida . . . . . . . . . . . . . . . . . . . 9
2.2.3 Mensagem de chat do Jogo . . . . . . . . . . . . . . . . . . . . . 9
2.3 O Jogo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
2.3.1 Novo Jogo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
2.3.2 Partida em Andamento . . . . . . . . . . . . . . . . . . . . . . . 9
2.3.3 Atualização de Campos . . . . . . . . . . . . . . . . . . . . . . . 10
2.3.4 Atualização de Nı́vel . . . . . . . . . . . . . . . . . . . . . . . 10
2.3.5 Usar Especial . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
2.3.6 Enviar linhas de adição de Estilo Clássico . . . . . . . . . . . . 10
2.3.7 Jogador Eliminado . . . . . . . . . . . . . . . . . . . . . . . . . 11
2.3.8 Jogador Vencedor . . . . . . . . . . . . . . . . . . . . . . . . . 11
2.3.9 Pausar / Retomar Partida . . . . . . . . . . . . . . . . . . . . . 11
2.3.10 Fim de Jogo . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
2.4 String de Regras do Jogo . . . . . . . . . . . . . . . . . . . . . . . . . 12
2.5 Funções Adicionais . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
2.5.1 Sem conexão . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
2.5.2 Solicitação de Informações do Cliente . . . . . . . . . . . . . . . 13
2.5.3 Teste de Conexão . . . . . . . . . . . . . . . . . . . . . . . . . 14
2.6 Linhas de lixo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
2.7 Linhas Espciais . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
2.8 Tipos de Blocos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
2.8.1 Blocos Especiais . . . . . . . . . . . . . . . . . . . . . . . . . 18

3 Modo Clássico 19
3.1 Adicionar Estilo Clássico . . . . . . . . . . . . . . . . . . . . . . . . 19

4 Cliente - Mensagens 20
4.1 Conectar ao Servidor . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
4.1.1 Login . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
4.1.2 Nome da Equipe . . . . . . . . . . . . . . . . . . . . . . . . . . 20
4.1.3 Informação do Cliente . . . . . . . . . . . . . . . . . . . . . . . 21
4.2 Comunicação do Cliente . . . . . . . . . . . . . . . . . . . . . . . . . . 21
4.2.1 Mensagem de bate-papo da partida . . . . . . . . . . . . . . . . . 21
4.2.2 Ação de bate-papo da Partida . . . . . . . . . . . . . . . . . . . 21
4.2.3 Mensagem de Bate-Papo do Jogo . . . . . . . . . . . . . . . . . . . 22
4.3 O Jogo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
4.3.1 Iniciar e Parar Jogo . . . . . . . . . . . . . . . . . . . . . . . 22
4.3.2 Atualização de Campo . . . . . . . . . . . . . . . . . . . . . . . 22
4.3.3 Atualização de nı́vel . . . . . . . . . . . . . . . . . . . . . . . 22

C. Fernando, et al. Informational [Page 2]


RFC 20191 TetriNet April 2019

4.3.4 Enviar Especial . . . . . . . . . . . . . . . . . . . . . . . . . . 23


4.3.5 Enviar Linhas de Adição de Estilo Clássico . . . . . . . . . . . . 23
4.3.6 Jogador Eliminado . . . . . . . . . . . . . . . . . . . . . . . . . 23
4.3.7 Pausar e Retomar Jogo . . . . . . . . . . . . . . . . . . . . . . . 24

5 Atualização de Campos 25

C. Fernando, et al. Informational [Page 3]


RFC 20191 TetriNet April 2019

1 Introdução

1.1 Propósito

O protocolo Tetrinet é um nı́vel de aplicação para informações distribuı́das,


pode ser usado em rede com o protocolo da camada de transporte(TCP) ou da
camada de aplicação(HHTP). Esta especificação define o protocolo referido
como TetriNet 1.14, definindo os processos e funções do servidor e do
clientes, como também as mensagens trocadas entre clientes e servidor.

1.2 Requerimentos

As palavras-chave "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",


"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY"e "OPTIONAL"neste documento
devem ser interpretados como descrito na RFC 2119.

Uma implementação não é compatı́vel se falhar em satisfazer um ou mais


dos MUST ou REQUIRED requisitos de nı́vel para os protocolos que implementa.
Uma implementação que satisfaz todos os MUST ou REQUIRED nı́vel e todos os
requisitos de nı́vel deve para seus protocolos é definido como "incondicionalmente
complacente", aquele que satisfaz todo o MUST requisitos de nı́vel, mas não
todos SHOULD lrequisitos de nı́vel para seus protocolos é definido como
"incondicionalmente complacente."

1.3 Terminologia

Esta especificação usa vários termos para se referir ˋas funções desempenhadas
pelos clientes e servidor, e os objetos da comunicação do protocolo
TetriNet.

partyline (partida)
Uma sessão de partida entre jogadores.

player score (pontuação do jogador)


Pontuação do jogador na partida ou o acumulado das partidas.

team score (pontuação da equipe)


Pontuação de uma partida obitida pela equipe

tetrifast
Variação do jogo TetriNet deixando o jogo mais veloz.

chat window (janela de conversas)


Janela onde são exibidas as mensagens dos jogadores

special (especial)

C. Fernando, et al. Informational [Page 4]


RFC 20191 TetriNet April 2019

Define uma mensagem para enviar bloco especial a outro jogador

classic mode (modo clássico)


Modo clássico do jogo Tetris, apenas um jogador na partida

block (bloco)
Nome dos objetos básicos do jogos

special block (bloco especial)


Blocos com caracteristicas especiais que acerretam em alguns efeitos na
janela de jogo de outro jogador

targetnum (numero do jogador)


Define o numero do jogador que recebera a mensagem

field(campo, janela do jogo)


Definido como janela de jogo do jogador.

newgame
Inicio de um novo jogo.

starting height
Altura inicial da partida

starting level
Nı́vel que se inicia a partida

lines per level


Quantidade de linhas por nı́vel

level increment
Incremento do nı́vel

lines per special


Linhas por especial

specials added
Especial adicionado

special capacity
Capacidade do especial

Block frequencies
frequência de blocos

special frequencies
Frequência de especial

average levels
Taxa do nı́vel, velocidade.

classic rules
Regras clássicas

C. Fernando, et al. Informational [Page 5]


RFC 20191 TetriNet April 2019

1.4 Visão Geral do Protocolo

O protocolo TetriNet é a definição do jogo Tetris em modo multiplayer.


Ele define como o servidor gerencia as partidas, as mensagens que são
trocadas entre cliente-servidor-cliente, suas funções e variações. O jogo
admite de 1 a 6 jogadores, que recebem um número de acordo com a sua
entrada na partida, sendo que o jogador de número 1 é o operador do canal
e pode iniciar, parar, pausar e retomar jogos. O servidor pode reorganizar
a numeração dos jogadores de acordo com os critérios estabelecidos neste
protocolo.
A utilização do protocolo em aplicações distribuı́das pode ser por meio
do protocolo da camada de transporte (TCP) e também pelo protocolo da camada
de aplicação (HTTP).

C. Fernando, et al. Informational [Page 6]


RFC 20191 TetriNet April 2019

2 Servidor - Mensagens

2.1 Jogadores

2.1.1 Numero de Jogador

playernum <number> or #)(!@(*3 <number>

(O primeiro formato é usado pelo TetriNET original protocolo, e


o segundo pelo protocolo Tetrifast.)

Enviado para um único cliente imediatamente após o cliente se


conectar e para qualquer número de clientes sempre que o servidor
desejar reorganizar a ordem de seus clientes conectados. Especifica
o "número do jogador"do cliente. O jogador com o menor número é
o operador do canal, que pode iniciar, parar, pausar e retomar
jogos, e quem pode ter outros poderes, dependendo do servidor e suas
configurações.

argumentos tipo valores descrição


number integer 1 − 6 o número de jogador para um novo jogador do cliente

2.1.2 Ingresso de Jogador

playerjoin <number> <nickname>

Enviado para todos os clientes conectados (incluindo, com alguns


servidores, o cliente ingressando) quando um novo participante ingressa
no servidor. Os clientes de conexão também recebem uma dessas
mensagens para cada player já conectado ao servidor. Observe que
alguns servidores enviarão essa mensagem para o cliente que está
ingressando imediatamente após ele ingressar.

argumentos tipo valor descrição


number integer 1 − 6 o número de jogador do novo jogador
nickname string o apelido do novo jogador

2.1.3 Saı́da de Jogador

playerleave <number>

Enviado para todos os clientes conectados sempre que um jogador


deixar o servidor.

argumentos tipo valores descrição


number integer 1 − 6 o número do jogador que saiu do jogo

C. Fernando, et al. Informational [Page 7]


RFC 20191 TetriNet April 2019

2.1.4 Equipe de Jogadores

team <number> <team name>

Enviado para todos os clientes, exceto o cliente com o jogador


correspondente, sempre que um jogador entrar no jogo e identificar
sua equipe e quando um jogador mudar de equipe.

argumentos tipos valores descrição


o número do jogador que entrou no jogo
number integer 1 − 6
em equipe ou mudou de equipe

2.1.5 Ranking

winlist <type><name>;<score> <type><name>;<score> ... <type><name>;<score>

(Lista de argumentos de tamanho variável, espaços entre cada conjunto


de três.)

Enviado para um único cliente imediatamente após esse cliente se


conectar e para todos os clientes após o final de um jogo. Especifica
a lista de jogadores e equipes que possuem as pontuações mais altas
no servidor.

argumentos tipo valores descrição


especifica se a entrada é uma equipe
type char t or p
(t) ou um jogador (p)
o nome do jogador ou time;
name string note que se este for um nome de equipe,
pode conter espaços
score integer a pontuação do jogador ou da equipe

2.2 Comunicação entre Jogadores

2.2.1 Mensagem de bate-papo da partida

pline <sendernum> <message>

Enviado para todos os jogadores (excluindo o remetente original da


mensagem) sempre que uma mensagem de bate-papo for enviada durante a
partida (a janela de bate-papo principal.)

C. Fernando, et al. Informational [Page 8]


RFC 20191 TetriNet April 2019

argumentos tipo valores descrição


o número de jogador do remetente da mensagem
sendernum integer 0 − 6
(0 indica as mensagens enviadas pelo servidor)
o conteúdo da mensagem. pode conter
message string
caracteres de formatação

2.2.2 Ações de bate-papo da Partida

plineact <sendernum> <action>

Enviado para todos os jogadores (excluindo o remetente da mensagem


original) sempre que uma mensagem de "ação"(uma mensagem começando
com /me, também conhecido como atacar) é enviado para a partida.

argumentos tipo valores descrição


o número de jogador do remetente da mensagem
sendernum integer 1 − 6 (servidor não envia
mensagens de ação)
message string o conteúdo da mensagem após o argumento /me

2.2.3 Mensagem de chat do Jogo

gmsg <message>

Enviado para todos os jogadores (incluindo o remetente da mensagem


original) sempre que uma mensagem é enviada para o campo de chat do
jogo. Observe que o número do jogador do remetente não é enviado
junto com a mensagem; os clientes geralmente incluem o apelido do
jogador na própria mensagem.

argumento tipo valores descrição


message string o conteúdo da mensagem de chat

2.3 O Jogo

2.3.1 Novo Jogo

Ver regras de nova partida

2.3.2 Partida em Andamento

ingame

Enviado para um único cliente quando esse cliente se conecta. Indica


que há uma partida em andamento no servidor.

C. Fernando, et al. Informational [Page 9]


RFC 20191 TetriNet April 2019

argumentos tipo valores descrição


sem argumentos

2.3.3 Atualização de Campos

Ver atualização de campos

2.3.4 Atualização de Nı́vel

lvl <playernum> <levelnum>

Enviado para todos os clientes (incluindo o remetente original) sempre


que o nı́vel do jogo de um jogador for alterado.

argument type values meaning


playernum integer 1 - 6 o no número do jogador cujo nı́vel de jogo mudou
levelnum integer o novo nı́vel de jogo do jogador

2.3.5 Usar Especial

sb <targetnum> <specialtype> <sendernum>

Enviado para todos os clientes (excluindo o remetente do especial)


sempre que um bloco especial for usado.

argumentos tipo valores descrição


o número do jogador que é o alvo do
targetnum integer 1 − 6
especial (0 indica todos os jogadores)
a, b, c, g,
o tipo de especial usado (ver
specialtype n, o, q, r
blocos especiais)
ou s
o número do jogador que enviou o especial
sendernum integer 1 − 6 (0 indica os especiais enviados pelo servidor,
o que é incomum, mas possı́vel).

2.3.6 Enviar linhas de adição de Estilo Clássico

sb 0 cs<numlines> <sendernum>

(Uma pequena variação da mensagem "Enviar especial", acima.)

Enviado para todos os clientes (excluindo o remetente) sempre que um


jogador concluir várias linhas em um jogo com o "modo clássico"ativado,
(veja regras de novo jogo) acionando adicionar estilo clássico.
O argumento targetnum deve sempre 0, já que o estilo clássico é
adicionado a todos os jogadores, exceto o remetente.

C. Fernando, et al. Informational [Page 10]


RFC 20191 TetriNet April 2019

argumentos tipos valores descrição


o número de linhas adicionadas ao campo
numlines char 1, 2 ou 4 (não necessariamente o mesmo que o
número de linhas limpas)
the number of the player who cleared the lines
sendernum integer 0 − 6 (0indicates lines added to everyone’s fields
by the server)

2.3.7 Jogador Eliminado

playerlost <playernum>

Enviado para todos os clientes (incluindo o jogador em questão) quando


o campo de um jogador fica cheio e ele perde o jogo em andamento.

argumentos tipo valores descrição


playernum integer 1 - 6 o número do jogador que perdeu o jogo

2.3.8 Jogador Vencedor

playerwon <playernum>

Enviado para todos jogadores quando resta apenas um jogador na


partida, o jogador vencedor.

argumentos tipos valores descrição


playernum integer 1 − 6 o número do jogador vencedor

2.3.9 Pausar / Retomar Partida

pause <state>

Enviado para um único cliente imediatamente após uma mensagem no


jogo para indicar se o jogo em andamento quando o cliente entra
em pausa e para todos os clientes conectados (incluindo o cliente
que originalmente enviou a solicitação de pausa) sempre que o jogo é
pausado ou retomado . Observe que, diferentemente da versão de cliente
para servidor, (veja protocolo tetrinet: mensagens cliente-para-
servidor) esta mensagem não inclui um número de jogador.

argumentos tipos valores descrição


"estado de pausa"do jogo: 1 indica pausa,
state boolean 1 ou 0
0 indica retomar.

C. Fernando, et al. Informational [Page 11]


RFC 20191 TetriNet April 2019

2.3.10 Fim de Jogo

endgame

Enviado para todos os clientes no final do jogo. Os jogos terminam


quando todos, exceto um jogador, são eliminados ou quando o operador
termina o jogo mais cedo.

2.4 String de Regras do Jogo

No inı́cio de um jogo, o servidor enviará ao cliente uma mensagem "newgame",


que será algo como se segue:

newgame 0 1 2 1 1 1 18 33333333333333555555555555552222222222222224444444
4444444666666666666667777777777777711111111111111111111111111111111111111
1111111111222222222222222222223444444444444456666666666666667888888999999
99990 1ÿ

Servidores Tetrifast irão substituir sete asteriscos ******* for the


newgame

Esta string, que representa as regras do jogo, se divide da seguinte


forma:

newgame <starting height> <starting level> <lines per level> <level increment>
<lines per special> <specials added> <special capacity> <block frequencies>
<special frequencies> <average levels> <classic rules>

ou

******* <starting height> <starting level> <lines per level> <level increment>
<lines per special> <specials added> <special capacity> <block frequencies>
<special frequencies> <average levels> <classic rules>

C. Fernando, et al. Informational [Page 12]


RFC 20191 TetriNet April 2019

argumentos tipo valores descrição


o número de linhas de lixo que deve estar
starting
integer ≥ 0 presente na parte inferior do campo de cada jogador
height
quando o jogo começa
starting
integer ≥ 1 o nı́vel em que todos os jogadores começam o jogo
level
lines per o número de linhas que um jogador deve limpar para
integer ≥ 1
level avançar para o próximo nı́vel
o número de nı́veis que um jogador avança quando
level
integer ≥ 0 ele ou ela completa o número requerido
increment
de linhas
lines per o número de linhas que um jogador deve limpar antes
integer ≥ 1
special especiais são adicionados para o campo dele ou dela
o número de especiais adicionados ao quadro de um jogador
specials
integer ≥ 0 quando ele ou ela completar o número requerido
added
de linhas
o número de especiais que um jogador pode ter em sua
special
integer ≥ 0 sua fila em um determinado momento. especiais coletadas
capacity
além deste número são descartados
string of
block freqüência de ocorrência (sendo cada número 1%)
100 1 − 7
frequencies de cada um dos diferentes tipos de blocos
integers
string of
special a frequência de ocorrência de cada um dos diferentes
100 1 − 9
frequencies blocos especiais
integers
average e 1, o cliente deve exibir os nı́veis médios de todos
boolean 1 or 0
levels ogadores no jogo (0 significa apenas que o valor está oculto)
classic
boolean 1 or 0 se 1, modo clássico está habilitado
mode

2.5 Funções Adicionais

2.5.1 Sem conexão

noconnecting <reason>

Enviado para um único cliente ao tentar se conectar a um servidor,


como uma mensagem de erro informando ao cliente que ele não pode se
conectar ao servidor no momento.

argumentos tipos valores descrição


uma mensagem de erro detalhando por
reason string
que o servidor recusou a conexão do cliente

2.5.2 Solicitação de Informações do Cliente

lvl 0 0

(Opcional, não faz parte do protocolo)

C. Fernando, et al. Informational [Page 13]


RFC 20191 TetriNet April 2019

Uma mensagem de atualização de nı́vel modificada, esta mensagem é


enviada por alguns servidores para um único cliente depois que
esse cliente se conecta. Ele é usado como uma solicitação para as
informações do aplicativo do cliente. veja \Informações do Cliente"
em protocolo tetrinet: mensagens de cliente para servidor

argumentos tipos valores descrição


(sem argumento)

2.5.3 Teste de Conexão

(Opcional, não faz parte do protocolo)


Uma mensagem em branco (apenas um caracter) enviada a todos os
clientes periodicamente para manter a conexão aberta. Nenhuma ação é
necessária, mas os clientes provavelmente desejarão enviar um próprio
teste de conexão para manter o soquete de leitura do servidor aberto.

argumentos tipos valores descrição


(sem argumento)

2.6 Linhas de lixo

Sob certas circunstâncias, (especificamente, o bloco especial "addline"e


a criação de um campo com um tamanho de pilha inicial diferente de zero)
você precisará gerar linhas de "lixo aleatório"para adicionar ao campo. O
código fonte do GTetrinet, que afirma em um comentário estar imitando o
comportamento do cliente TetriNET oficial, usa esse algoritmo:

1. De forma aleatória, defina cada célula na linha para conter um bloco


colorido ou espaço vazio.

2. Para garantir que haja pelo menos uma célula vazia, selecione aleatoriamente
uma célula na linha e defina-a como vazia.

Observe que esse algoritmo pode resultar em uma linha completamente vazia.

Implementação de exemplo (em C, usando random () do BSD; substitua seu


idioma favorito e RNG):
for ( var column = 0; column < NUM_COLUMNS ; column ++){
field_contents [ garbage_row ][ column ] =
Math . floor ( Math . random () * 100)
% ( NUM_CELL_COLORS + 1)
}
field_contents [ garbage_row ][ Math . floor ( Math . random ()
* 100) % NUM_COLUMNS ] = 0

Um algoritmo de linha de lixo diferente é usado para adicionar modo


clássico

C. Fernando, et al. Informational [Page 14]


RFC 20191 TetriNet April 2019

2.7 Linhas Espciais

Quando o jogador completa um certo número de linhas, especificadas pelo


servidor no inı́cio do jogo, um número de blocos especiais são adicionados
ao campo dele, para serem coletados quando o jogador completar as linhas
em que aparecem.

O algoritmo para adicionar um bloco especial ao campo é um pouco complicado e


muito mal documentado. A fonte GTetrinet, que pretende imitar o comportamento
do cliente TetiNET original, faz o seguinte:

1. para cada especial que desejamos adicionar ao campo:


i. conta o número de células preenchidas no campo que não contêm especiais
ii. se o número de células não especiais preenchidas for 0 (ou seja, o
campo estiver vazio ou contiver apenas especiais):
a. tente as seguintes 20 vezes:
aa. selecione uma coluna do campo aleatoriamente
ab. começando na parte superior do campo, verifique cada célula na coluna
selecionada até encontrarmos uma célula preenchida ou a parte inferior do
campo
b. se, depois de 20 tentativas, não conseguirmos encontrar uma coluna vazia
(também na parte inferior do campo) ou uma coluna cuja célula mais alta não
é especial, abandonaremos adicionar mais especiais
c. caso contrário, adicione um especial aleatório na parte inferior da
coluna vazia ou acima da célula não especial
iii. Se houver células não especiais no campo:
a. escolha aleatoriamente uma das células não especiais e substitua-a por
uma especial aleatória

Como você deve ter notado, existem algumas. . . esquisitices. . . neste


método. Em primeiro lugar, não há absolutamente nenhuma razão para
verificar se há colunas com células não especiais nelas na ramificação
"sem especialidades encontradas"; não estarı́amos nesse ramo se existisse
tal coluna. Em segundo lugar, existe uma possibilidade (um tanto remota)
de que, mesmo quando há colunas vazias presentes no campo, esse ramo não
pode adicionar nenhum especial ao campo; Eu escolhi replicar essa chance,
no entanto, por uma questão de consistência, já que a iTetrinet geraria um
pouco mais de especialidades do que outros clientes. (O algoritmo acima
também reconsidera de maneira ineficiente o número de células não especiais
no campo para cada especial colocado, mas isso é apenas uma questão de
velocidade.)

Como tal, a iTetrinet usa um método alternativo:


(A disposição do código real também é diferente e é refletida aqui)

1. conta o número de células não especiais no campo


2. para cada especial que desejamos adicionar ao campo:
i. Se houver células preenchidas não especiais no campo:
a. selecione uma célula não-especial aleatoriamente e substitua-a por uma
especial aleatória
b. diminuir a contagem de células não especiais no campo
ii. de outra forma:
a. tente as seguintes 20 vezes:
aa. selecione uma coluna aleatoriamente
ab. se a coluna estiver vazia, coloque um especial aleatório na linha

C. Fernando, et al. Informational [Page 15]


RFC 20191 TetriNet April 2019

inferior; se não, continue tentando


b. Se 20 tentativas passarem sem sucesso, abandone a colocação de outras
especialidades

(Uma nota: em um campo sem células não especiais, e a linha inferior


quase totalmente preenchida com especiais, exceto por uma coluna, ambos os
algoritmos adicionarão apenas o especial final - e, portanto, completar
uma linha completa de especialidades - aproximadamente 82% A Hora.)
Uma amostra de implementação do método da iTetrinet, em C, usando
random() do BSD (note que no iTetrinet, o campo é indexado de baixo para
cima, ou seja, a linha 0 é a linha inferior):

// Add specials to this field


void add_specials ( int specials_count )
{
// Count the number of non - special filled cells on the field
int non_special_cells = 0;
char cell ;
for ( int row = 0; row < NUM_ROWS ; row ++)
{
for ( int column = 0; column < NUM_COLUMNS ; column ++)
{
cell = field_contents [ row ][ column ];
if (( cell > 0) && ( cell < NUM_CELL_COLORS ))
non_special_cells ++;
}
}
// Attempt to add the specified number of specials
for ( int specials_added = 0; specials_added <
specials_count ; specials_added ++)
{
// If there are non - special cells on the field ,
// replace one at random with a special
if ( non_special_cells > 0)
{
// Choose a random number of cells to
// pass over before dropping the special
int cells_left = random () % non_special_cells ;
// Iterate over the field
for ( int row = 0; row < NUM_ROWS ; row ++)
{
for ( int column = 0; column < NUM_COLUMNS ; column ++)
{
// If this is a non - special cell , check
// whether to add the special
cell = field_contents [ row ][ column ];
if (( cell > 0) && ( cell < NUM_CELL_COLORS ))
{
// If we have skipped the predetermined
// number of cells , add the special

C. Fernando, et al. Informational [Page 16]


RFC 20191 TetriNet April 2019

if ( cells_left == 0)
{
// Replace the cell with a random special
field_contents [ row ][ column ] =
random_special ( special_frequencies );
// Decrement the number of non - special
cells remaining
non_special_cells - -;
// Jump to the next iteration of the
special - adding loop
goto next_special ;
}
// Haven ’ t reached the predetermined
// number of cells yet
cells_left - -;
}
}
}
}
else
{
// Make 20 attempts to find an empty column
int tries ;
for ( tries = 0; tries < 20; tries ++)
{
// Choose a random column
int row , column = random () % NUM_COLUMNS ;
// Check if the column is empty
for ( row = 0; row < NUM_ROWS ; row ++)
{
if ( field_contents [ row ][ column ] > 0)
break ;
}
// If the column was empty , add the new special
if ( row == NUM_ROWS )
{
// Add the new special to the bottom row
field_contents [0][ column ] =
random_special ( special_frequencies );
// Go to the next iteration of the
// special - adding loop
goto next_special ;
}
}
// If we ’ ve tried 20 times and not found
// an empty column , abandon adding more specials
if ( tries == 20)
goto abort ;
}
next_special :
}
abort :
}

C. Fernando, et al. Informational [Page 17]


RFC 20191 TetriNet April 2019

2.8 Tipos de Blocos

valor da nova string do jogo tipo de bloco


1 linha ou l
2 quadrado ou O
3 esquerda-L ou J
4 direita-L
5 direita-Z
6 esquerda-Z ou S
7 meia cruz ou T

2.8.1 Blocos Especiais

O protocolo TetriNET original define os seguintes blocos especiais


e seus efeitos:

caracter especial efeito


adiciona uma linha de lixo ˋa parte
a addline
inferior do campo do jogador de destino
remove a linha na parte inferior do campo
c clearline do jogador de destino (o restante
do campo é deslocado para baixo)
limpa completamente o campo do jogador
n nukefield
alvo
seleciona 10 células aleatoriamente no
r randomclear
campo do jogador alvo e as limpa
s switchfield troca o seu campo com o jogador do alvo
transforma todos os especiais no
b clearspecials campo do jogador alvo em blocos
regulares
puxa as células ocupadas do campo
g gravity do jogador alvo para baixo, preenchendo
lacunas
faz com que todas as linhas do campo do jogador
q quakefield de destino mudem aleatoriamente
de 0 a 3 colunas para a esquerda ou para a direita
destrói todos os blocos blockbomb no campo
do jogador alvo e espalha aleatoriamente
o blockbomb
em torno do campo os 8 blocos (em uma
área 3 × 3) em torno de cada um

O número na primeira coluna representa o código usado por uma nova


string de regras do jogo especificando as frequências das especiais,
enquanto a letra na segunda coluna representa o valor de char do
especial usado em atualizações de campo, e para a representação
interna da célula na maioria dos clientes.

As linhas limpas ou removidas como resultado de um jogador usando


um especial não são contadas para a contagem de linhas do jogador
liberada, e os especiais nas linhas limpas não são adicionados ˋa fila
do jogador.

C. Fernando, et al. Informational [Page 18]


RFC 20191 TetriNet April 2019

3 Modo Clássico

3.1 Adicionar Estilo Clássico

Se o servidor ativou o \modo clássico", (um dos argumentos para a nova


string de regras do jogo), então sempre que um jogador limpa várias linhas
simultaneamente, ele aciona um \estilo clássico". Adicionais no estilo
clássico, como o addline bloco especial, adiciona linhas ˋa parte inferior
dos campos dos jogadores, empurrando o resto do conteúdo do campo para cima.
Ao contrário das addlines, o estilo clássico adiciona o destino a todos os
outros players, em vez de apenas um, pode adicionar mais de uma linha por
vez e usar um algoritmo diferente para gerar o conteúdo das linhas.

número de linhas limpas linhas adicionadas a outros jogadores


2 1
3 2
4 4

Algoritmo de geração de linha de lixo:

1. preencha a linha com células aleatórias, não vazias e não especiais


2. escolha uma coluna aleatoriamente e limpe-a

Exemplo de implementação, em C, usando random() do BSD:

for ( int column = 0; column < NUM_COLUMNS ; column ++)


{
field_contents [ garbage_row ][ column ] =
( random () % NUM_CELL_COLORS ) + 1;
}
field_contents [ garbage_row ][ random ()
% NUM_COLUMNS ] = 0;

C. Fernando, et al. Informational [Page 19]


RFC 20191 TetriNet April 2019

4 Cliente - Mensagens
(Nota: "jogador local"é uma convenção que se refere ao usuário do cliente que
envia a mensagem.)

4.1 Conectar ao Servidor

4.1.1 Login

Para entrar em um servidor tetrifast com um apelido de TestUser, a


string que temos que enviar para o servidor é:

tetrifaster TestUser 1.13

Essa seqüência de caracteres deve ser codificada como exemplificado


no script (python) a seguir. Algumas páginas afirmam que você tem que
usar o IP do servidor para derivar h, mas a maioria dos servidores
adivinha isso de qualquer maneira e não se importa com o IP de onde
ele vem ou vai. Este script está usando o IP 209.52.144.98 como o IP
do servidor.

ip = [209 , 52 , 144 , 98] # list of ints


reg_str = ’ tetrifaster TestUser 1.13 ’
h = str (54 * ip [0] + 41 * ip [1] + 29 * ip [2] + 17 * ip [3])
dec = randrange (256) # random value between 0 <= x < 256
encoded = ’{:02 X } ’. format ( dec )
for i , c in enumerate ( reg_str ):
dec = (( dec + ord ( c )) % 255) ˆ ord ( h [ i % len ( h )])
encoded += ’{:02 X } ’. format ( dec )

Para um valor aleatório inicial de dec = 128, isto produz a string


80C512B4114A81DB7DC71DBEE70E4588CD1ABF13B5E42F6F96F9.

4.1.2 Nome da Equipe

team <number> <team name>

Enviado para o servidor imediatamente após o número do jogador de


jogador local for recebido. Identifica o nome da equipe que o jogador
local joga.

argumentos tipos valores descrição


number integer 1 − 6 o número de jogador do jogador local
team name string o nome da equipe do jogador local

C. Fernando, et al. Informational [Page 20]


RFC 20191 TetriNet April 2019

4.1.3 Informação do Cliente

clientinfo <client name> <client version>

(Opcional, não faz parte do protocolo)


Usado para enviar o nome e a versão do aplicativo cliente para o
servidor. Nem todos os servidores aceitarão esta mensagem - aqueles
que o solicitarão enviando uma solicitação de informações do cliente
( ver mensagens de servidor para cliente)

argumentos tipos valores descrição


o nome do aplicativo cliente (por exemplo,
client name string
"iTetrinet")
o número da versão do aplicativo cliente,
client version string
como uma string (por exemplo, "1.0.0")

4.2 Comunicação do Cliente

4.2.1 Mensagem de bate-papo da partida

pline <sendernum> <message>

Usado para enviar mensagens de bate-papo da partida do jogador local


para os outros jogadores no servidor. Esta mensagem é normalmente
repetida para todos os outros clientes conectados, mas muitos servidores
suportam o uso de comandos de barra (como /list ou /whisper) que são
manipulados pelo servidor e não são ecoados. Note que /me não é um
comando de barra do lado do servidor, veja \Ação de bate-papo da
Partida" abaixo.

argumentos tipos valores descrição


sendernum integer 1 − 6 o número de jogador do jogador local
o conteúdo da mensagem a enviar.
message string
pode conter caracteres de formatação

4.2.2 Ação de bate-papo da Partida

plineact <sendernum> <action>

Usado para enviar ações de linha partidária (mensagens iniciando


com /me, também conhecidas como emotes) do jogador local para os
outros jogadores no servidor. Essas mensagens não devem conter a
chave /me.

argumentos tipos valores descrição


sendernum integer 1 − 6 o número de jogador do jogador local
message string o conteúdo da mensagem após a chave /me

C. Fernando, et al. Informational [Page 21]


RFC 20191 TetriNet April 2019

4.2.3 Mensagem de Bate-Papo do Jogo

gmsg <message>

Usada para enviar uma mensagem do jogo (ou seja, uma mensagem inserida
no campo de bate-papo abaixo das áreas de jogo) do jogador local para
os outros jogadores no servidor. Tenha em atenção que esta mensagem
não contém o número de jogador do jogador local e, como resultado,
o cliente de receção não sabe de quem é que veio. Recomenda-se que
os clientes anexe o apelido do jogador local ˋa frente do conteúdo da
mensagem antes de enviá-lo.

argumentos tipos valores descrição


o conteúdo da mensagem de chat, talvez com
message string
o apelido do jogador local anexado na frente.

4.3 O Jogo

4.3.1 Iniciar e Parar Jogo

gmsg <message>

Usado para iniciar um novo jogo ou interromper um jogo em andamento.


Os servidores só responderão a esta mensagem se ela for enviada pelo
operador do canal, ou seja, o reprodutor conectado com o menor número
de jogador.

argumentos tipos valores descrição


indica se o jogo deve ser iniciado ou
state boolean 1 ou 0 interrompido: 1 significa "iniciar jogo",
0 significa "parar jogo"
o número de jogador do jogador local,
deve ser o menor número de jogadores
playernum integer 1 − 6
entre os jogadores no servidor para que
esta mensagem funcione

4.3.2 Atualização de Campo

Ver atualização de campos

4.3.3 Atualização de nı́vel

lvl <playernum> <levelnum>

Enviado quando o jogador local atinge um nı́vel mais alto no jogo, o


que ocorre quando o jogador local completa um certo número de linhas,
especificado na string de regras quando o jogo inı́cia.

C. Fernando, et al. Informational [Page 22]


RFC 20191 TetriNet April 2019

argumentos tipos valores descrição


playernum integer 1 − 6 o número de jogador do jogador local
levelnum integer o novo nı́vel de jogo do jogador local

4.3.4 Enviar Especial

sb <targetnum> <specialtype> <sendernum>

Enviado quando o jogador local usa um especial em outro jogador

argumentos tipo valores descrição


o jogador escolhido pelo jogador
targetnum integer 1 − 6
local para receber o especial
a, b, c, g, n, o tipo de especial usado (ver
specialtype char
o, q, r ou s blocos especiais)
sendernum integer 1 − 6 o número do jogador do jogador local

4.3.5 Enviar Linhas de Adição de Estilo Clássico

sb 0 cs<numlines> <sendernum>

(Uma pequena variação da mensagem "Enviar especial", acima.)


Enviado quando o player local completa várias linhas simultaneamente
em um jogo com o "modo clássico"ativado (consulte a nova string
de regras do jogo), acionando um acréscimo no estilo clássico. O
campo targetnum da mensagem deve ser sempre 0, uma vez que o estilo
clássico adiciona todos os players, exceto o remetente.

argumentos tipo valores descrição


o número de linhas adicionadas aos campos
numlines char 1, 2 ou 4 de outros jogadores, veja
os acréscimos no estilo clássico
sendernum integer 1 − 6 o número do jogador do jogador local

4.3.6 Jogador Eliminado

playerlost <playernum>

Enviado quando o jogador local perde o jogo, isto é, quando o seu campo
está cheio ao ponto que o bloco seguinte não pode ser movido para ele.

Observação de implementação: alguns servidores (Jetrix, por exemplo)


esperam que o cliente envie um "campo de morte"preenchido aleatoriamente
(por meio de uma mensagem de atualização de campo) após o jogador
perder, mas antes de enviar a mensagem "playerlost".

argumentos tipo valores descrição


playernum integer 1 − 6 o número do jogador do jogador local

C. Fernando, et al. Informational [Page 23]


RFC 20191 TetriNet April 2019

4.3.7 Pausar e Retomar Jogo

pause <state> <playernum>

Usado para pausar ou retomar um jogo em andamento. Como a mensagem


Iniciar / Parar Jogo, os servidores só responderão a esta mensagem
se ela for enviada pelo operador do canal.

argumentos tipo valores descrição


indica se o jogo deve ser pausado ou
state boolean 1 ou 0 retomado: 1 significa "pausa", 0
significa "retomar"
o número de jogador do jogador local,
deve ser o menor número de jogadores
playernum integer 1 − 6
entre os jogadores no servidor para que
esta mensagem funcione

C. Fernando, et al. Informational [Page 24]


RFC 20191 TetriNet April 2019

5 Atualização de Campos
A mensagem de atualização de campo, que é idêntica para as versões de servidor
para cliente e de cliente para servidor, possui o seguinte formato:

f <playernum> <fieldstring>

arguments type values meaning


o número do jogador a quem
playernum integer 1 − 6
a atualização de campo se aplica
o conteúdo do campo do jogador,
fieldstring string see below
ou uma atualização parcial de campo

O segundo argumento vem em duas formas. A forma mais longa, mas mais simples,
é chamada de \fieldstring", que consiste em 264 (12 * 22) caracteres, cada um
representando uma única célula no campo, indexados da esquerda para a direita e
depois de cima para baixo, começando com o canto superior esquerdo do campo. Um
example de fieldstring:
0000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000005
10000000055511101000a555511010005555a5101022r525521010225222c22

Os números representam células coloridas normais (com os zeros sendo espaço vazio)
enquanto as letras (que sempre serão minúsculas) representam blocos especiais.
A segunda forma mais curta de atualização de campo é uma atualização parcial:
#8F7G8G9G O primeiro caractere de uma atualização de campo parcial está no
intervalo de ASCII 0x21 a 0x2F, inclusive. Estes valores correspondem a uma cor
de célula ou tipo de bloco especial:

Caracter Valor ASCII tipo de célula


! 0x21 / 33 vazia
" 0x22 / 34 célula azul
# 0x23 / 35 célula amarela
$ 0x24 / 36 célula verde
% 0x25 / 37 célula roxa
& 0x26 / 38 célula vermelha
’ 0x27 / 39 adicionar linha
( 0x28 / 40 limpar linha
) 0x29 / 41 campo de nuke
* 0x2A / 42 limpar aleatório
+ 0x2B / 43 mudar de campo
, 0x2C / 44 limpar especiais
- 0x2D / 45 gravidade
. 0x2E / 46 campo de terremoto
/ 0x2F / 47 bloco bomba

C. Fernando, et al. Informational [Page 25]


RFC 20191 TetriNet April 2019

Uma atualização parcial pode conter mais de um dos caracteres nesta lista e
sempre conterá um deles como o primeiro caractere

Caracteres diferentes deles correspondem a coordenadas no tabuleiro, indexadas


em ordem de linha de coluna, da esquerda para a direita e de cima para baixo,
com o caractere ASCII ’3’ (0x33, decimal 51) representando 0, e caracteres com
valores ASCII mais altos representando ı́ndices mais altos.

Para aplicar uma atualização parcial a um campo, basta preencher a célula em


cada par de coordenadas com o último tipo de célula encontrado na string.

C. Fernando, et al. Informational [Page 26]

Das könnte Ihnen auch gefallen