コード例 #1
0
	def ping(self, server, relposinlist=0.0):
		destport = server.port+1
		# server must already have been pinged and must have sent a reply which is less time ago than EXTINFO_TIMEOUT
		extinfotimeout = (server.lastping and server.lastreply and ((self.t-server.lastreply) < servercommunicator.EXTINFO_TIMEOUT) and ((self.t-server.lastping) < servercommunicator.EXTINFO_TIMEOUT) and ((not server.lastextinforeply) or ((self.t-server.lastextinforeply) > servercommunicator.EXTINFO_TIMEOUT)))
		
		#TODO
		if server.lastping and server.lastreply:
			print(	server.lastping,
				server.lastreply,
				(self.t-server.lastreply) < servercommunicator.EXTINFO_TIMEOUT,
				(self.t-server.lastping) < servercommunicator.EXTINFO_TIMEOUT,
				((not server.lastextinforeply) or ((self.t-server.lastextinforeply) > servercommunicator.EXTINFO_TIMEOUT))
			)
		else:
			print(server.lastping, server.lastreply)
		
		tryaltextinfo = (not extinfotimeout) if server.usealtextinfo else extinfotimeout
		debug.msg(servercommunicator.DBGTAG_PING, "pinging server at %s:%d%s (sending packets to port %d)" % (server.host, server.port, ((", %sreached extinfo timeout, using %s extinfo request" % ("" if extinfotimeout else "not ", "alternative" if tryaltextinfo else "standard")) if (extinfotimeout or server.usealtextinfo or tryaltextinfo) else ""), destport))
		if server.lastreply != None and server.lastping != None and server.lastreply > server.lastping: # this is the first ping after a reply has been received
			server.pings = 1
		else:
			server.pings += 1
		if not server.firstping: server.firstping = self.t
		server.lastping = self.t
		server.nextping = server.lastping + (config.PING_INTERVAL * (1 + (0 if server.quicktest else (relposinlist * config.PING_SPREADRATIO))))
		self.packetqueue.append(packet.pingpacket((server.host, destport)))
		if tryaltextinfo:
			# reached standard-extinfo timeout, try with alternative extinfo request
			self.packetqueue.append(packet.altextinfopacket((server.host, destport)))
		else:
			# standard-extinfo timeout has not been reached, proceed with standard extinfo request
			self.packetqueue.append(packet.extinfopacket((server.host, destport)))
コード例 #2
0
ファイル: netserver.py プロジェクト: xthirtyfive/gamemod
	def run(self, funcs):
		sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
		sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
		sock.bind((self.addr, self.port))
		sock.listen(5)
		
		while True:
			try:
				i = sock.accept()
				
				if self.accesscache.permit(i[1][0]):
					tt = threading.Thread(target=self.processconnection, args=(i, funcs))
					tt.start()
					
				else: # connection not permitted by accesscache
					debug.msg(netserver.DBGTAG_REJECT, "rejecting connection from %s:%d (not permitted by accesscache)" % i[1])
					try:
						i[0].shutdown(socket.SHUT_RDWR)
					except: pass
					try:
						i[0].close()
					except: pass
					
			except:
				debug.exc(self)
コード例 #3
0
    def run(self, funcs):
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        sock.bind((self.addr, self.port))
        sock.listen(5)

        while True:
            try:
                i = sock.accept()

                if self.accesscache.permit(i[1][0]):
                    tt = threading.Thread(target=self.processconnection,
                                          args=(i, funcs))
                    tt.start()

                else:  # connection not permitted by accesscache
                    debug.msg(
                        netserver.DBGTAG_REJECT,
                        "rejecting connection from %s:%d (not permitted by accesscache)"
                        % i[1])
                    try:
                        i[0].shutdown(socket.SHUT_RDWR)
                    except:
                        pass
                    try:
                        i[0].close()
                    except:
                        pass

            except:
                debug.exc(self)
コード例 #4
0
ファイル: server.py プロジェクト: xthirtyfive/gamemod
	def readinfo(self, buf):
		try:
			numclients_ = buf.getint()
			attrs_ = buf.getint()
			if attrs_ != 5: return False, "attrs is not 5"
			version_ = buf.getint()
			gamemode_ = buf.getint()
			remaining_ = buf.getint() # TODO: switch protocol versions (in sooner versions, remaining_ is in minutes)
			maxclients_ = buf.getint()
			mastermode_ = buf.getint()
			map_ = buf.getstring()
			desc_ = buf.getstring()
		except EndOfBufError:
			return False, "end of buf unexpectedly reached"
		
		debug.msg(server.DBGTAG_READINFO, "%s:%d: numclients=%d, attrs=%d, version=%d, gamemode=%d, remaining=%d, maxclients=%d, mastermode=%d, map=\"%s\", desc=\"%s\""
			% (self.host, self.port, numclients_, attrs_, version_, gamemode_, remaining_, maxclients_, mastermode_, map_, desc_))
			
		self.numclients = numclients_
		self.version = version_
		self.gamemode = gamemode_
		self.remaining = remaining_
		self.maxclients = maxclients_
		self.mastermode = mastermode_
		self.map = map_
		self.desc = tools.safe(desc_)
		
		return True, ""
コード例 #5
0
 def pingservers(self):
     kicklist = []
     for name in self.lists:
         clist = self.lists[name]
         total = float(clist.len())
         n = 0.0
         for server in clist.releasingiterator():
             if (
                 (not server.persistent) or name != self.pendingservers_key
             ) and server.lastping != None and server.nextping != None and server.nextping < self.t and (
                     server.lastreply == None or server.lastreply <
                     server.lastping) and server.pings >= (
                         1 if server.quicktest else config.PINGS_GIVEUP):
                 # server is either not persistent or is not in pending servers list (it will be added there) has been pinged once or more, time is reached for a new ping, but the number of pings before giving up is exceeded. kick server.
                 kicklist.append(server)
             elif server.nextping == None or server.nextping < self.t:
                 # last ping has been too long ago, or server was never pinged. ping it.
                 self.ping(server, n / total)
             n += 1
         if len(kicklist) > 0:
             debug.msg(
                 servercommunicator.DBGTAG_KICK,
                 "kicking out %d servers from %s list" %
                 (len(kicklist), name))
             for server in kicklist:
                 self.kick(clist, name, server)
             del kicklist[:]
コード例 #6
0
ファイル: server.py プロジェクト: xthirtyfive/gamemod
	def readextinfo(self, buf):
		try:
			ack_ = buf.getint()
			if ack_ != packet.EXT_ACK: return False, "EXT_ACK (%d) expected, got %d instead" % (packet.EXT_ACK, ack_)
			version_ = buf.getint()
			if version_ != packet.EXT_VERSION: return False, "received unknown extinfo version %d" % version_
			error_ = buf.getint()
			if error_ != packet.EXT_NO_ERROR: return False, "extinfo request contains errors, expected EXT_NO_ERROR (%d), got %d instead" % (packet.EXT_NO_ERROR, error_)
		
			content_ = buf.getint()
			if content_ == packet.EXT_PLAYERSTATS_RESP_IDS:
				e = debug.tagenabled(server.DBGTAG_CLIENTCNSDUMP)
				if e:
					s = ""
					n = 0
				while buf.available():
					cn = buf.getint()
					self.clients.keep(cn) # keep this player
					if e:
						s += " " + str(cn)
						n += 1
				self.clients.keep() # remove players not called keep() on
				if e:
					debug.msg(server.DBGTAG_CLIENTCNSDUMP, "%s:%d: received %d cns:%s" % (self.host, self.port, n, s))
				
			elif content_ == packet.EXT_PLAYERSTATS_RESP_STATS:
				cn = buf.getint()
				ping = buf.getint()
				name = buf.getstring()
				team = buf.getstring()
				frags = buf.getint()
				flags = buf.getint()
				deaths = buf.getint()
				teamkills = buf.getint()
				damage = buf.getint()
				health = buf.getint()
				armour = buf.getint()
				gunselect = buf.getint()
				priv = buf.getint()
				state = buf.getint()
				ip = (buf.read(), buf.read(), buf.read())
				
				c = self.clients.get(cn)
				c.name = name
				c.team = team
				c.frags = frags
				c.flags = flags
				c.priv = priv
				c.state = state
				c.ip = ip
				
				if debug.tagenabled(server.DBGTAG_CLIENTDUMP):
					debug.msg(server.DBGTAG_CLIENTDUMP, "%s:%d: received client: cn=%d, name=\"%s\", team=\"%s\", frags=%d, flags=%d, priv=%d, ip=%d.%d.%d.x" % ((self.host, self.port, cn, name, team, frags, flags, priv)+ip))
			else:
				return False, "invalid content type, expected EXT_PLAYERSTATS_RESP_IDS (%d) or EXT_PLAYERSTATS_RESP_STATS (%d), got %d instead" % (packet.EXT_PLAYERSTATS_RESP_IDS, packet.EXT_PLAYERSTATS_RESP_STATS, content_)
				
		except EndOfBufError:
			return False, "end of buf unexpectedly reached"
		
		return True, ""
コード例 #7
0
 def processdata(self, p):
     debug.msg(servercommunicator.DBGTAG_RECV,
               "received %d bytes from %s:%d" % ((len(p.data), ) + p.addr))
     host = p.addr[0]
     servport = p.addr[1] - 1
     plist = self.lists[self.pendingservers_key]
     s = plist.find(host, servport)
     if s:
         # server from pending servers list has replied, move it to registered servers list
         rlist = self.lists[self.registeredservers_key]
         self.register(s, rlist, plist)
     else:
         # sender is not in pending servers list, look through other lists
         for name in self.lists:
             if name == self.pendingservers_key: continue
             clist = self.lists[name]
             s = clist.find(host, servport)
             if s: break
         if not s:  #if no server was found in any list, return.
             debug.msg(
                 servercommunicator.DBGTAG_UNKNOWNSERVER,
                 "received %d bytes from an unknown server at %s:%d (packet sent from port %d)"
                 % (len(p.data), host, servport, p.addr[1]))
             return
             # TODO maybe add the server directly, even though it did not announce itself via regserv command?
     s.lastreply = self.t
     s.read(
         buf(p.data), self.t
     )  # hand over current time (self.t) so server can set s.lastextinforeply if this is extinfo
コード例 #8
0
	def kick(self, clist, name, server):
		debug.msg(servercommunicator.DBGTAG_MOVESERVER if server.persistent else servercommunicator.DBGTAG_KICKSERVER, "%s server at %s:%d from %s list%s (first ping: %s, last ping: %s, last reply: %s)" % ("moving persistent" if server.persistent else "kicking out", server.host, server.port, name, (" to %s list" % self.pendingservers_key) if server.persistent else "", ("never" if server.firstping == None else ("%f seconds ago" % (self.t-server.firstping))), ("never" if server.lastping == None else ("%f seconds ago" % (self.t-server.lastping))), ("never" if server.lastreply == None else ("%f seconds ago" % (self.t-server.lastreply)))))
		clist.remove(server)
		if server.persistent:
			self.lists[self.pendingservers_key].append_once(server)
		else:
			server.onremove()
コード例 #9
0
 def updatefrommaster(self):
     s = self.connect()
     s.send("list\n")
     self.fetch(s)
     s.close()
     debug.msg(masterclient.DBGTAG_FETCHED,
               "fetched %d servers from master" % self.list.len())
コード例 #10
0
 def append_once(self, server):
     if not self.exists(server):
         if not self._isbanned(server):
             self._append(server)
         else:
             debug.msg(
                 serverlist.DBGTAG_REFUSED,
                 "refused a banned server at %s:%d" %
                 (server.host, server.port))
コード例 #11
0
 def register(self, server, rlist, plist):
     plist.removeall(server)
     rlist.append_once(server)
     debug.msg(
         servercommunicator.DBGTAG_SUCCREG,
         "registration of server %s:%d successful" %
         (server.host, server.port))
     server.quicktest = False
     server.onregister()
コード例 #12
0
    def ping(self, server, relposinlist=0.0):
        destport = server.port + 1
        # server must already have been pinged and must have sent a reply which is less time ago than EXTINFO_TIMEOUT
        extinfotimeout = (
            server.lastping and server.lastreply and
            ((self.t - server.lastreply) < servercommunicator.EXTINFO_TIMEOUT)
            and
            ((self.t - server.lastping) < servercommunicator.EXTINFO_TIMEOUT)
            and ((not server.lastextinforeply) or
                 ((self.t - server.lastextinforeply) >
                  servercommunicator.EXTINFO_TIMEOUT)))

        #TODO
        if server.lastping and server.lastreply:
            print(server.lastping, server.lastreply,
                  (self.t - server.lastreply) <
                  servercommunicator.EXTINFO_TIMEOUT,
                  (self.t - server.lastping) <
                  servercommunicator.EXTINFO_TIMEOUT,
                  ((not server.lastextinforeply) or
                   ((self.t - server.lastextinforeply) >
                    servercommunicator.EXTINFO_TIMEOUT)))
        else:
            print(server.lastping, server.lastreply)

        tryaltextinfo = (
            not extinfotimeout) if server.usealtextinfo else extinfotimeout
        debug.msg(
            servercommunicator.DBGTAG_PING,
            "pinging server at %s:%d%s (sending packets to port %d)" %
            (server.host, server.port,
             ((", %sreached extinfo timeout, using %s extinfo request" %
               ("" if extinfotimeout else "not ",
                "alternative" if tryaltextinfo else "standard")) if
              (extinfotimeout or server.usealtextinfo
               or tryaltextinfo) else ""), destport))
        if server.lastreply != None and server.lastping != None and server.lastreply > server.lastping:  # this is the first ping after a reply has been received
            server.pings = 1
        else:
            server.pings += 1
        if not server.firstping: server.firstping = self.t
        server.lastping = self.t
        server.nextping = server.lastping + (
            config.PING_INTERVAL *
            (1 + (0 if server.quicktest else
                  (relposinlist * config.PING_SPREADRATIO))))
        self.packetqueue.append(packet.pingpacket((server.host, destport)))
        if tryaltextinfo:
            # reached standard-extinfo timeout, try with alternative extinfo request
            self.packetqueue.append(
                packet.altextinfopacket((server.host, destport)))
        else:
            # standard-extinfo timeout has not been reached, proceed with standard extinfo request
            self.packetqueue.append(
                packet.extinfopacket((server.host, destport)))
コード例 #13
0
	def __str__(self, *args):
		s = ""
		for p in self.parts:
			if type(p) == types.StringType:
				s += p
			else:
				try:
					s += p.__str__(*args)
				except:
					debug.msg(guiline.DBGTAG_STRPARTERROR, "was getting string from guicommand: %s (re-raising this exception)" % repr(p))
					raise
		return s
コード例 #14
0
ファイル: masterclient.py プロジェクト: xthirtyfive/gamemod
	def processline(self, line):
		if line[:len(masterclient.ADDSERVER_COMMAND)] != masterclient.ADDSERVER_COMMAND:
			debug.msg(masterclient.DBGTAG_INVALID, "received invalid line from master, does not start with \"%s\": %s" % (masterclient.ADDSERVER_COMMAND, line))
			return
		a = line[len(masterclient.ADDSERVER_COMMAND)+1:]
		p = a.split(" ")
		if len(p) < 2:
			debug.msg(masterclient.DBGTAG_INVALID, "received invalid line from master, does not contain 2 arguments: %s" % line)
			return
		host = p[0]
		port = int(p[1])
		self.list.add_from_master(host, port)
コード例 #15
0
ファイル: serverlist.py プロジェクト: xthirtyfive/gamemod
	def check(self):
		if not self.banned: return
		dellist = []
		for s in self.list.iterator():
			if self._isbanned(s):
				dellist.append(s)
		if len(dellist):
			debug.msg(serverlist.DBGTAG_DELBANNEDSERVERS, "removing %d banned servers" % len(dellist))
			for s in dellist:
				debug.msg(serverlist.DBGTAG_DELBANNED, "removing banned server at %s:%d" % (s.host, s.port))
				self.remove(s)
				s.onremove()
コード例 #16
0
 def check(self):
     if not self.banned: return
     dellist = []
     for s in self.list.iterator():
         if self._isbanned(s):
             dellist.append(s)
     if len(dellist):
         debug.msg(serverlist.DBGTAG_DELBANNEDSERVERS,
                   "removing %d banned servers" % len(dellist))
         for s in dellist:
             debug.msg(serverlist.DBGTAG_DELBANNED,
                       "removing banned server at %s:%d" % (s.host, s.port))
             self.remove(s)
             s.onremove()
コード例 #17
0
ファイル: gamemod.py プロジェクト: xthirtyfive/gamemod
def main():
	debug.msg(True, "--- gamemod masterserver %s starting up ---" % gamemod.VERSION)

	g = gamemod()
	try:
		while True: time.sleep(1) # TODO
	except KeyboardInterrupt:
		msg = "exiting (KeyboardInterrupt) ...";
		try:
			debug.msg(True, msg)
		except:
			try: log.out("(debug.msg failed, using log.out) " + msg)
			except: print("(debug.msg and log.out failed, using print) " + msg)
		sys.exit()
コード例 #18
0
    def readinfo(self, buf):
        try:
            numclients_ = buf.getint()
            attrs_ = buf.getint()
            if attrs_ != 5: return False, "attrs is not 5"
            version_ = buf.getint()
            gamemode_ = buf.getint()
            remaining_ = buf.getint(
            )  # TODO: switch protocol versions (in sooner versions, remaining_ is in minutes)
            maxclients_ = buf.getint()
            mastermode_ = buf.getint()
            map_ = buf.getstring()
            desc_ = buf.getstring()
        except EndOfBufError:
            return False, "end of buf unexpectedly reached"

        if int(time.time()) - latest_check > 60:
            for serv in known_servers.keys():
                if int(time.time()) - known_servers[serv] > 60:
                    del known_servers[serv]
                    print("Server removed: ID: %s" % serv)
        server_id = "%s:%s" % (self.host, self.port)
        if (server_id not in known_servers.keys()):
            print(
                "Server added: IP: %s, Port: %d, Description: \"%s\", Map: \"%s\", ID: %s, Clients: %d, Version: %d, Attrs: %d, Gamemode: %d, Remaining: %d, Max. Clients: %d, Mastermode: %d\n"
                % (self.host, self.port, desc_.replace("\r\n", "").replace(
                    "\n", "").decode('utf-8',
                                     'ignore'), map_, server_id, numclients_,
                   version_, attrs_, gamemode_, remaining_, maxclients_,
                   mastermode_))  # TODO: Translate numbers to actual words.
        known_servers[server_id] = int(time.time())

        debug.msg(
            server.DBGTAG_READINFO,
            "%s:%d: id=%s-%d, numclients=%d, attrs=%d, version=%d, gamemode=%d, remaining=%d, maxclients=%d, mastermode=%d, map=\"%s\", desc=\"%s\""
            % (self.host, self.port, self.host, self.port, numclients_, attrs_,
               version_, gamemode_, remaining_, maxclients_, mastermode_, map_,
               desc_))

        self.numclients = numclients_
        self.version = version_
        self.gamemode = gamemode_
        self.remaining = remaining_
        self.maxclients = maxclients_
        self.mastermode = mastermode_
        self.map = map_
        self.desc = tools.safe(desc_)

        return True, ""
コード例 #19
0
	def sendqueue(self):
		before = len(self.packetqueue)
		if before:
			while len(self.packetqueue):
				p = self.packetqueue.popleft()
				try:
					self.socket.sendto(p.data, p.addr)
				except:
					self.packetqueue.appendleft(p)
					break
				#print("sending packet to %s:%d" % (p.addr[0], p.addr[1]))
				#self.socket.sendto(p.data, 0, p.addr)
			now = len(self.packetqueue)
			if before != now:
				debug.msg(servercommunicator.DBGTAG_SENT, "sent %d of %d packets (%d packets left)" % (before-now, before, now))
コード例 #20
0
 def sendqueue(self):
     before = len(self.packetqueue)
     if before:
         while len(self.packetqueue):
             p = self.packetqueue.popleft()
             try:
                 self.socket.sendto(p.data, p.addr)
             except:
                 self.packetqueue.appendleft(p)
                 break
             #print("sending packet to %s:%d" % (p.addr[0], p.addr[1]))
             #self.socket.sendto(p.data, 0, p.addr)
         now = len(self.packetqueue)
         if before != now:
             debug.msg(
                 servercommunicator.DBGTAG_SENT,
                 "sent %d of %d packets (%d packets left)" %
                 (before - now, before, now))
コード例 #21
0
def main():
    debug.msg(True,
              "--- gamemod masterserver %s starting up ---" % gamemod.VERSION)

    g = gamemod()
    try:
        while True:
            time.sleep(1)  # TODO
    except KeyboardInterrupt:
        msg = "exiting (KeyboardInterrupt) ..."
        try:
            debug.msg(True, msg)
        except:
            try:
                log.out("(debug.msg failed, using log.out) " + msg)
            except:
                print("(debug.msg and log.out failed, using print) " + msg)
        sys.exit()
コード例 #22
0
 def processline(self, line):
     if line[:len(masterclient.ADDSERVER_COMMAND
                  )] != masterclient.ADDSERVER_COMMAND:
         debug.msg(
             masterclient.DBGTAG_INVALID,
             "received invalid line from master, does not start with \"%s\": %s"
             % (masterclient.ADDSERVER_COMMAND, line))
         return
     a = line[len(masterclient.ADDSERVER_COMMAND) + 1:]
     p = a.split(" ")
     if len(p) < 2:
         debug.msg(
             masterclient.DBGTAG_INVALID,
             "received invalid line from master, does not contain 2 arguments: %s"
             % line)
         return
     host = p[0]
     port = int(p[1])
     self.list.add_from_master(host, port)
コード例 #23
0
	def pingservers(self):
		kicklist = []
		for name in self.lists:
			clist = self.lists[name]
			total = float(clist.len())
			n = 0.0
			for server in clist.releasingiterator():
				if ((not server.persistent) or name != self.pendingservers_key) and server.lastping != None and server.nextping != None and server.nextping < self.t and (server.lastreply == None or server.lastreply < server.lastping) and server.pings >= (1 if server.quicktest else config.PINGS_GIVEUP):
					# server is either not persistent or is not in pending servers list (it will be added there) has been pinged once or more, time is reached for a new ping, but the number of pings before giving up is exceeded. kick server.
					kicklist.append(server)
				elif server.nextping == None or server.nextping < self.t:
					# last ping has been too long ago, or server was never pinged. ping it.
					self.ping(server, n/total)
				n += 1
			if len(kicklist) > 0:
				debug.msg(servercommunicator.DBGTAG_KICK, "kicking out %d servers from %s list" % (len(kicklist), name))
				for server in kicklist:
					self.kick(clist, name, server)
				del kicklist[:]
コード例 #24
0
 def kick(self, clist, name, server):
     debug.msg(
         servercommunicator.DBGTAG_MOVESERVER
         if server.persistent else servercommunicator.DBGTAG_KICKSERVER,
         "%s server at %s:%d from %s list%s (first ping: %s, last ping: %s, last reply: %s)"
         % ("moving persistent" if server.persistent else "kicking out",
            server.host, server.port, name,
            (" to %s list" %
             self.pendingservers_key) if server.persistent else "",
            ("never" if server.firstping == None else
             ("%f seconds ago" % (self.t - server.firstping))),
            ("never" if server.lastping == None else
             ("%f seconds ago" % (self.t - server.lastping))),
            ("never" if server.lastreply == None else
             ("%f seconds ago" % (self.t - server.lastreply)))))
     clist.remove(server)
     if server.persistent:
         self.lists[self.pendingservers_key].append_once(server)
     else:
         server.onremove()
コード例 #25
0
ファイル: gui.py プロジェクト: zlyfer/crapmod-masterserver
    def update(self, catch=True, force=False):
        # update gui (read it from file)
        try:
            f = open(self.path, "r")
            newguilines = []
            errors = []
            warnings = []
            n = 0  # line number
            for line in f:
                n += 1
                self.curline = n
                gl = guiline(
                    self.g, line[:-1] if
                    (len(line) > 0 and line[-1] == "\n") else l)
                for w in gl.warnings:
                    warnings.append("warning in line %d: %s" % (n, w))
                if gl.error:
                    errors.append("skipping line %d: %s" % (n, gl.error))
                else:
                    newguilines.append(gl)
            f.close()
            exchange = force or (not len(errors))

            for w in warnings:
                debug.msg(gui.DBGTAG_WARNING, w)
            debug.msg(
                gui.DBGTAG_WARNINGS, "%s warnings while reading gui" %
                (str(len(warnings)) if len(warnings) else "no"))

            for e in errors:
                debug.msg(gui.DBGTAG_ERROR, e)
            debug.msg(
                gui.DBGTAG_ERRORS, "%s errors while reading gui%s, %s" %
                (str(len(errors)) if len(errors) else "no",
                 " (ignoring these lines)" if len(errors) else "",
                 "applying new guilines list"
                 if exchange else "cancelling update"))

            if exchange:
                self.guilines.exchange(newguilines)
            return exchange, "%d lines read, %d errors (skipping lines with errors), %d warnings" % (
                len(newguilines), len(errors), len(warnings))

        except:
            try:
                f.close()
            except:
                pass
            if catch: debug.exc(self)
            else: raise
        return False, "internal errors occurred"
コード例 #26
0
ファイル: serverlist.py プロジェクト: xthirtyfive/gamemod
	def add_once(self, host, port, selfreg=False, suggested=False, persistent=False, force=False, checkport=True, file=None, quicktest=False): # add server if it doesn't already exist, return (serverobject, existed)
		if (not force) and self._isbanned(host, port):
			debug.msg(serverlist.DBGTAG_REFUSED, "refused a banned server at %s:%d" % (host, port))
			return None, False
		else:
			if checkport and (port < 0 or port > 65534):
				debug.msg(serverlist.DBGTAG_INVALIDPORT, "trying to add a new server with an invalid port: %s:%d" % (host, port))
				return
			s = self.find(host, port)
			if s:
				existed = True
			else:
				s = server(host, port)
				self._append(s)
				existed = False
			if selfreg: s.selfreg = True # whether this server has registered itself to gamemod (and not arrived via sauerbraten.org)
			if (not existed) and suggested: s.suggested = True # whether this server has been suggested to gamemod and was unknown before (and not arrived via sauerbraten.org)
			if persistent: s.persistent = True # whether this server should never be kicked from the pending servers list
			if file: s.fromfile = file
			if (not existed) and quicktest: s.quicktest = True # whether this server should be tested for registration quickly (= kick it if it does not already reply within one request and config.PING_INTERVAL)
			return s, existed
コード例 #27
0
 def add_once(
     self,
     host,
     port,
     selfreg=False,
     suggested=False,
     persistent=False,
     force=False,
     checkport=True,
     file=None,
     quicktest=False
 ):  # add server if it doesn't already exist, return (serverobject, existed)
     if (not force) and self._isbanned(host, port):
         debug.msg(serverlist.DBGTAG_REFUSED,
                   "refused a banned server at %s:%d" % (host, port))
         return None, False
     else:
         if checkport and (port < 0 or port > 65534):
             debug.msg(
                 serverlist.DBGTAG_INVALIDPORT,
                 "trying to add a new server with an invalid port: %s:%d" %
                 (host, port))
             return
         s = self.find(host, port)
         if s:
             existed = True
         else:
             s = server(host, port)
             self._append(s)
             existed = False
         if selfreg:
             s.selfreg = True  # whether this server has registered itself to gamemod (and not arrived via sauerbraten.org)
         if (not existed) and suggested:
             s.suggested = True  # whether this server has been suggested to gamemod and was unknown before (and not arrived via sauerbraten.org)
         if persistent:
             s.persistent = True  # whether this server should never be kicked from the pending servers list
         if file: s.fromfile = file
         if (not existed) and quicktest:
             s.quicktest = True  # whether this server should be tested for registration quickly (= kick it if it does not already reply within one request and config.PING_INTERVAL)
         return s, existed
コード例 #28
0
    def read(self, buf, t):
        debug.msg(
            server.DBGTAG_READ,
            "%s:%d: reading %d bytes" % (self.host, self.port, buf.len()))
        if debug.tagenabled(server.DBGTAG_BUFDUMP):
            pos = buf.pos()
            s = ""
            while buf.available():
                try:
                    s += " " + str(buf.getint())
                except EndOfBufError:
                    break
            debug.msg(server.DBGTAG_BUFDUMP,
                      "%s:%d: buf:%s" % (self.host, self.port, s))
            buf.seek(pos)

        req = buf.read()
        if (req == ord(packet.ALTEXTINFO_BYTE)) or (not req):
            # (standard/alternative) extinfo
            buf.skip(
                len(packet.ALTEXTINFO_DATA if
                    (req == packet.ALTEXTINFO_BYTE) else packet.EXTINFO_DATA) -
                1)
            succ, msg = self.readextinfo(buf)
            if succ:
                self.lastextinforeply = t
                self.usealtextinfo = (req == packet.ALTEXTINFO_BYTE)
        else:
            succ, msg = self.readinfo(buf)
        if not succ:
            debug.msg(
                server.DBGTAG_READFAIL,
                "%s:%d: reading %d bytes of %sinfo failed: %s" %
                (self.host, self.port, buf.len(), "" if req else "ext", msg))
コード例 #29
0
	def processdata(self, p):
		debug.msg(servercommunicator.DBGTAG_RECV, "received %d bytes from %s:%d" % ((len(p.data),)+p.addr))
		host = p.addr[0]
		servport = p.addr[1] - 1
		plist = self.lists[self.pendingservers_key]
		s = plist.find(host, servport)
		if s:
			# server from pending servers list has replied, move it to registered servers list
			rlist = self.lists[self.registeredservers_key]
			self.register(s, rlist, plist)
		else:
			# sender is not in pending servers list, look through other lists
			for name in self.lists:
				if name == self.pendingservers_key: continue
				clist = self.lists[name]
				s = clist.find(host, servport)
				if s: break
			if not s: #if no server was found in any list, return.
				debug.msg(servercommunicator.DBGTAG_UNKNOWNSERVER, "received %d bytes from an unknown server at %s:%d (packet sent from port %d)" % (len(p.data), host, servport, p.addr[1]))
				return
				# TODO maybe add the server directly, even though it did not announce itself via regserv command?
		s.lastreply = self.t
		s.read(buf(p.data), self.t) # hand over current time (self.t) so server can set s.lastextinforeply if this is extinfo
コード例 #30
0
 def onrequest(self, line, addr, build):  # return (reply, close)
     if line == guiprovider.LIST_REQUEST:
         debug.msg(
             guiprovider.DBGTAG_REQUEST, "%s request from %s:%d (%sbuild)" %
             ((line, ) + addr + ("" if build else "don't ", )))
         self.counter.add(addr[0])
         s = (self.request() if build else True)
         debug.msg(
             guiprovider.DBGTAG_REQUEST,
             "sending reply to %s request to %s:%d" % ((line, ) + addr))
         return s, True
     elif line == guiprovider.READABLELIST_REQUEST:
         debug.msg(
             guiprovider.DBGTAG_REQUEST, "%s request from %s:%d (%sbuild)" %
             ((line, ) + addr + ("" if build else "don't ", )))
         s = (self.request(True) if build else True)
         debug.msg(
             guiprovider.DBGTAG_REQUEST,
             "sending reply to %s request to %s:%d" % ((line, ) + addr))
         return s, True
     return None, False
コード例 #31
0
ファイル: gui.py プロジェクト: xthirtyfive/gamemod
	def update(self, catch=True, force=False):
		# update gui (read it from file)
		try:
			f = open(self.path, "r")
			newguilines = []
			errors = []
			warnings = []
			n = 0 # line number
			for line in f:
				n += 1
				self.curline = n
				gl = guiline(self.g, line[:-1] if (len(line) > 0 and line[-1]=="\n") else l)
				for w in gl.warnings:
					warnings.append("warning in line %d: %s" % (n, w))
				if gl.error: errors.append("skipping line %d: %s" % (n, gl.error))
				else: newguilines.append(gl)
			f.close()
			exchange = force or (not len(errors))
			
			for w in warnings:
				debug.msg(gui.DBGTAG_WARNING, w)
			debug.msg(gui.DBGTAG_WARNINGS, "%s warnings while reading gui" % (str(len(warnings)) if len(warnings) else "no"))
			
			for e in errors:
				debug.msg(gui.DBGTAG_ERROR, e)
			debug.msg(gui.DBGTAG_ERRORS, "%s errors while reading gui%s, %s" % (str(len(errors)) if len(errors) else "no", " (ignoring these lines)" if len(errors) else "", "applying new guilines list" if exchange else "cancelling update"))
			
			if exchange:
				self.guilines.exchange(newguilines)
			return exchange, "%d lines read, %d errors (skipping lines with errors), %d warnings" % (len(newguilines), len(errors), len(warnings))
			
		except:
			try: f.close()
			except: pass
			if catch: debug.exc(self)
			else: raise
		return False, "internal errors occurred"
コード例 #32
0
ファイル: server.py プロジェクト: xthirtyfive/gamemod
	def read(self, buf, t):
		debug.msg(server.DBGTAG_READ, "%s:%d: reading %d bytes" % (self.host, self.port, buf.len()))
		if debug.tagenabled(server.DBGTAG_BUFDUMP):
			pos = buf.pos()
			s = ""
			while buf.available():
				try: s += " " + str(buf.getint())
				except EndOfBufError: break
			debug.msg(server.DBGTAG_BUFDUMP, "%s:%d: buf:%s" % (self.host, self.port, s))
			buf.seek(pos)

		req = buf.read()
		if (req == ord(packet.ALTEXTINFO_BYTE)) or (not req):
			# (standard/alternative) extinfo
			buf.skip(len(packet.ALTEXTINFO_DATA if (req == packet.ALTEXTINFO_BYTE) else packet.EXTINFO_DATA)-1)
			succ, msg = self.readextinfo(buf)
			if succ:
				self.lastextinforeply = t
				self.usealtextinfo = (req == packet.ALTEXTINFO_BYTE)
		else:
			succ, msg = self.readinfo(buf)
		if not succ:
			debug.msg(server.DBGTAG_READFAIL, "%s:%d: reading %d bytes of %sinfo failed: %s" % (self.host, self.port, buf.len(), "" if req else "ext", msg))
コード例 #33
0
    def processconnection(self, i, funcs):
        (sock, addr) = i
        (host, port) = addr

        debug.msg(netserver.DBGTAG, "connection from %s:%d" % (host, port))

        sock.settimeout(2)

        closecon = False
        try:
            while True:
                lines, err = self.recv(sock)

                if err:
                    debug.msg(
                        netserver.DBGTAG_RECVFAIL,
                        "an error occured while receiving request from %s:%d" %
                        (host, port))
                    break

                for line in lines:

                    if len(line) <= 0:
                        debug.msg(
                            netserver.DBGTAG_EMPTYLINE,
                            "empty line received from %s:%d, skipping" %
                            (host, port))
                        continue

                    debug.msg(netserver.DBGTAG_TRAFFIC,
                              "received from %s:%d: %s" % (host, port, line))

                    reply = None
                    close = False
                    cachedreply = self.cache.find(line)

                    build = not bool(cachedreply)
                    for func in funcs:
                        r = func(line, addr, build)
                        if not r: continue
                        (creply, cclose) = r
                        if build: (reply, close) = r
                        if creply or cclose: break

                    if cachedreply:
                        (reply, close) = cachedreply

                    closecon = closecon or close

                    if reply:
                        replytext, n, err = self.send(
                            sock, reply,
                            (debug.tagenabled(netserver.DBGTAG_REPLYTEXT) or
                             ((not cachedreply) and replycache.enabled(line))))

                        if not err:
                            debug.msg(
                                netserver.DBGTAG_REPLY,
                                "sent %sreply with length %d to %s:%d" %
                                (("cached " if cachedreply else ""), n, host,
                                 port))
                            if replytext != None:
                                debug.msg(
                                    netserver.DBGTAG_REPLYTEXT,
                                    "sent %sreply to %s:%d: (starts next line)\n%s\n --- end of reply ---"
                                    % (("cached " if cachedreply else ""),
                                       host, port, replytext))

                            if (not cachedreply) and replycache.enabled(line):
                                self.cache.cache(line, replytext, close)
                        else:
                            debug.msg(
                                netserver.DBGTAG_SENDFAIL,
                                "an error occured while sending reply to %s:%d"
                                % (host, port))

                    elif close:  # no reply, but close - forceclose
                        debug.msg(
                            netserver.DBGTAG_FORCECLOSE,
                            "force-closing connection to %s:%d without reply" %
                            (host, port))
                        break
                    else:
                        debug.msg(
                            netserver.DBGTAG_UNKNOWN,
                            "no reply available for line received from %s:%d: %s"
                            % (host, port, line))

                if closecon: break
        except:
            debug.msg(
                netserver.DBGTAG,
                "an error occured while processing connection with %s:%d" %
                (host, port))
            debug.exc()

        self.accesscache.end(host)

        shut = False
        try:
            sock.shutdown(socket.SHUT_RDWR)
            shut = True
        except:
            pass  # remote has already shut down connection
        try:
            sock.close()
        except:
            pass

        debug.msg(
            netserver.DBGTAG, "connection %s:%d closed (shutdown %s)" %
            (host, port, "succeeded" if shut else "failed"))
コード例 #34
0
    def readextinfo(self, buf):
        try:
            ack_ = buf.getint()
            if ack_ != packet.EXT_ACK:
                return False, "EXT_ACK (%d) expected, got %d instead" % (
                    packet.EXT_ACK, ack_)
            version_ = buf.getint()
            if version_ != packet.EXT_VERSION:
                return False, "received unknown extinfo version %d" % version_
            error_ = buf.getint()
            if error_ != packet.EXT_NO_ERROR:
                return False, "extinfo request contains errors, expected EXT_NO_ERROR (%d), got %d instead" % (
                    packet.EXT_NO_ERROR, error_)

            content_ = buf.getint()
            if content_ == packet.EXT_PLAYERSTATS_RESP_IDS:
                e = debug.tagenabled(server.DBGTAG_CLIENTCNSDUMP)
                if e:
                    s = ""
                    n = 0
                while buf.available():
                    cn = buf.getint()
                    self.clients.keep(cn)  # keep this player
                    if e:
                        s += " " + str(cn)
                        n += 1
                self.clients.keep()  # remove players not called keep() on
                if e:
                    debug.msg(
                        server.DBGTAG_CLIENTCNSDUMP,
                        "%s:%d: received %d cns:%s" %
                        (self.host, self.port, n, s))

            elif content_ == packet.EXT_PLAYERSTATS_RESP_STATS:
                cn = buf.getint()
                ping = buf.getint()
                name = buf.getstring()
                team = buf.getstring()
                frags = buf.getint()
                flags = buf.getint()
                deaths = buf.getint()
                teamkills = buf.getint()
                damage = buf.getint()
                health = buf.getint()
                armour = buf.getint()
                gunselect = buf.getint()
                priv = buf.getint()
                state = buf.getint()
                ip = (buf.read(), buf.read(), buf.read())

                c = self.clients.get(cn)
                c.name = name
                c.team = team
                c.frags = frags
                c.flags = flags
                c.priv = priv
                c.state = state
                c.ip = ip

                if debug.tagenabled(server.DBGTAG_CLIENTDUMP):
                    debug.msg(
                        server.DBGTAG_CLIENTDUMP,
                        "%s:%d: received client: cn=%d, name=\"%s\", team=\"%s\", frags=%d, flags=%d, priv=%d, ip=%d.%d.%d.x"
                        % ((self.host, self.port, cn, name, team, frags, flags,
                            priv) + ip))
            else:
                return False, "invalid content type, expected EXT_PLAYERSTATS_RESP_IDS (%d) or EXT_PLAYERSTATS_RESP_STATS (%d), got %d instead" % (
                    packet.EXT_PLAYERSTATS_RESP_IDS,
                    packet.EXT_PLAYERSTATS_RESP_STATS, content_)

        except EndOfBufError:
            return False, "end of buf unexpectedly reached"

        return True, ""
コード例 #35
0
 def onrequest(self, line, addr, build):
     if line == statsprovider.STATS_REQUEST:
         debug.msg(statsprovider.DBGTAG_REQUEST,
                   "%s request from %s:%d" % ((line, ) + addr))
         return self.jsonstats(), True
コード例 #36
0
ファイル: masterclient.py プロジェクト: xthirtyfive/gamemod
	def updatefrommaster(self):
		s = self.connect()
		s.send("list\n")
		self.fetch(s)
		s.close()
		debug.msg(masterclient.DBGTAG_FETCHED, "fetched %d servers from master" % self.list.len())
コード例 #37
0
    def fetch(self,
              catch,
              path,
              synclists,
              oldlist,
              needport=True,
              add_once=False):
        # sync synclist (read it from file, add unexisting servers, remove servers no more in file (compare read items with oldlist)) and return a list of fetched items (which will be used as oldlist next time

        debug.msg(
            additionalservers.DBGTAG_UPDATING,
            "updating %d server list%s with servers from file %s" %
            (len(synclists), "s" if len(synclists) > 1 else "", path))

        try:
            f = open(path, "r")

            newlist = []
            addlist = []

            n = 0  # line number
            errors = 0
            for line_ in f:
                n += 1
                if line_[-1] == "\n": line = line_[:-1]
                else: line = line_
                if len(line) <= 0 or line.startswith(
                        additionalservers.COMMENT_STR):
                    continue
                p = line.split(" ")
                if len(p) < 2 and needport:
                    debug.msg(
                        additionalservers.DBGTAG_INVALID,
                        "can't fetch server from line %d in file %s" %
                        (n, path))
                    errors += 1
                else:
                    whost = p[0]
                    if len(p) >= 2:
                        try:
                            port = int(p[1])
                        except:
                            debug.msg(
                                additionalservers.DBGTAG_INVALID,
                                "can't fetch port for server at %s from line %d in file %s"
                                % (whost, n, path))
                            errors += 1
                            continue
                    else:
                        port = "*"
                    try:
                        host = socket.gethostbyname(whost)
                    except:
                        debug.msg(
                            additionalservers.DBGTAG_INVALID,
                            "can't resolve host %s for server at %s:%s from line %d in file %s"
                            % (whost, whost, str(port), n, path))
                        errors += 1
                        continue

                    item = (host, port)
                    newlist.append(item)
                    addlist.append(item)

            f.close()

            dellist = []

            for old in oldlist:
                if addlist.count(old): addlist.remove(old)  # was added already
                else: dellist.append(old)  # was removed from file

            for (synclist, listname) in synclists:
                for (host, port) in dellist:
                    s = synclist.find(host, port)
                    if s and s.fromfile == path:
                        synclist.removeall(s)
                        debug.msg(
                            additionalservers.DBGTAG_REMOVED,
                            "removed server at %s:%s from %s servers list" %
                            (host, str(port), listname))

            for (host, port) in addlist:
                if add_once:  # don't add this anywhere if it already exists in any of the supplied synclists
                    skip = False
                    for (list_, name) in synclists:
                        if list_.find(host, port):
                            skip = True
                            break
                    if skip:
                        debug.msg(
                            additionalservers.DBGTAG_SKIP,
                            "skipping server %s:%s from file %s because it already exists in the supplied synclists"
                            % (host, str(port), path))
                        continue
                debug.msg(
                    additionalservers.DBGTAG_ADD,
                    "adding server at %s:%s to %s servers list" %
                    (host, str(port), synclists[0][1]))
                synclists[0][0].add_from_file(
                    host, (port if (type(port) == types.IntType) else None),
                    file=path)

            debug.msg(
                additionalservers.DBGTAG_UPDATED,
                "updated %d server list%s with servers from file %s: %d items fetched from %d lines, %d errors, %d items added, %d items deleted"
                % (len(synclists), "s" if len(synclists) > 1 else "", path,
                   len(newlist), n, errors, len(addlist), len(dellist)))

            return True, "%d items fetched from %d lines, %d errors (skipping lines with errors), %d items added, %d items deleted" % (
                len(newlist), n, errors, len(addlist), len(dellist)), newlist

        except:
            if catch:
                debug.exc(self)
                try:
                    f.close()
                except:
                    pass
            else:
                try:
                    f.close()
                except:
                    pass
                raise
        return False, "internal errors occurred", oldlist
コード例 #38
0
ファイル: statsprovider.py プロジェクト: xthirtyfive/gamemod
	def onrequest(self, line, addr, build):
		if line == statsprovider.STATS_REQUEST:
			debug.msg(statsprovider.DBGTAG_REQUEST, "%s request from %s:%d" % ((line,)+addr))
			return self.jsonstats(), True
コード例 #39
0
	def parse(self, s, standalone):
		start_i = 0
		while start_i < len(s): # skip whitespaces in front
			b = s[start_i]
			if b != "\t" and b != " ": break
			start_i += 1
		self.leadingwhitespaces = s[:start_i]
		comment_i = s.find("//", start_i)
		if comment_i > -1:
			s = s[:comment_i]
		for i in guiline.GUI_REPLACEMENTS:
			s = s.replace(i, guiline.GUI_REPLACEMENTS[i])
		while True:
			i = s.find(self.gui.GUICOMMAND_PREFIX, start_i)
			if i < 0:
				p = s[start_i:]
				if len(p): self.parts.append(p) # append rest of the line (or the whole line if it does not contain any guicommands)
				break
			argpart_i = s.find(self.gui.GUICOMMAND_ARGS_PREFIX, i+len(self.gui.GUICOMMAND_PREFIX))
			if argpart_i < 0: return "missing arguments-opening \"%s\" after guicommand-prefix \"%s\" and guicommand-name" % (self.gui.GUICOMMAND_ARGS_PREFIX, self.gui.GUICOMMAND_PREFIX)
			cmd = s[i+len(self.gui.GUICOMMAND_PREFIX):argpart_i]
			args_i = argpart_i+len(self.gui.GUICOMMAND_ARGS_PREFIX)
			endargs_i = None
			whole = guicommand.args_whole(cmd)
			while True:
				end = False
				if s.startswith(self.gui.ARGS_NOMODIFIERS_MODIFIER, args_i): # allow no more modifiers
					args_i += len(self.gui.ARGS_NOMODIFIERS_MODIFIER)
					end = True
				elif s.startswith(self.gui.ARGS_TILEOL_MODIFIER, args_i): # read argument until ")" at end of line
					endargs_i = False
					args_i += len(self.gui.ARGS_TILEOL_MODIFIER)
				elif s.startswith(self.gui.ARGS_WHOLE_MODIFIER, args_i): # read whole argument list as one string
					whole = True
					args_i += len(self.gui.ARGS_WHOLE_MODIFIER)
				else: break
				if end: break
			if endargs_i == None: # search for end of args
				endargs_i = s.find(self.gui.GUICOMMAND_ARGS_SUFFIX, args_i)
				if endargs_i < 0: return "missing arguments-closing \"%s\" at end of command" % gui.GUICOMMAND_ARGS_SUFFIX
			elif endargs_i == False: # TILEOL modifier is used
				endargs_i = len(s)-len(self.gui.GUICOMMAND_ARGS_SUFFIX)
				if s[endargs_i:endargs_i+len(self.gui.GUICOMMAND_ARGS_SUFFIX)] != self.gui.GUICOMMAND_ARGS_SUFFIX: return "missing arguments-closing \"%s\" at end of line" % gui.GUICOMMAND_ARGS_SUFFIX
			
			argstring = s[args_i:endargs_i]
			if not len(argstring):
				args = []
			elif whole: # WHOLE modifier is used
				args = [argstring]
			else:
				args = argstring.split(self.gui.GUICOMMAND_ARGS_SEPERATOR)
				
			args_min = guicommand.args_min(cmd)
			if len(args) < args_min and ((not whole) or (not len(args))):
				return "guicommand \"%s\" requires at least %d argument%s" % (cmd, args_min, "s" if args_min > 1 else "")
				
			if guicommand.args_guiline(cmd):
				args_ = []
				for a in args:
					gl = guiline(self.g, a, False)
					if gl.error: return "in argument of guicommand \"%s\": %s" % (cmd, gl.error)
					args_.append(gl)
				args = args_
			
			item, msg = guicommand.get(self.g, cmd, args, standalone) # item may either be a guicommand instance or just a string (in case a guicommand would always result in the same string)
			if item == None:
				return "guicommand \"%s\": %s" % (cmd, msg)
			
			p = s[start_i:i]
			if len(p): self.parts.append(p)
			#self.parts.append("guicommand \"%s\" with %d args: \"%s\"" % (cmd, len(args), "\", \"".join(args)))
			self.parts.append(item)
			start_i = endargs_i+len(self.gui.GUICOMMAND_ARGS_SUFFIX) # start search for next guicommand at position where the last one ended
		
		if debug.tagenabled(guiline.DBGTAG_DUMPPARTS): debug.msg(guiline.DBGTAG_DUMPPARTS, "parsed %d parts: %s" % (len(self.parts), repr(self.parts)))
コード例 #40
0
	def register(self, server, rlist, plist):
		plist.removeall(server)
		rlist.append_once(server)
		debug.msg(servercommunicator.DBGTAG_SUCCREG, "registration of server %s:%d successful" % (server.host, server.port))
		server.quicktest = False
		server.onregister()
コード例 #41
0
	def fetch(self, catch, path, synclists, oldlist, needport=True, add_once=False):
		# sync synclist (read it from file, add unexisting servers, remove servers no more in file (compare read items with oldlist)) and return a list of fetched items (which will be used as oldlist next time
		
		debug.msg(additionalservers.DBGTAG_UPDATING, "updating %d server list%s with servers from file %s" % (len(synclists), "s" if len(synclists) > 1 else "", path))
		
		try:
			f = open(path, "r")
			
			newlist = []
			addlist = []
			
			n = 0 # line number
			errors = 0
			for line_ in f:
				n += 1
				if line_[-1] == "\n": line = line_[:-1]
				else: line = line_
				if len(line) <= 0 or line.startswith(additionalservers.COMMENT_STR): continue
				p = line.split(" ")
				if len(p) < 2 and needport:
					debug.msg(additionalservers.DBGTAG_INVALID, "can't fetch server from line %d in file %s" % (n, path))
					errors += 1
				else:
					whost = p[0]
					if len(p) >= 2:
						try:
							port = int(p[1])
						except:
							debug.msg(additionalservers.DBGTAG_INVALID, "can't fetch port for server at %s from line %d in file %s" % (whost, n, path))
							errors += 1
							continue
					else:
						port = "*"
					try:
						host = socket.gethostbyname(whost)
					except:
						debug.msg(additionalservers.DBGTAG_INVALID, "can't resolve host %s for server at %s:%s from line %d in file %s" % (whost, whost, str(port), n, path))
						errors += 1
						continue
						
					item = (host, port)
					newlist.append(item)
					addlist.append(item)

					
			f.close()
			
			dellist = []
			
			for old in oldlist:
				if addlist.count(old): addlist.remove(old) # was added already
				else: dellist.append(old) # was removed from file
			
			for (synclist, listname) in synclists:
				for (host, port) in dellist:
					s = synclist.find(host, port)
					if s and s.fromfile == path:
						synclist.removeall(s)
						debug.msg(additionalservers.DBGTAG_REMOVED, "removed server at %s:%s from %s servers list" % (host, str(port), listname))
			
			for (host, port) in addlist:
				if add_once: # don't add this anywhere if it already exists in any of the supplied synclists
					skip = False
					for (list_, name) in synclists:
						if list_.find(host, port):
							skip = True
							break
					if skip:
						debug.msg(additionalservers.DBGTAG_SKIP, "skipping server %s:%s from file %s because it already exists in the supplied synclists" % (host, str(port), path))
						continue
				debug.msg(additionalservers.DBGTAG_ADD, "adding server at %s:%s to %s servers list" % (host, str(port), synclists[0][1]))
				synclists[0][0].add_from_file(host, (port if (type(port) == types.IntType) else None), file=path)
				
			debug.msg(additionalservers.DBGTAG_UPDATED, "updated %d server list%s with servers from file %s: %d items fetched from %d lines, %d errors, %d items added, %d items deleted" % (len(synclists), "s" if len(synclists) > 1 else "", path, len(newlist), n, errors, len(addlist), len(dellist)))
			
			return True, "%d items fetched from %d lines, %d errors (skipping lines with errors), %d items added, %d items deleted" % (len(newlist), n, errors, len(addlist), len(dellist)), newlist
			
		except:
			if catch:
				debug.exc(self)
				try: f.close()
				except: pass
			else:
				try: f.close()
				except: pass
				raise
		return False, "internal errors occurred", oldlist
コード例 #42
0
ファイル: serverlist.py プロジェクト: xthirtyfive/gamemod
	def append_once(self, server):
		if not self.exists(server):
			if not self._isbanned(server):
				self._append(server)
			else:
				debug.msg(serverlist.DBGTAG_REFUSED, "refused a banned server at %s:%d" % (server.host, server.port))
コード例 #43
0
ファイル: masterserver.py プロジェクト: xthirtyfive/gamemod
	def onrequest(self, line, addr, build): # return reply, close
		if line.startswith(masterserver.REGSERV_COMMAND):
			port = False
			try:
				port = int(line[len(masterserver.REGSERV_COMMAND)+1:])
			except:
				debug.msg(masterserver.DBGTAG_INVALID, "could not get port from line received from %s:%d: %s" % (addr+(line,)))
				return None, False
			if port < 0 or port > 65534:
				debug.msg(masterserver.DBGTAG_INVALIDPORT, "server tried to register with invalid port: %d" % port)
				return ("%s wtf port? %d?" % (masterserver.FAILREG_COMMAND, port)), True
			debug.msg(masterserver.DBGTAG_REGSERV, "trying to register server at port %d (received from %s:%d)" % ((port,)+addr))
			succ, existed, banned = self.regserv(addr[0], port)
			debug.msg(masterserver.DBGTAG_REGSERV, "registration of %sserver at %s:%d (received from %s:%d) %s%s" % ((("existing " if existed else ""), addr[0], port)+addr+(("succeeded" if succ else "failed"), (", address is banned" if banned else ""))))
			if succ:
				return masterserver.SUCCREG_COMMAND, True
			else:
				if banned:
					return ("%s you are banned from this masterserver" % masterserver.FAILREG_COMMAND), True
				else:
					return (("%s no reply received after requesting from %s:%d") % (masterserver.FAILREG_COMMAND, addr[0], port+1)), True
					
		elif line.startswith(masterserver.SUGGEST_COMMAND):
			port = False
			try:
				addr_s = line[len(masterserver.REGSERV_COMMAND)+1:].split(" ")
				host_s = addr_s[0]
				port = int(addr_s[1])				
			except:
				debug.msg(masterserver.DBGTAG_INVALID, "could not get host and port from line received from %s:%d: %s" % (addr+(line,)))
				return ("%s could not parse command, use: %s host port" % (masterserver.FAILREG_COMMAND, masterserver.SUGGEST_COMMAND)), True
			if port < 0 or port > 65534:
				debug.msg(masterserver.DBGTAG_INVALIDPORT, "client tried to suggest a server with an invalid port: %d" % port)
				return ("%s wtf port? %d?" % (masterserver.FAILREG_COMMAND, port)), True
			try:
				host = socket.gethostbyname(host_s)
			except:
				debug.msg(masterserver.DBGTAG_INVALID, "could not get host and port from line received from %s:%d: %s" % (addr+(line,)))
				return ("%s could not resolve %s" % (masterserver.FAILREG_COMMAND, host_s)), True
			debug.msg(masterserver.DBGTAG_SUGGEST, "trying to register suggested server at %s:%d (%s) (received from %s:%d)" % ((host, port, host_s)+addr))
			succ, existed, banned = self.suggest(host, port)
			debug.msg(masterserver.DBGTAG_SUGGEST, "registration of %ssuggested server at %s:%d (received from %s:%d) %s%s" % ((("existing " if existed else ""), host, port)+addr+(("succeeded" if succ else "failed"), (", address is banned" if banned else ""))))
			if succ:
				return ("%s the server at %s:%d %s" % (masterserver.SUCCREG_COMMAND, host, port, ("has already been registered" if existed else "is now registered"))), True
			else:
				if banned:
					return ("%s %s:%d is banned from this masterserver" % (masterserver.FAILREG_COMMAND, host, port)), True
				else:
					return (("%s server at %s:%d did not reply to info-request (sent to %s:%d)") % (masterserver.FAILREG_COMMAND, host, port, host, port+1)), True
					
		return None, False
コード例 #44
0
ファイル: netserver.py プロジェクト: xthirtyfive/gamemod
	def processconnection(self, i, funcs):
		(sock, addr) = i
		(host, port) = addr

		debug.msg(netserver.DBGTAG, "connection from %s:%d" % (host, port))
		
		sock.settimeout(2)
	
		closecon = False
		try:
			while True:
				lines, err = self.recv(sock)
				
				if err:
					debug.msg(netserver.DBGTAG_RECVFAIL, "an error occured while receiving request from %s:%d" % (host, port))
					break
				
				for line in lines:
				
					if len(line) <= 0:
						debug.msg(netserver.DBGTAG_EMPTYLINE, "empty line received from %s:%d, skipping" % (host, port))
						continue
		
					debug.msg(netserver.DBGTAG_TRAFFIC, "received from %s:%d: %s" % (host, port, line))
	
					reply = None
					close = False
					cachedreply = self.cache.find(line)
					
					build = not bool(cachedreply)
					for func in funcs:
						r = func(line, addr, build)
						if not r: continue
						(creply, cclose) = r
						if build: (reply, close) = r
						if creply or cclose: break
					
					if cachedreply:
						(reply, close) = cachedreply
					
					closecon = closecon or close
				
					if reply:
						replytext, n, err = self.send(sock, reply, (debug.tagenabled(netserver.DBGTAG_REPLYTEXT) or ((not cachedreply) and replycache.enabled(line))))
					
						if not err:
							debug.msg(netserver.DBGTAG_REPLY, "sent %sreply with length %d to %s:%d" % (("cached " if cachedreply else ""), n, host, port))
							if replytext != None: debug.msg(netserver.DBGTAG_REPLYTEXT, "sent %sreply to %s:%d: (starts next line)\n%s\n --- end of reply ---" % (("cached " if cachedreply else ""), host, port, replytext))
						
							if (not cachedreply) and replycache.enabled(line): self.cache.cache(line, replytext, close)
						else:
							debug.msg(netserver.DBGTAG_SENDFAIL, "an error occured while sending reply to %s:%d" % (host, port))
						
					elif close: # no reply, but close - forceclose
						debug.msg(netserver.DBGTAG_FORCECLOSE, "force-closing connection to %s:%d without reply" % (host, port))
						break
					else:
						debug.msg(netserver.DBGTAG_UNKNOWN, "no reply available for line received from %s:%d: %s" % (host, port, line))
					
				if closecon: break
		except:
			debug.msg(netserver.DBGTAG, "an error occured while processing connection with %s:%d" % (host, port))
			debug.exc()
			
		self.accesscache.end(host)

		shut = False
		try:
			sock.shutdown(socket.SHUT_RDWR)
			shut = True
		except: pass # remote has already shut down connection
		try:
			sock.close()
		except: pass
		
		debug.msg(netserver.DBGTAG, "connection %s:%d closed (shutdown %s)" % (host, port, "succeeded" if shut else "failed"))