-
Notifications
You must be signed in to change notification settings - Fork 0
/
servidor
executable file
·151 lines (127 loc) · 6.65 KB
/
servidor
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
#!/usr/bin/env python3
import asyncio
import re
import sys
from tcp import Servidor
from pprint import pprint
from ast import literal_eval
DEBUG = 1
#if sys.platform == 'win32': asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
def log(*args, **kwargs):
if DEBUG: pprint(*args, **kwargs)
def validar_nome(nome):
return re.match(br'^[a-zA-Z][a-zA-Z0-9_-]*$', nome) is not None
def sair(conexao):
addresseeList = []
#for each channel in servidor
for channel in servidor.chan_db:
servidor.chan_db[channel].pop(conexao.nick, None)
for i in servidor.chan_db[channel]:
addresseeList.append(servidor.chan_db[channel][i])
for j in addresseeList:
print(b':'+conexao.nick + b' QUIT' + b' :Connection closed\r\n')
print(j)
servidor.nick_db.pop(conexao.nick, None)
j.enviar(b':'+conexao.nick + b' QUIT' + b' :Connection closed\r\n')
print(conexao, 'conexão fechada')
conexao.fechar()
def dados_recebidos(conexao, dados):
dados = conexao.dados_residuais + dados
conexao.dados_residuais = b''
if dados == b'':
return sair(conexao)
print(conexao, dados)
#PASSO 2:
if not dados.endswith(b'\r\n'):
#if the string does not ends with \r\n it means that the remainning caracters must be used in the next instruction
dados = list(filter((b'').__ne__, dados.split(b'\r\n')))
conexao.dados_residuais += dados.pop(-1)
else:
dados = list(filter((b'').__ne__, dados.split(b'\r\n')))
for data in dados:
command, payload = data.split(b' ', 1)
#PASSO 1:
if command.upper() == b'PING':
conexao.enviar(b':server PONG server :' + payload + b'\r\n')
#PASSO 3 e 4:
if command.upper() == b'NICK':
pUpper = payload.upper()
if validar_nome(payload):
if conexao in servidor.nick_db.values():
oldNick = list(servidor.nick_db.keys())[list(servidor.nick_db.values()).index(conexao)]
if pUpper not in (upp.upper() for upp in list(servidor.nick_db.keys())):
servidor.nick_db[payload] = conexao
del servidor.nick_db[oldNick]
conexao.nick = payload
conexao.enviar(b':'+ oldNick + b' NICK '+ payload +b'\r\n')
else:
conexao.enviar(b':server 433 '+ oldNick + b' ' + payload + b' :Nickname is already in use\r\n')
else:
if pUpper not in (upp.upper() for upp in list(servidor.nick_db.keys())):
servidor.nick_db[payload] = conexao
conexao.nick = payload
conexao.enviar(b':server 001 ' + payload + b' :Welcome\r\n')
conexao.enviar(b':server 422 ' + payload + b' :MOTD File is missing\r\n')
else:
conexao.enviar(b':server 433 * ' + payload + b' :Nickname is already in use\r\n')
else:
conexao.enviar(b':server 432 * ' + payload + b' :Erroneous nickname\r\n')
#PASSO 5:
if command.upper() == b'PRIVMSG':
destination, content = payload.split(b' :', 1)
remetenteNick = list(servidor.nick_db.keys())[list(servidor.nick_db.values()).index(conexao)]
dUpper = destination.upper()
if destination.startswith(b'#') and dUpper in servidor.chan_db.keys():
for i in servidor.chan_db[dUpper]:
if servidor.chan_db[dUpper][i] != conexao:
servidor.chan_db[dUpper][i].enviar(b':' + remetenteNick + b' PRIVMSG ' + destination + b' :' + content + b'\r\n')
else:
destinationConnection = None
for i in servidor.conn_db:
if list(servidor.nick_db.keys())[list(servidor.nick_db.values()).index(i)].upper() == dUpper:
destinationConnection = i
if destinationConnection != None:
destinationConnectionNick = list(servidor.nick_db.keys())[list(servidor.nick_db.values()).index(destinationConnection)]
destinationConnection.enviar(b':' + remetenteNick + b' PRIVMSG ' + destinationConnectionNick + b' :' + content + b'\r\n')
#PASSO 6:
if command.upper() == b'JOIN':
if payload.startswith(b'#') and validar_nome(payload[1:]):
pUpper = payload.upper()
connectionNick = list(servidor.nick_db.keys())[list(servidor.nick_db.values()).index(conexao)]
if pUpper not in (upp.upper() for upp in list(servidor.chan_db.keys())):
servidor.chan_db[pUpper] = dict()
servidor.chan_db[pUpper][connectionNick] = conexao
for i in servidor.chan_db[pUpper]:
servidor.chan_db[pUpper][i].enviar(b':' + connectionNick + b' JOIN :' + payload + b'\r\n')
members = b''
for i in sorted(servidor.chan_db[pUpper].keys()):
members += i + b' '
send = b':server 353 ' + connectionNick + b' = ' + payload + b' :' + members
while len(send) > 510: # len('\r\n') = 2
residuals = send[:510]
conexao.enviar(send + b'\r\n')
send = residuals
conexao.enviar(send + b'\r\n' + b':server 366 ' + connectionNick + b' ' + payload + b' :End of /NAMES list.\r\n')
#PASSO 7:
if command.upper() == b'PART':
pIgnored = payload.split(b' ')[0]
pUpper = payload.split(b' ')[0].upper() #channel name, suposed to be a servidor.chan_db.key
if pUpper.startswith(b'#') and pUpper in servidor.chan_db.keys():
connectionNick = list(servidor.nick_db.keys())[list(servidor.nick_db.values()).index(conexao)]
if connectionNick in servidor.chan_db[pUpper].keys():
for i in servidor.chan_db[pUpper]:
servidor.chan_db[pUpper][i].enviar(b':' + connectionNick + b' PART ' + pIgnored + b'\r\n')
del servidor.chan_db[pUpper][connectionNick]
def conexao_aceita(conexao):
print(conexao, 'nova conexão')
servidor.conn_db.append(conexao)
conexao.dados_residuais = b''
conexao.nick = b''
conexao.registrar_recebedor(dados_recebidos)
servidor = Servidor(6667)
servidor.nick_db = dict()
servidor.chan_db = dict()#key: channelName, value: tcp.Conexao
servidor.conn_db = list()
servidor.registrar_monitor_de_conexoes_aceitas(conexao_aceita)
asyncio.get_event_loop().run_forever()
print(servidor.chan_db)