<commit_before>import asyncore
import re
import sys
import socket
import urllib

from constants import MAIN_METASERVER_URL
from lib.log import debug, info, warning, exception
from serverclient import ConnectionToClient
from serverroom import InTheLobby, OrganizingAGame, Playing
from lib.ticker import Ticker
from version import VERSION

import config
import options


REGISTER_INTERVAL = 10 * 60 # register server every 10 minutes
REGISTER_URL = MAIN_METASERVER_URL + "servers_register.php"
UNREGISTER_URL = MAIN_METASERVER_URL + "servers_unregister.php"
WHATISMYIP_URL = open("cfg/whatismyip.txt").read().strip()


class Server(asyncore.dispatcher):

    def __init__(self, parameters, is_standalone):
        self.parameters = parameters
        self.is_standalone = is_standalone
        asyncore.dispatcher.__init__(self)
        self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
        self.set_reuse_addr()
        self.bind(("", options.port))
        self.listen(5)
        self.login = config.login
        self.clients = []
        self.games = []
        if "admin_only" in parameters:
            self.nb_games_max = 1
            self.nb_clients_max = 20
        else:
            self.nb_games_max = 10
            self.nb_clients_max = 40

    next_id = 0

    def get_next_id(self, increment=True):
        if increment:
            self.next_id += 1
            return self.next_id
        else:
            return self.next_id + 1

    def handle_connect(self):
        pass

    def handle_read(self):
        pass

    def handle_accept(self):
        ConnectionToClient(self, self.accept())

    def _cleanup(self):
        for c in self.clients[:]:
            if c not in asyncore.socket_map.values():
                self.clients.remove(c)
        if self.games and not self.clients:
            self.games = []

    def log_status(self):
        self._cleanup()
        info("%s players (%s not playing), %s games", len(self.clients),
             len(self.players_not_playing()),
             len([g for g in self.games if g.started]))

    def _is_admin(self, client):
        return client.address[0] == "127.0.0.1" and client.login == self.login

    def remove_client(self, client):
        info("disconnect: %s" % client.login)
        client.is_disconnected = True
        if client in self.clients: # not anonymous
            self.clients.remove(client)
            for c in self.players_not_playing():
                if client.is_compatible(c):
                    c.send_msg([client.login, 4259]) # ... has just disconnected
            self.update_menus()
        if isinstance(client.state, Playing):
            client.cmd_abort_game([])
        if self._is_admin(client) and not self.is_standalone:
            info("the admin has disconnected => close the server")
            sys.exit()
        self.log_status()

    def handle_write(self):
        pass

    def handle_close(self):
        try:
            debug("Server.handle_close")
        except:
            pass
        sys.exit()

    def handle_error(self):
        try:
            debug("Server.handle_error %s", sys.exc_info()[0])
        except:
            pass
        if sys.exc_info()[0] in [SystemExit, KeyboardInterrupt]:
            sys.exit()
        else:
            try:
                exception("Server.handle_error")
            except:
                pass

    def can_create(self, client):
        if "admin_only" in self.parameters:
            return self._is_admin(client)
        else:
            return len([g for g in self.games if g.started]) < self.nb_games_max

    def unregister(self):
        try:
            info("unregistering server...")
            s = urllib.urlopen(UNREGISTER_URL + "?ip=" + self.ip).read()
        except:
            s = "couldn't access to the metaserver"
        if s:
            warning("couldn't unregister from the metaserver (%s)", s[:80])

    ip = ""

    def _get_ip_address(self):
        if options.ip:
            self.ip = options.ip
            return
        try:
            self.ip = urllib.urlopen(WHATISMYIP_URL).read().strip()
            if not re.match("^[0-9.]{7,40}$", self.ip):
                self.ip = ""
        except:<commit_msg>set the timeout to 3 seconds when using a "what is my ip" website<commit_after>import asyncore
import re
import sys
import socket
import urllib
import urllib2

from constants import MAIN_METASERVER_URL
from lib.log import debug, info, warning, exception
from serverclient import ConnectionToClient
from serverroom import InTheLobby, OrganizingAGame, Playing
from lib.ticker import Ticker
from version import VERSION

import config
import options


REGISTER_INTERVAL = 10 * 60 # register server every 10 minutes
REGISTER_URL = MAIN_METASERVER_URL + "servers_register.php"
UNREGISTER_URL = MAIN_METASERVER_URL + "servers_unregister.php"
WHATISMYIP_URL = open("cfg/whatismyip.txt").read().strip()


class Server(asyncore.dispatcher):

    def __init__(self, parameters, is_standalone):
        self.parameters = parameters
        self.is_standalone = is_standalone
        asyncore.dispatcher.__init__(self)
        self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
        self.set_reuse_addr()
        self.bind(("", options.port))
        self.listen(5)
        self.login = config.login
        self.clients = []
        self.games = []
        if "admin_only" in parameters:
            self.nb_games_max = 1
            self.nb_clients_max = 20
        else:
            self.nb_games_max = 10
            self.nb_clients_max = 40

    next_id = 0

    def get_next_id(self, increment=True):
        if increment:
            self.next_id += 1
            return self.next_id
        else:
            return self.next_id + 1

    def handle_connect(self):
        pass

    def handle_read(self):
        pass

    def handle_accept(self):
        ConnectionToClient(self, self.accept())

    def _cleanup(self):
        for c in self.clients[:]:
            if c not in asyncore.socket_map.values():
                self.clients.remove(c)
        if self.games and not self.clients:
            self.games = []

    def log_status(self):
        self._cleanup()
        info("%s players (%s not playing), %s games", len(self.clients),
             len(self.players_not_playing()),
             len([g for g in self.games if g.started]))

    def _is_admin(self, client):
        return client.address[0] == "127.0.0.1" and client.login == self.login

    def remove_client(self, client):
        info("disconnect: %s" % client.login)
        client.is_disconnected = True
        if client in self.clients: # not anonymous
            self.clients.remove(client)
            for c in self.players_not_playing():
                if client.is_compatible(c):
                    c.send_msg([client.login, 4259]) # ... has just disconnected
            self.update_menus()
        if isinstance(client.state, Playing):
            client.cmd_abort_game([])
        if self._is_admin(client) and not self.is_standalone:
            info("the admin has disconnected => close the server")
            sys.exit()
        self.log_status()

    def handle_write(self):
        pass

    def handle_close(self):
        try:
            debug("Server.handle_close")
        except:
            pass
        sys.exit()

    def handle_error(self):
        try:
            debug("Server.handle_error %s", sys.exc_info()[0])
        except:
            pass
        if sys.exc_info()[0] in [SystemExit, KeyboardInterrupt]:
            sys.exit()
        else:
            try:
                exception("Server.handle_error")
            except:
                pass

    def can_create(self, client):
        if "admin_only" in self.parameters:
            return self._is_admin(client)
        else:
            return len([g for g in self.games if g.started]) < self.nb_games_max

    def unregister(self):
        try:
            info("unregistering server...")
            s = urllib.urlopen(UNREGISTER_URL + "?ip=" + self.ip).read()
        except:
            s = "couldn't access to the metaserver"
        if s:
            warning("couldn't unregister from the metaserver (%s)", s[:80])

    ip = ""

    def _get_ip_address(self):
        if options.ip:
            self.ip = options.ip
            return
        try:
            self.ip = urllib2.urlopen(WHATISMYIP_URL, timeout=3).read().strip()
            if not re.match("^[0-9.]{7,40}$", self.ip):
                self.ip = ""
        except:
{'fraction_non_alphanumeric': 0.10162744409319752, 'fraction_numerical': 0.0091324200913242, 'mean_word_length': 2.045276292335116, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 2, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6777850', 'n_tokens_mistral': 2638, 'n_tokens_neox': 2510, 'n_words': 613}