Advertisement
Guest User

Untitled

a guest
Jul 3rd, 2016
139
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.22 KB | None | 0 0
  1. from tornado import websocket, web, ioloop
  2. from tornado.ioloop import PeriodicCallback
  3. import json
  4. import time
  5. import re
  6. import gc
  7. import sys
  8.  
  9. INTRO_FILE = "intro.txt"
  10. PING_INTERVAL = 10.0
  11. default_room = "#default"
  12. rooms = {}
  13. bannedip = {}
  14. nicknames ={}
  15. clients = {}
  16. bots = {}
  17.  
  18. def print_stat():
  19. for room in rooms:
  20. print "ROOM:",rooms[room].name,rooms[room].users
  21.  
  22. def process_message(user,msg): #xss protecton
  23. if "script" in msg.lower() and "<" in msg and ">" in msg:
  24. MainServer.raw_to_user(user,"WARNING:XSS not allowed!")
  25. msg = msg.replace("<","&lt")
  26. msg = msg.replace(">","&gt")
  27. return msg
  28.  
  29.  
  30. class Room:
  31.  
  32. #Test for name integrity and create empty room
  33. def __init__(self,name):
  34. if re.match("^#[A-Za-z0-9_-]+$",name):
  35. self.name = name
  36. self.users = {}
  37. print "Room %s is beeing made!"%name
  38. else:
  39. raise ValueError("The room name is not correctly formatted!")
  40.  
  41. def join_room(self,user):
  42. if user.ron == True and user.nickname not in self.users :
  43. MainServer.raw_to_user(user,"JOINED:%s"%self.name)
  44. user.raw_message("%s:USERS:%s"%(self.name,json.dumps([u.nickname for u in self.users.values()])))
  45. self.users[user.nickname] = user
  46. for key in self.users: #let everyone in room know
  47. self.users[key].raw_message("%s:ADDUSR:%s"%(self.name,user.nickname))
  48. return True
  49. else:
  50. user.raw_message("WARNING:Already in a room")
  51. return False
  52.  
  53. def leave_room(self,user,socket_closed=False):
  54. if user.nickname in self.users:
  55. if not socket_closed:
  56. MainServer.raw_to_user(user,"LEFT:%s"%self.name)
  57. del self.users[user.nickname]
  58. for i in self.users:
  59. self.users[i].raw_message("%s:REMUSR:%s"%(self.name,user.nickname))
  60. return True
  61. else:
  62. if not socket_closed:
  63. user.raw_message("WARNING:Not in room.." )
  64. return False
  65. #Send all users message from one of them.
  66. def user_message(self,user,msg):
  67. for client in self.users:
  68. self.users[client].raw_message("%s:MSG:<n> %s </n> : <msg> %s </msg>"%(self.name,user.nickname,msg))
  69.  
  70. #Send all users message as is (ussualy used by server routines)
  71. def raw_message(self,msg):
  72. for client in self.users:
  73. self.users[client].raw_message(msg)
  74.  
  75.  
  76. class NickServ:
  77.  
  78. return_info = {
  79. "nickname_changed":"NICKSERV:STAT:NICK_CHANGED:%s:%s",
  80. "nickname_exists":["NICKSERV:STAT:NICK_EXISTS:%s","WARNING:Nickname %s vec postoji"],
  81. "formatting_error":"WARNING:Nickname ne moze biti tako formatiran"
  82. }
  83.  
  84. @staticmethod
  85. def nick_change(user,new_nick):
  86. global clients
  87. old_nick = user.nickname.lower()
  88. if not new_nick.lower() in nicknames and re.match("^[A-Za-z0-9_-]+$",new_nick):
  89. NickServ.nick_unset(old_nick)
  90. user.nickname=new_nick
  91. NickServ.nick_set(new_nick,user)
  92. if user.ron:
  93. MainServer.broadcast_raw_message(clients.values(),NickServ.return_info["nickname_changed"]%(old_nick,new_nick))
  94. return True
  95. else:
  96. if new_nick.lower() in nicknames:
  97. MainServer.raw_to_user(user,NickServ.return_info["nickname_exists"][0]%new_nick)
  98. else:
  99. MainServer.raw_to_user(user,NickServ.return_info["formatting_error"])
  100. return False
  101.  
  102. @staticmethod
  103. def nick_unset(nick):
  104. nick = nick.lower().strip()
  105. if nick in nicknames:
  106. del nicknames[nick]
  107.  
  108. @staticmethod
  109. def nick_set(nick,user):
  110. nicknames[nick.lower().strip()] = user
  111.  
  112.  
  113. class RoomServ:
  114.  
  115. name = "ROOM_SERV"
  116.  
  117. @staticmethod
  118. def join_user(user,room_name):
  119. global rooms
  120. room = None
  121. if room_name not in rooms:
  122. try:
  123. room = Room(room_name)
  124. rooms[room_name] = room
  125. except ValueError , e:
  126. MainServer.raw_to_user(user,"WARNING:%s"%str(e))
  127. return
  128. else:
  129. room = rooms[room_name]
  130. user.rooms.append(room)
  131. room.join_room(user)
  132.  
  133. #Check for room exsistance before leaving it
  134. @staticmethod
  135. def leave_user(user,room_name,closed):
  136. if room_name in rooms:
  137. rooms[room_name].leave_room(user,closed)
  138. else:
  139. MainServer.raw_to_user(user,"WARNING:Ta soba ne postoji..")
  140.  
  141.  
  142. class UserServ:
  143.  
  144. #Remove user from chat and do the cleanup
  145. @staticmethod
  146. def disconnected(socket):
  147. print "DISCONNECTED CALLED"
  148. if socket in clients:
  149. user = clients[socket]
  150. print "Client %s removed."%(user.nickname)
  151. user.leaveAllRooms()
  152. NickServ.nick_unset(user.nickname)
  153. print "NICKNAMES : "+str(nicknames)+"\n"
  154. del clients[socket]
  155. print "REFERENCES : %s \n"%gc.get_referrers(user)
  156. print "CLIENTS : %s \n"%clients
  157. #else:
  158. # print "Socket refferers:%s"%gc.get_referrers(socket)
  159. print_stat()
  160.  
  161. class MainServer:
  162.  
  163. @staticmethod
  164. def raw_to_user(user,msg):
  165. user.raw_message(msg)
  166.  
  167. @staticmethod
  168. def broadcast_raw_message(client_list,msg):
  169. for client in client_list:
  170. if client.ron:
  171. client.raw_message(msg)
  172.  
  173. #Send intro file to client
  174. @staticmethod
  175. def intro(user,file):
  176. with open(file) as f:
  177. for line in f:
  178. user.raw_message("MSG:%s"%line)
  179.  
  180. @staticmethod
  181. def register_user(user,nickname):
  182. if NickServ.nick_change(user,nickname):
  183. user.raw_message("R_O_N:%s"%user.nickname)
  184. MainServer.intro(user,INTRO_FILE)
  185. user.ron = True
  186. #print "User joined chat with nickname : %s and ip : %s"%(self.nickname,self.ip)
  187. RoomServ.join_user(user,default_room)
  188.  
  189.  
  190. class User:
  191.  
  192. nickname = ""
  193. rooms = []
  194. socket = None
  195. ron = False
  196. ip = ""
  197. timeout = 0
  198. callback = None
  199.  
  200. def __init__(self,socket):
  201. self.socket = socket
  202. self.ip = str(socket.request.remote_ip)
  203. def leaveAllRooms(self):
  204. for room in list(self.rooms):
  205. if room.leave_room(self,True) == False:
  206. break
  207. else:
  208. self.rooms.remove(room)
  209. else:
  210. print "We're stuck.."
  211.  
  212. def raw_message(self,msg):
  213. try:
  214. self.socket.write_message(msg)
  215. except:
  216. print "Connection lost %s"%self.nickname
  217. UserServ.disconnected(self.socket)
  218. print "OBJECT : "%self
  219.  
  220. def destroy_client(self, code,reason):
  221. self.socket.close(code,reason)
  222.  
  223. '''
  224. If client is not registered message in form
  225. "nick:user_nickname" must be recived to initialize
  226. chat, othrewise parse the message in form
  227. "msg: " + additional params splitted with :
  228. "command: " + -||-
  229. '''
  230. def message_recived(self,msg):
  231. #parse and route messages
  232.  
  233. msg = process_message(self,msg)
  234. print "%s : %s"%(self.nickname,msg)
  235. if not self.ron:
  236. nickname_info = msg.split(":")
  237. if nickname_info[0].strip().lower() == "nick":
  238. nickname = nickname_info[1]
  239. MainServer.register_user(self,nickname)
  240. else:
  241. self.destroy_client(1008,"First 'nick:your_nickname' command must be sent.")
  242. else:
  243. msg_info = msg.split(":",1)
  244. if msg_info[0].lower() == "msg":
  245. msg_info = msg_info[1].split(":",1)
  246. if len(msg_info) == 2:
  247. msg = msg_info[1].strip()
  248. if msg_info[0].strip().startswith("#"):
  249. room = msg_info[0].strip()
  250. if room in rooms.keys():
  251. rooms[room].user_message(self,msg)
  252. else:
  253. receiver = msg_info[0].strip().lower()
  254. if receiver in nicknames:
  255. nicknames[receiver].user_message(self,msg)
  256. if msg_info[0].lower() == "command":
  257. msg_info = msg_info[1].split(" ")
  258. if len(msg_info)>1:
  259. if msg_info[0].lower() == "nick":
  260. NickServ.nick_change(self,msg_info[1])
  261. elif msg_info[0].lower() == "join":
  262. room_name = msg_info[1].lower()
  263. RoomServ.join_user(self,room_name)
  264. elif msg_info[0].lower() == "leave":
  265. room_name = msg_info[1].lower()
  266. RoomServ.leave_user(self,room_name,False)
  267. else:
  268. pass
  269. elif len(msg_info)==1:
  270. MainServer.raw_to_user(self,"WARNING:Not yet implemented...")
  271.  
  272.  
  273. def user_message(self,user,message):
  274. self.raw_message("USER:%s:MSG:%s"%(user.nickname,message))
  275.  
  276. def __del__(self):
  277. print "Deleted user %s"%self.nickname
  278.  
  279.  
  280. class SocketHandler(websocket.WebSocketHandler):
  281. def check_origin(self, origin):
  282. return True
  283.  
  284. def open(self):
  285. self.set_nodelay(True)
  286. if not self in clients:
  287. clients[self] = User(self)
  288. #clients[self].callback = PeriodicCallback(clients[self].keepalive,1000);
  289. #clients[self].callback.start()
  290. else:
  291. print "You're here..."
  292.  
  293. def on_close(self):
  294. if self:
  295. UserServ.disconnected(self)
  296. print "Client list after close event %s"%clients.keys()
  297.  
  298. def on_message(self,message):
  299. if self in clients:
  300. clients[self].message_recived(message.encode("utf-8"))
  301.  
  302. app = web.Application([
  303. (r'/', SocketHandler),
  304. ])
  305.  
  306. rooms[default_room] = Room(default_room)
  307.  
  308. if __name__ == '__main__':
  309. app.listen(5000)
  310. ioloop.IOLoop.instance().start()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement