def selectPreset(Preset=None, Level=None, Mod=None, LT=None):
    global presetCicler, modCicler, mapCicler, LT_Cicler

    #io.messageLog(("selectPreset(): Preset %s Level %s Mod %s LT %s" % (str(Preset), str(Level), str(Mod), str(LT))),io.LOG_WARN)

    msg = ""
    if Preset:
        presetCicler.pushSelection(Preset)
        msg += " Preset " + Preset
    if Level:
        mapCicler.pushSelection(Level)
        msg += " Map " + Level
        #io.messageLog(("selectPreset(): presetCicler.preSelectedList %s" % (str(presetCicler.preSelectedList))),io.LOG_WARN)
        if len(presetCicler.preSelectedList) <= 0:
            presetCicler.pushSelection(
                "Random")  # Prevent loading preset that overrides this setting
    if Mod:
        modCicler.pushSelection(Mod)
        msg += " Mod " + Mod
        #io.messageLog(("selectPreset(): presetCicler.preSelectedList %s" % (str(presetCicler.preSelectedList))),io.LOG_WARN)
        if len(presetCicler.preSelectedList) <= 0:
            presetCicler.pushSelection(
                "Random")  # Prevent loading preset that overrides this setting
    if LT:
        LT_Cicler.pushSelection(str(LT))
        msg += " LT " + str(LT)
        #io.messageLog(("selectPreset(): presetCicler.preSelectedList %s" % (str(presetCicler.preSelectedList))),io.LOG_WARN)
        if len(presetCicler.preSelectedList) <= 0:
            presetCicler.pushSelection(
                "Random")  # Prevent loading preset that overrides this setting

    if gameState != GAME_LOBBY:
        io.chatMsg(msg.strip() + " will be selected for next game")
    else:
        io.chatMsg(msg.strip())
def selectPreset( Preset = None, Level = None, Mod = None, LT = None ):
	global presetCicler, modCicler, mapCicler, LT_Cicler

	#io.messageLog(("selectPreset(): Preset %s Level %s Mod %s LT %s" % (str(Preset), str(Level), str(Mod), str(LT))),io.LOG_WARN)

	msg = ""
	if Preset:
		presetCicler.pushSelection(Preset)
		msg += " Preset " + Preset
	if Level:
		mapCicler.pushSelection(Level)
		msg += " Map " + Level
		#io.messageLog(("selectPreset(): presetCicler.preSelectedList %s" % (str(presetCicler.preSelectedList))),io.LOG_WARN)
		if len(presetCicler.preSelectedList) <= 0:
			presetCicler.pushSelection( "Random" ) # Prevent loading preset that overrides this setting
	if Mod:
		modCicler.pushSelection(Mod)
		msg += " Mod " + Mod
		#io.messageLog(("selectPreset(): presetCicler.preSelectedList %s" % (str(presetCicler.preSelectedList))),io.LOG_WARN)
		if len(presetCicler.preSelectedList) <= 0:
			presetCicler.pushSelection( "Random" ) # Prevent loading preset that overrides this setting
	if LT:
		LT_Cicler.pushSelection(str(LT))
		msg += " LT " + str(LT)
		#io.messageLog(("selectPreset(): presetCicler.preSelectedList %s" % (str(presetCicler.preSelectedList))),io.LOG_WARN)
		if len(presetCicler.preSelectedList) <= 0:
			presetCicler.pushSelection( "Random" ) # Prevent loading preset that overrides this setting

	if gameState != GAME_LOBBY:
		io.chatMsg( msg.strip() + " will be selected for next game")
	else:
		io.chatMsg( msg.strip() )
def recheckVote(verbose=True):
    global voteCommand, voteTime, votePoster, voteDescription
    global kickedUsers
    if not voteCommand:
        return

    voteCount = 0
    notVoted = 0

    if cfg.VOTING_COUNT_NEGATIVE:
        for w in hnd.worms.keys():
            voteCount += hnd.worms[w].Voted
            if hnd.worms[w].Voted == 0:
                notVoted += 1
    else:
        for w in hnd.worms.keys():
            if hnd.worms[w].Voted == 1:
                voteCount += 1
            else:
                notVoted += 1

    humanWormCount = len(hnd.worms) - len(io.getComputerWormList())
    needVoices = int(math.ceil(humanWormCount * cfg.VOTING_PERCENT / 100.0))

    if voteCount >= needVoices or (time.time() - voteTime >= cfg.VOTING_TIME
                                   and cfg.VOTING_AUTO_ACCEPT):
        try:
            exec(voteCommand)
        except:
            io.messageLog(formatExceptionInfo(),
                          io.LOG_ERROR)  #Helps to fix errors

        voteCommand = None
        voteTime = 0
        return
    if time.time(
    ) - voteTime >= cfg.VOTING_TIME or needVoices - voteCount > notVoted:
        voteCommand = None
        voteTime = 0
        io.chatMsg("Vote failed: " + voteDescription)
        if (votePoster in hnd.worms.keys()) and (
                hnd.worms[votePoster].Voted == 1
        ):  # Check if worm left and another worm joined with same ID
            hnd.worms[votePoster].FailedVoteTime = time.time()
        return

    if verbose:
        io.chatMsg("Vote: " + voteDescription + ", " +
                   str(needVoices - voteCount) + " voices to go, " +
                   str(int(cfg.VOTING_TIME + voteTime - time.time())) +
                   (" seconds, say %sy or %sn" %
                    (cfg.ADMIN_PREFIX, cfg.ADMIN_PREFIX)))
def recheckVote(verbose = True):
	global voteCommand, voteTime, votePoster, voteDescription
	global kickedUsers
	if not voteCommand:
		return

	voteCount = 0
	notVoted = 0

	if cfg.VOTING_COUNT_NEGATIVE:
		for w in hnd.worms.keys():
			voteCount += hnd.worms[w].Voted
			if hnd.worms[w].Voted == 0:
				notVoted += 1
	else:
		for w in hnd.worms.keys():
			if hnd.worms[w].Voted == 1:
				voteCount += 1
			else:
				notVoted += 1
	
	humanWormCount = len(hnd.worms) - len(io.getComputerWormList())
	needVoices = int( math.ceil( humanWormCount * cfg.VOTING_PERCENT / 100.0 ) )

	if voteCount >= needVoices or (time.time() - voteTime >= cfg.VOTING_TIME and cfg.VOTING_AUTO_ACCEPT):
		try:
			exec(voteCommand)
		except:
			io.messageLog(formatExceptionInfo(),io.LOG_ERROR) #Helps to fix errors
		
		voteCommand = None
		voteTime = 0
		return
	if time.time() - voteTime >= cfg.VOTING_TIME or needVoices - voteCount > notVoted:
		voteCommand = None
		voteTime = 0
		io.chatMsg("Vote failed: " + voteDescription )
		if ( votePoster in hnd.worms.keys() ) and ( hnd.worms[votePoster].Voted == 1 ): # Check if worm left and another worm joined with same ID
			hnd.worms[votePoster].FailedVoteTime = time.time()
		return

	if verbose:
		io.chatMsg("Vote: " + voteDescription + ", " + str( needVoices - voteCount ) + " voices to go, " +
				str(int( cfg.VOTING_TIME + voteTime - time.time() )) + ( " seconds, say %sy or %sn" % ( cfg.ADMIN_PREFIX, cfg.ADMIN_PREFIX ) ) )
Beispiel #5
0
def parseUserCommand(wormid, message):

    try:  # Do not check on msg size or anything, exception handling is further down

        cmd = message.split(" ")[0]
        cmd = cmd.replace(cfg.USER_PREFIX, "", 1).lower()  #Remove the prefix

        if cfg.USERCOMMAND_LOGGING:
            if wormid >= 0:
                io.messageLog(
                    "%i:%s issued %s" % (wormid, hnd.worms[wormid].Name,
                                         cmd.replace(cfg.USER_PREFIX, "", 1)),
                    io.LOG_USRCMD)
            else:
                io.messageLog("ded admin issued %s" % cmd, io.LOG_USRCMD)

        # Unnecesary to split multiple times, this saves CPU.
        params = message.split(" ")[1:]

        if cmd == "help":
            userCommandHelp(wormid)
            return "none"

        elif cmd == "maphelp":
            mapHelp(wormid)
            return "none"

        #News feed (previously called updates, hence the command name...)
        elif cmd == "news":
            controlUpdatesList(wormid)
            return "none"

        #Teamchanges...
        elif cfg.ALLOW_TEAM_CHANGE and cmd == "team":
            #Not team deathmatch
            if io.getGameType() != 1:
                io.privateMsg(wormid, "Game type is not team deathmatch")
            #Not in lobby
            elif hnd.gameState != hnd.GAME_LOBBY:
                io.privateMsg(wormid, "You can only change team in lobby")
            #No team specified
            elif not params:
                io.privateMsg(wormid, "You need to specify a team")
            #Everything OK
            else:
                if params[0].lower() == "blue" or params[0].lower() == "b":
                    hnd.setTeam(wormid, 0)
                elif params[0].lower() == "red" or params[0].lower() == "r":
                    hnd.setTeam(wormid, 1)
                elif (params[0].lower() == "green"
                      or params[0].lower() == "g") and cfg.MAX_TEAMS >= 3:
                    hnd.setTeam(wormid, 2)
                elif (params[0].lower() == "yellow"
                      or params[0].lower() == "y") and cfg.MAX_TEAMS >= 4:
                    hnd.setTeam(wormid, 3)
                else:
                    io.privateMsg(wormid, "Invalid team")

        elif cfg.RANKING and cmd in ("rank", "toprank", "ranktotal"):
            if cmd == "toprank":
                ranking.firstRank(wormid)
            if cmd == "rank":
                if wormid in hnd.worms:
                    wormName = hnd.worms[wormid].Name
                    if params:
                        wormName = " ".join(params).replace(
                            "\"", "\'\'"
                        )  #Convert double quotes to prevent annoyance
                    ranking.myRank(wormName, wormid)
            if cmd == "ranktotal":
                if cfg.NAME_CHECK_ACTION == 1 and cfg.HANDLE_RANDOMS_IN_RANKTOTAL:
                    tmp_rankplayers = sortRankPlayers(
                        randoms=0, random_max=cfg.NAME_CHECK_RANDOM)
                    tmp_rankrandoms = sortRankPlayers(
                        randoms=1, random_max=cfg.NAME_CHECK_RANDOM)
                    io.privateMsg(
                        wormid, "There are " + str(len(tmp_rankplayers)) +
                        " players and " + str(len(tmp_rankrandoms)) +
                        " unnamed players in the ranking.")
                else:
                    io.privateMsg(
                        wormid, "There are " + str(len(ranking.rank)) +
                        " players in the ranking.")
            return "none"

        elif cfg.KICK_VOTING and cmd == "kick":
            try:
                kicked = int(params[0])
            except ValueError:
                io.privateMsg(wormid, "Invalid player ID")

            if not kicked in hnd.worms.keys():
                io.privateMsg(wormid, "Invalid player ID")
            else:
                hnd.worms[wormid].votedKick = kicked
                io.chatMsg(
                    hnd.worms[wormid].getCleanName() + " votes to kick " +
                    hnd.worms[kicked].getCleanName()
                )  #NOTE: We are using the real name here - so it should be cleaned
                return "kick"

        elif cfg.VOTING and cmd in ("mod", "map", "m"):

            if cmd == "mod":

                #NEW: only presets
                preset = -1
                for p in range(len(hnd.availablePresets)):
                    if hnd.availablePresets[p].lower().find(
                            params[0].lower()) != -1:
                        preset = p
                        break
                if preset != -1:
                    hnd.worms[wormid].votedPreset = hnd.availablePresets[
                        preset]
                    io.privateMsg(wormid, "You voted for %s" %
                                  hnd.worms[wormid].votedPreset
                                  )  #Send these as private msgs to reduce spam
                    return "mod"
                else:
                    io.privateMsg(
                        wormid, "Invalid preset, available presets: " +
                        ", ".join(hnd.availablePresets))

            if cmd == "map":
                level = ""
                for l in io.listMaps():
                    if l.lower().find(" ".join(params[0:]).lower()) != -1:
                        level = l
                        break
                if level != "":
                    hnd.worms[wormid].votedMap = level
                    io.privateMsg(
                        wormid,
                        "You voted for %s" % hnd.worms[wormid].votedMap)
                    return "map"
                else:
                    io.privateMsg(
                        wormid, "Invalid map, available maps: " +
                        ", ".join(io.listMaps())
                    )  #NOTE: This generates a very spammy message...

            #Quick map voting
            if cmd == "m":
                if not params:
                    io.privateMsg(
                        wormid,
                        "No map specified, try %smaphelp for a list of options"
                        % cfg.USER_PREFIX)
                elif params[0].lower() in presetcfg.MAP_SHORTCUTS.keys():
                    hnd.worms[wormid].votedMap = presetcfg.MAP_SHORTCUTS[
                        params[0].lower()]
                    io.privateMsg(
                        wormid,
                        "You voted for %s" % hnd.worms[wormid].votedMap)
                    return "map"
                else:
                    io.privateMsg(
                        wormid,
                        "Invalid map option, try %smaphelp for a list of available options"
                        % cfg.USER_PREFIX)

        elif cfg.TEAMGAMES_VOTING and (cmd == "teams" or cmd == "noteams"):
            if cmd == "teams":
                hnd.worms[wormid].votedTeams = 1
                io.privateMsg(wormid, "You voted for team game!")
            elif cmd == "noteams":
                hnd.worms[wormid].votedTeams = 0
                io.privateMsg(wormid, "You voted for deathmatch!")
            return "teams"

        #Team shuffling
        elif cmd == "shuffle" and cfg.TEAM_SHUFFLE:
            #Not TDM
            if io.getGameType() != 1:
                io.privateMsg(wormid, "Not TDM - cannot shuffle")
            #Not in lobby
            elif hnd.gameState != hnd.GAME_LOBBY:
                io.privateMsg(wormid, "Cannot shuffle when not in lobby")
            #Too many shuffles
            elif hnd.shuffle_counter >= cfg.TEAM_SHUFFLE:
                io.privateMsg(wormid, "Shuffle limit already reached")
            else:
                hnd.shuffleTeams()
            #Not in lobby

        #TEST: Use this to check team status...
        #elif cfg.TEAMCHANGE_LOGGING and cmd == "teamtest":
        #	io.messageLog("TEAMTEST: teamtest called by player " + str(wormid), io.LOG_INFO)
        #	teamtestresult = str(hnd.getNumberWormsInAllTeams()).replace("[","").replace("]","").replace(","," ")
        #	io.privateMsg(wormid, "Team status is "+teamtestresult+" - is this reasonable?")
        #	return "none"

        else:
            raise Exception, "Invalid user command"

    except:  # All python classes derive from main "Exception", but confused me, this has the same effect.
        if wormid >= 0:
            io.privateMsg(
                wormid,
                "Invalid user command - type !help for list of commands")
        if cfg.USERCOMMAND_ERROR_LOGGING:
            io.messageLog(io.formatExceptionInfo(),
                          io.LOG_ERROR)  #Helps to fix errors
        return None
    return "none"
Beispiel #6
0
def updateVotes(send_msg=()):
    global gameState, oldGameState
    global vote_locked
    global worms, availablePresets

    votedMaps = {}
    votedPresets = {}
    teams_voted = 0
    teams_ready = False
    gametype_old = io.getGameType()

    #Reset kick vote counters to zero
    for w in worms.keys():
        worms[w].resetKickVotes()

    #Count all votes
    for w in worms.keys():
        #Count map votes
        if worms[w].votedMap:
            if not worms[w].votedMap in votedMaps.keys():
                votedMaps[worms[w].votedMap] = 1
            else:
                votedMaps[worms[w].votedMap] += 1
        #Count mod (preset) votes
        if worms[w].votedPreset:
            if not worms[w].votedPreset in votedPresets.keys():
                votedPresets[worms[w].votedPreset] = 1
            else:
                votedPresets[worms[w].votedPreset] += 1
        #Count kick votes for each player
        if worms[w].votedKick in worms.keys():
            worms[worms[w].votedKick].kickVoted += 1
        else:
            worms[
                w].votedKick = None  #If player is not on the server, remove vote
        #Count team votes
        if worms[w].votedTeams:
            teams_voted += 1

    #Find most voted ones
    mostVotedMap = ""
    mostVotedPreset = ""
    for m in votedMaps.keys():
        if not mostVotedMap:
            mostVotedMap = m
        else:
            if votedMaps[m] > votedMaps[mostVotedMap]:
                mostVotedMap = m
    for p in votedPresets.keys():
        if not mostVotedPreset:
            mostVotedPreset = p
        else:
            if votedPresets[p] > votedPresets[mostVotedPreset]:
                mostVotedPreset = p

    #Announce voting status
    if "map" in send_msg and mostVotedMap:
        io.chatMsg("Most voted map: " + mostVotedMap)
    if "mod" in send_msg and mostVotedPreset:
        io.chatMsg("Most voted preset: " + mostVotedPreset)

    #Check teamgame votes
    if len(worms) != 0 and (float(teams_voted) / float(
            len(worms))) * 100 >= cfg.VOTING_PERCENT and len(
                worms) >= cfg.MIN_PLAYERS_TEAMS:
        teams_ready = True
    else:
        teams_ready = False

    #Announce team voting status
    if "teams" in send_msg and teams_voted != 0:
        if teams_ready:
            io.chatMsg(
                "Team voting status: Looks like the next game will be Team Deathmatch!"
            )
        elif len(worms) < cfg.MIN_PLAYERS_TEAMS:
            io.chatMsg(
                "Team voting status: Not enough players for team game (" +
                str(cfg.MIN_PLAYERS_TEAMS) + " is minimum)")
        elif (float(teams_voted) /
              float(len(worms))) * 100 < cfg.VOTING_PERCENT:
            io.chatMsg(
                "Team voting status: Not enough votes for team game yet")

    #Check kick votes
    for w in worms.keys():
        if (float(worms[w].kickVoted) /
                float(len(worms))) * 100 > cfg.VOTING_PERCENT:
            kickWithTime(w, "other players voted to kick you")

    #If we are safely in lobby, load settings
    if gameState == GAME_LOBBY and not vote_locked:
        #Set map and preset
        if mostVotedMap:
            loadMap(mostVotedMap)
        if mostVotedPreset:
            loadPreset(mostVotedPreset)
        #Set team game
        if teams_ready:
            if io.getGameType() == 0:
                io.setvar("GameOptions.GameInfo.GameType", 1)
                setupTeams()
        else:
            io.setvar("GameOptions.GameInfo.GameType", 0)

    #Announce team game status if 1) it has not been announced and 2) game type has been changed
    if not "teams" in send_msg and gametype_old != io.getGameType():
        if teams_ready:
            io.chatMsg(
                "Team voting status: Looks like the next game will be Team Deathmatch!"
            )
        elif len(worms) < cfg.MIN_PLAYERS_TEAMS:
            io.chatMsg(
                "Team voting status: Not enough players for team game (" +
                str(cfg.MIN_PLAYERS_TEAMS) + " is minimum)")
        elif (float(teams_voted) /
              float(len(worms))) * 100 < cfg.VOTING_PERCENT:
            io.chatMsg("Team voting status: Not enough votes for team game")

    return (mostVotedMap, mostVotedPreset, int(teams_ready))
Beispiel #7
0
def parseChatMessage(sig):
    global worms

    wormID = int(sig[1])
    message = sig[2]

    #Length-based anti-spam - see dedicated_config for details
    if cfg.ANTISPAM != 0:
        if len(message) > cfg.ANTISPAM_KICKLIMIT:
            if cfg.ANTISPAM > 1 and len(message) > cfg.ANTISPAM_BANLIMIT:
                if cfg.ANTISPAM == 2:
                    kickWithTime(wormID, "excessive spamming")
                    return
                elif cfg.ANTISPAM == 3:
                    io.banWorm(wormID, "excessive spamming")
                    io.messageLog(
                        "Player " + worms[wormID].Name + " from IP " +
                        worms[wormID].Ip + " was banned for spamming",
                        io.LOG_INFO)
                    return
            else:
                io.kickWorm(wormID, "spamming")
                return

    #NEW: Impersonation protection - check if the player tries to impersonate another player using the newline tags.
    #NOTE: The "GOGO" spamfest taunt is whitelisted here!
    if cfg.ANTI_IMPERSONATION:
        if message not in cfg.ANTI_IMPERSONATION_WHITELIST and detectFormattingTags(
                message):
            #Warn the player and count the attempt
            io.privateMsg(wormID, cfg.ANTI_IMPERSONATION_CLIENT_WARNING)
            worms[wormID].tags_detected += 1
            #TODO HACK EXPERIMENTAL TEST: Check whether the message contains other players' nicknames - if yes, warn the other players
            for w in worms.keys():
                if w != wormID and (worms[w].real_name.strip() in message
                                    or worms[w].getCleanName().strip()
                                    in message):
                    if cfg.ANTI_IMPERSONATION_SERVER_WARNING:  #Do not broadcast warning if it doesn't exist
                        io.chatMsg(
                            cfg.ANTI_IMPERSONATION_SERVER_WARNING.replace(
                                "<player>",
                                worms[wormID].getCleanName()).replace(
                                    "<another>", worms[w].getCleanName()))
            #Apply sanctions
            if worms[wormID].tags_detected > cfg.ANTI_IMPERSONATION_LIMIT:
                if cfg.ANTI_IMPERSONATION_ACTION == 1:
                    io.kickWorm(wormID,
                                "used non-allowed formatting tags in chat")
                    return
                elif cfg.ANTI_IMPERSONATION_ACTION == 2:
                    kickWithTime(wormID,
                                 "used non-allowed formatting tags in chat")
                    return

    #Taunt antispam - see dedicated_config for details
    if cfg.TAUNT_ANTISPAM:
        for kw in cfg.TAUNT_KEYWORDS:
            if kw in message.lower():
                worms[wormID].spammed += 1
                io.privateMsg(wormID, cfg.TAUNT_ANTISPAM_WARNING)
                if worms[wormID].spammed > cfg.TAUNT_ANTISPAM_LIMIT:
                    if cfg.TAUNT_ANTISPAM == 1:
                        io.kickWorm(wormID, "spamming")
                    elif cfg.TAUNT_ANTISPAM == 2:
                        kickWithTime(wormID, "spamming")
                    return

    #Commands
    ret = None
    aret = None
    if worms[wormID].isAdmin and message.startswith(cfg.ADMIN_PREFIX):
        aret = cmds.parseAdminCommand(wormID, message)
    if message.startswith(cfg.USER_PREFIX):
        ret = cmds.parseUserCommand(wormID, message)

    if ret == "map":
        updateVotes(send_msg=("map", ))
    elif ret == "mod":
        updateVotes(send_msg=("mod", ))
    elif ret == "teams":
        updateVotes(send_msg=("teams", ))
    elif ret == "kick":  #Don't broadcast voting status if voted for kick
        updateVotes(send_msg=())
Beispiel #8
0
def controlHandlerDefault():

    global worms, gameState, lobbyChangePresetTimeout, lobbyWaitBeforeGame, lobbyWaitAfterGame
    global lobbyWaitGeneral, lobbyEnoughPlayers, oldGameState, scriptPaused, sentStartGame
    global currentAutocyclePreset, currentAutocycleMap
    global vote_locked, shuffle_counter

    if scriptPaused:
        return

    curTime = time.time()

    if gameState == GAME_LOBBY:

        # Do not check ping in lobby - it's wrong

        if oldGameState != GAME_LOBBY:
            lobbyEnoughPlayers = False  # reset the state
            lobbyWaitGeneral = curTime + cfg.WAIT_BEFORE_SPAMMING_TOO_FEW_PLAYERS_MESSAGE
            lobbyWaitAfterGame = curTime
            if oldGameState == GAME_PLAYING:
                lobbyWaitAfterGame = curTime + cfg.WAIT_AFTER_GAME

            #Reset shuffle counter
            shuffle_counter = 0

            #Update votes when game ends
            updateResult = updateVotes(send_msg=("map", "mod", "teams"))
            #Autocycle if not voted
            #Advance autocycle counters first
            if not updateResult[0]:
                currentAutocycleMap += 1
                if currentAutocycleMap >= len(cfg.LEVELS):
                    currentAutocycleMap = 0
            if not updateResult[1]:
                currentAutocyclePreset += 1
                if currentAutocyclePreset >= len(cfg.PRESETS):
                    currentAutocyclePreset = 0
            ##Map
            if not updateResult[0]:
                io.setvar("GameOptions.GameInfo.LevelName",
                          cfg.LEVELS[currentAutocycleMap])
            ##Mod (preset)
            if not updateResult[1]:
                loadPreset(cfg.PRESETS[currentAutocyclePreset])

            #Check if teams are balanced
            ##This should be done because teams may become uneven if people leave during game and BALANCE_TEAMS_INGAME is not set
            if io.getGameType() == 1:
                io.chatMsg("Checking if teams are even...")
                balanceTeams(bmsg="game ended")

        if lobbyWaitAfterGame <= curTime:

            if not lobbyEnoughPlayers and lobbyWaitGeneral <= curTime:
                lobbyWaitGeneral = curTime + cfg.WAIT_BEFORE_SPAMMING_TOO_FEW_PLAYERS_MESSAGE
                io.chatMsg(cfg.TOO_FEW_PLAYERS_MESSAGE)

            if not lobbyEnoughPlayers and len(
                    worms
            ) >= cfg.MIN_PLAYERS:  # Enough players already - start game
                lobbyEnoughPlayers = True
                io.chatMsg(cfg.WAIT_BEFORE_GAME_MESSAGE)
                lobbyWaitBeforeGame = curTime + cfg.WAIT_BEFORE_GAME

            if lobbyEnoughPlayers and len(
                    worms
            ) < cfg.MIN_PLAYERS:  # Some players left when game not yet started
                lobbyEnoughPlayers = False
                io.chatMsg(cfg.TOO_FEW_PLAYERS_MESSAGE)

            if lobbyEnoughPlayers and not sentStartGame:

                if lobbyWaitBeforeGame <= curTime:  # Start the game

                    #Starting game...		##NOTE Removed team check from here - teams should be assigned before the round starts
                    if io.startGame():
                        if cfg.ALLOW_TEAM_CHANGE and len(
                                worms) >= cfg.MIN_PLAYERS_TEAMS:
                            io.chatMsg(cfg.TEAM_CHANGE_MESSAGE)
                        sentStartGame = True
                        vote_locked = True  #Lock vote-able settings when starting
                        clearVotes()  #Clear votes when starting
                    else:
                        io.messageLog("Game could not be started",
                                      io.LOG_ERROR)  #Log these errors!
                        io.chatMsg("Game could not be started")
                        oldGameState == GAME_PLAYING  # hack that it resets at next control handler call

    if gameState == GAME_WEAPONS:

        # if we allow empty games, ignore this check
        if len(worms) < cfg.MIN_PLAYERS and not io.getVar(
                "GameOptions.GameInfo.AllowEmptyGames"
        ):  # Some players left when game not yet started
            io.chatMsg("Too few players -> back to lobby")
            io.gotoLobby()
            sentStartGame = False

    if gameState == GAME_PLAYING:

        if cfg.PING_CHECK:
            checkMaxPing()

    #Unlock voting when the game is safely running
    if (gameState == GAME_WEAPONS or gameState
            == GAME_PLAYING) and oldGameState != GAME_LOBBY and vote_locked:
        vote_locked = False
def controlHandlerDefault():

    global worms, gameState, lobbyChangePresetTimeout, lobbyWaitBeforeGame, lobbyWaitAfterGame
    global lobbyWaitGeneral, lobbyEnoughPlayers, oldGameState, scriptPaused, sentStartGame
    global presetCicler, modCicler, mapCicler, LT_Cicler
    global videoRecorder, videoRecorderSignalTime

    if scriptPaused:
        return

    curTime = time.time()
    cmds.recheckVote(False)

    if gameState == GAME_LOBBY:

        # Do not check ping in lobby - it's wrong

        if oldGameState != GAME_LOBBY:
            mapCicler.check()
            modCicler.check()
            LT_Cicler.check()
            presetCicler.check()
            lobbyEnoughPlayers = False  # reset the state
            lobbyWaitGeneral = curTime + cfg.WAIT_BEFORE_SPAMMING_TOO_FEW_PLAYERS_MESSAGE
            lobbyWaitAfterGame = curTime
            if oldGameState == GAME_PLAYING:
                lobbyWaitAfterGame = curTime + cfg.WAIT_AFTER_GAME
            if videoRecorder:
                os.kill(
                    videoRecorder.pid, signal.SIGINT
                )  # videoRecorder.send_signal(signal.SIGINT) # This is available only on Python 2.6
                videoRecorderSignalTime = time.time()
                io.chatMsg("Waiting for video recorder to finish")

        canStart = True
        if videoRecorder and videoRecorder.returncode == None:
            canStart = False
            videoRecorder.poll()
            if time.time(
            ) - videoRecorderSignalTime > cfg.TIME_TO_KILL_VIDEORECORDER:
                io.chatMsg("Video recorder stalled, killing")
                os.kill(videoRecorder.pid, signal.SIGKILL)
                videoRecorder.poll()
            if videoRecorder.returncode != None:
                io.chatMsg("Video recorder encoding took " +
                           str(int(time.time() - videoRecorderSignalTime)) +
                           " secs")
                canStart = True
                videoRecorder = None

        if lobbyWaitAfterGame <= curTime:

            if not lobbyEnoughPlayers and lobbyWaitGeneral <= curTime:
                lobbyWaitGeneral = curTime + cfg.WAIT_BEFORE_SPAMMING_TOO_FEW_PLAYERS_MESSAGE
                io.chatMsg(cfg.TOO_FEW_PLAYERS_MESSAGE)

            if not lobbyEnoughPlayers and len(
                    worms
            ) >= cfg.MIN_PLAYERS:  # Enough players already - start game
                lobbyEnoughPlayers = True
                io.chatMsg(cfg.WAIT_BEFORE_GAME_MESSAGE)
                lobbyWaitBeforeGame = curTime + cfg.WAIT_BEFORE_GAME

            if lobbyEnoughPlayers and len(
                    worms
            ) < cfg.MIN_PLAYERS:  # Some players left when game not yet started
                lobbyEnoughPlayers = False
                io.chatMsg(cfg.TOO_FEW_PLAYERS_MESSAGE)

            if lobbyEnoughPlayers and not sentStartGame:

                if lobbyWaitBeforeGame <= curTime and canStart:  # Start the game

                    if io.getGameType() in ["Death Match", "Team Death Match"]:
                        if len(worms
                               ) >= cfg.MIN_PLAYERS_TEAMS:  # Split in teams
                            setvar("GameOptions.GameInfo.GameType",
                                   "Team Death Match")
                            if not cfg.ALLOW_TEAM_CHANGE:
                                counter = 0
                                for w in worms.values():
                                    if w.iID != -1:
                                        io.setWormTeam(w.iID,
                                                       counter % cfg.MAX_TEAMS)
                                        counter += 1
                        else:
                            io.setvar("GameOptions.GameInfo.GameType",
                                      "Death Match")

                    if io.startGame():
                        if cfg.ALLOW_TEAM_CHANGE and len(
                                worms) >= cfg.MIN_PLAYERS_TEAMS:
                            io.chatMsg(cfg.TEAM_CHANGE_MESSAGE)
                        sentStartGame = True
                        if cfg.RECORD_VIDEO:
                            try:
                                #io.messageLog("Running dedicated-video-record.sh, curdir " + os.path.abspath(os.path.curdir) ,io.LOG_INFO)
                                videoRecorder = subprocess.Popen(
                                    [
                                        "./dedicated-video-record.sh",
                                        "./dedicated-video-record.sh"
                                    ],
                                    stdin=open("/dev/null", "r"),
                                    stdout=open("../../../dedicatedVideo.log",
                                                "w"),
                                    stderr=subprocess.STDOUT,
                                    cwd="..")
                            except:
                                io.messageLog(formatExceptionInfo(),
                                              io.LOG_ERROR)
                    else:
                        io.chatMsg("Game could not be started")
                        oldGameState == GAME_PLAYING  # hack that it resets at next control handler call

    if gameState == GAME_WEAPONS:

        #checkMaxPing()

        # if we allow empty games, ignore this check
        if len(worms) < cfg.MIN_PLAYERS and not io.getVar(
                "GameOptions.GameInfo.AllowEmptyGames"
        ):  # Some players left when game not yet started
            io.chatMsg("Too less players -> back to lobby")
            io.gotoLobby()
            sentStartGame = False

    if gameState == GAME_PLAYING:

        checkMaxPing()
def controlHandlerDefault():

	global worms, gameState, lobbyChangePresetTimeout, lobbyWaitBeforeGame, lobbyWaitAfterGame
	global lobbyWaitGeneral, lobbyEnoughPlayers, oldGameState, scriptPaused, sentStartGame
	global presetCicler, modCicler, mapCicler, LT_Cicler
	global videoRecorder, videoRecorderSignalTime
	
	if scriptPaused:
		return

	curTime = time.time()
	cmds.recheckVote(False)
	
	if gameState == GAME_LOBBY:

		# Do not check ping in lobby - it's wrong

		if oldGameState != GAME_LOBBY:
			mapCicler.check()
			modCicler.check()
			LT_Cicler.check()
			presetCicler.check()
			lobbyEnoughPlayers = False # reset the state
			lobbyWaitGeneral = curTime + cfg.WAIT_BEFORE_SPAMMING_TOO_FEW_PLAYERS_MESSAGE
			lobbyWaitAfterGame = curTime
			if oldGameState == GAME_PLAYING:
				lobbyWaitAfterGame = curTime + cfg.WAIT_AFTER_GAME
			if videoRecorder:
				os.kill(videoRecorder.pid, signal.SIGINT)  # videoRecorder.send_signal(signal.SIGINT) # This is available only on Python 2.6
				videoRecorderSignalTime = time.time()
				io.chatMsg("Waiting for video recorder to finish")

		canStart = True
		if videoRecorder and videoRecorder.returncode == None:
			canStart = False
			videoRecorder.poll()
			if time.time() - videoRecorderSignalTime > cfg.TIME_TO_KILL_VIDEORECORDER:
				io.chatMsg("Video recorder stalled, killing")
				os.kill(videoRecorder.pid, signal.SIGKILL)
				videoRecorder.poll()
			if videoRecorder.returncode != None:
				io.chatMsg("Video recorder encoding took " + str(int(time.time() - videoRecorderSignalTime)) + " secs")
				canStart = True
				videoRecorder = None

		if lobbyWaitAfterGame <= curTime:

			if not lobbyEnoughPlayers and lobbyWaitGeneral <= curTime:
				lobbyWaitGeneral = curTime + cfg.WAIT_BEFORE_SPAMMING_TOO_FEW_PLAYERS_MESSAGE
				io.chatMsg(cfg.TOO_FEW_PLAYERS_MESSAGE)

			if not lobbyEnoughPlayers and len(worms) >= cfg.MIN_PLAYERS: # Enough players already - start game
				lobbyEnoughPlayers = True
				io.chatMsg(cfg.WAIT_BEFORE_GAME_MESSAGE)
				lobbyWaitBeforeGame = curTime + cfg.WAIT_BEFORE_GAME

			if lobbyEnoughPlayers and len(worms) < cfg.MIN_PLAYERS: # Some players left when game not yet started
				lobbyEnoughPlayers = False
				io.chatMsg(cfg.TOO_FEW_PLAYERS_MESSAGE)

			if lobbyEnoughPlayers and not sentStartGame:

				if lobbyWaitBeforeGame <= curTime and canStart: # Start the game

					if io.getGameType() in ["Death Match","Team Death Match"]:
						if len(worms) >= cfg.MIN_PLAYERS_TEAMS: # Split in teams
							setvar("GameOptions.GameInfo.GameType", "Team Death Match")
							if not cfg.ALLOW_TEAM_CHANGE:
								counter = 0
								for w in worms.values():
									if w.iID != -1:
										io.setWormTeam( w.iID, counter % cfg.MAX_TEAMS )
										counter += 1
						else:
							io.setvar("GameOptions.GameInfo.GameType", "Death Match")

					if io.startGame():
						if cfg.ALLOW_TEAM_CHANGE and len(worms) >= cfg.MIN_PLAYERS_TEAMS:
							io.chatMsg(cfg.TEAM_CHANGE_MESSAGE)
						sentStartGame = True
						if cfg.RECORD_VIDEO:
							try:
								#io.messageLog("Running dedicated-video-record.sh, curdir " + os.path.abspath(os.path.curdir) ,io.LOG_INFO)
								videoRecorder = subprocess.Popen( ["./dedicated-video-record.sh", "./dedicated-video-record.sh"],
												stdin=open("/dev/null","r"), stdout=open("../../../dedicatedVideo.log","w"),
												stderr=subprocess.STDOUT, cwd=".." )
							except:
								io.messageLog(formatExceptionInfo(),io.LOG_ERROR)
					else:
						io.chatMsg("Game could not be started")
						oldGameState == GAME_PLAYING # hack that it resets at next control handler call
					
	if gameState == GAME_WEAPONS:

		#checkMaxPing()

		# if we allow empty games, ignore this check
		if len(worms) < cfg.MIN_PLAYERS and not io.getVar("GameOptions.GameInfo.AllowEmptyGames"): # Some players left when game not yet started
			io.chatMsg("Too less players -> back to lobby")
			io.gotoLobby()
			sentStartGame = False

	if gameState == GAME_PLAYING:

		checkMaxPing()