def parseWormLeft(sig):
    global worms, scriptPaused

    wormID = int(sig[1])
    name = sig[2:]

    try:
        if worms[wormID].isAdmin:
            io.messageLog(
                ("Worm %i (%s) removed from admins" % (wormID, name)),
                io.LOG_ADMIN)
    except KeyError:
        io.messageLog(
            "AdminRemove: Our local copy of wormses doesn't match the real list.",
            io.LOG_ERROR)

    # Call last, that way we still have the data active.
    worms.pop(wormID)

    cmds.recheckVote()

    # If all admins left unpause ded server (or it will be unusable)
    isAdmins = False
    for w in worms.keys():
        if worms[w].isAdmin:
            isAdmins = True
    if not isAdmins:
        scriptPaused = False
Beispiel #2
0
def setTeam(wormid, team):
    if wormid in worms.keys() and worms[wormid].iID != -1:
        worms[wormid].Team = team
        io.setWormTeam(wormid, team)
        if cfg.TEAMCHANGE_LOGGING:
            io.messageLog(
                "TEAMCHANGE: Set worm " + str(wormid) + " " +
                worms[wormid].Name + " to team " + str(team), io.LOG_INFO)
    else:
        io.messageLog("Worm id %i invalid" % wormid, LOG_ADMIN)
Beispiel #3
0
def checkConfigLists():

    availableMapList = io.listMaps()

    for l in cfg.LEVELS:
        if l not in availableMapList:
            io.messageLog("Autocycle map not found: %s" % l, io.LOG_ERROR)

    for k in presetcfg.MAP_SHORTCUTS.values():
        if k not in availableMapList:
            io.messageLog("Shortcut map not found: %s" % k, io.LOG_ERROR)
Beispiel #4
0
def setupTeams():
    global worms

    if cfg.TEAMCHANGE_LOGGING:
        io.messageLog("TEAMSETUP: setupTeams called", io.LOG_INFO)

    counter = 0
    for w in worms.values():
        if w.iID != -1:
            setTeam(w.iID, counter % cfg.MAX_TEAMS)
            counter += 1
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 parseWormAuthorized(sig):	
	global worms

	wormID = int(sig[1])
	try:
		if not worms[wormID].isAdmin:
			worms[wormID].isAdmin = True
			io.messageLog(("Worm %i (%s) added to admins" % (wormID,worms[wormID].Name)),io.LOG_ADMIN)
			# TODO: Send the last part in a PM to the admin. (Needs new backend for private messaging. Add teamchat too!)
			io.authorizeWorm(wormID)
			io.privateMsg(wormID, "%s authenticated for admin! Type %shelp for command info" % (worms[wormID].Name,cfg.ADMIN_PREFIX))
	except KeyError:
		io.messageLog("AdminAdd: Our local copy of wormses doesn't match the real list.",io.LOG_ERROR)
Beispiel #7
0
def parseWormDied(sig):
    global worms

    deaderID = int(sig[1])
    killerID = int(sig[2])
    worms[deaderID].Lives -= 1
    worms[deaderID].Alive = False

    if not cfg.RANKING:
        return

    try:
        rank_file_path = io.getWriteFullFileName(cfg.RANKING_FILE)
        f = open(rank_file_path, "a")
        if not killerID in io.getComputerWormList():
            try:
                portalocker.lock(f, portalocker.LOCK_EX)
            except:
                pass
            f.write(
                time.strftime("%Y-%m-%d %H:%M:%S") + "\t" +
                worms[deaderID].Name + "\t" + worms[killerID].Name + "\n")
        f.close()
    except IOError:
        io.messageLog(
            "parseWormDied: Unable to open ranking file: " + cfg.RANKING_FILE +
            " from path: " + rank_file_path, io.LOG_ERROR)

    if not killerID in io.getComputerWormList():
        if deaderID == killerID:
            try:
                ranking.rank[worms[killerID].Name][2] += 1
            except KeyError:
                ranking.rank[worms[killerID].Name] = [
                    0, 0, 1, len(ranking.rank) + 1
                ]
        else:
            try:
                ranking.rank[worms[killerID].Name][0] += 1
            except KeyError:
                ranking.rank[worms[killerID].Name] = [
                    1, 0, 0, len(ranking.rank) + 1
                ]
    if not deaderID in io.getComputerWormList():
        try:
            ranking.rank[worms[deaderID].Name][1] += 1
        except KeyError:
            ranking.rank[worms[deaderID].Name] = [
                0, 1, 0, len(ranking.rank) + 1
            ]
def initPresets():
	global availablePresets

	# Reset - incase we get called a second time
	availablePresets = []

	for f in os.listdir(presetDir):
		if f.lower() != "defaults" and f.lower() != ".svn":
			availablePresets.append(f)

	for p in cfg.PRESETS:
		if availablePresets.count(p) == 0:
			availablePresets.append(p)

	if (len(availablePresets) == 0):
		io.messageLog("There are no presets available - nothing to do. Exiting.",io.LOG_CRITICAL)
		exit()
Beispiel #9
0
def parseWormLeft(sig):
    global worms, gameState, scriptPaused

    wormID = int(sig[1])
    name = sig[2:]

    try:
        if worms[wormID].isAdmin:
            io.messageLog(
                ("Worm %i (%s) removed from admins" % (wormID, name)),
                io.LOG_ADMIN)
    except KeyError:
        io.messageLog(
            "AdminRemove: Our local copy of wormses doesn't match the real list.",
            io.LOG_ERROR)

    #NOTE: There may be a better way to do this...
    #Check which vote options to broadcast when this player leaves
    temp_votedstatus = []
    if wormID in worms.keys(
    ):  #Note: this should be always true but checked anyway...
        if worms[wormID].votedMap:
            temp_votedstatus.append("map")
        if worms[wormID].votedPreset:
            temp_votedstatus.append("mod")
        #NOTE: No need to check team votes here because team status will be checked separately.

    # Call last, that way we still have the data active.
    worms.pop(wormID)

    #Update voting status after removing this player from the worms table
    updateVotes(send_msg=tuple(temp_votedstatus))

    #Balance teams
    if io.getGameType() == 1:
        if gameState == GAME_LOBBY or cfg.BALANCE_TEAMS_INGAME:
            balanceTeams(bmsg="player left")

    # If all admins left unpause ded server (or it will be unusable)
    isAdmins = False
    for w in worms.keys():
        if worms[w].isAdmin:
            isAdmins = True
    if not isAdmins:
        scriptPaused = False
def init():
	initPresets()

	io.startLobby(cfg.SERVER_PORT)

	# if we load this script with already some worms on board, we have to update our worm list now
	for w in io.getWormList():
		parseNewWorm( w, io.getWormName(w) )

	global GLOBAL_SETTINGS;
	for f in GLOBAL_SETTINGS.keys():
		io.setvar( f, GLOBAL_SETTINGS[f] )
	for f in cfg.GLOBAL_SETTINGS.keys():
		io.setvar( f, cfg.GLOBAL_SETTINGS[f] )
	
	if io.getVar("GameOptions.GameInfo.AllowEmptyGames") == "false" and cfg.MIN_PLAYERS < 2:
		io.messageLog("GameOptions.GameInfo.AllowEmptyGames is false - setting cfg.MIN_PLAYERS to 2", io.LOG_WARN)
		cfg.MIN_PLAYERS = 2
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 initPresets():
    global availablePresets

    # Reset - incase we get called a second time
    availablePresets = []

    for f in os.listdir(presetDir):
        if f.lower() != "defaults" and f.lower() != ".svn":
            availablePresets.append(f)

    for p in cfg.PRESETS:
        if availablePresets.count(p) == 0:
            availablePresets.append(p)

    if (len(availablePresets) == 0):
        io.messageLog(
            "There are no presets available - nothing to do. Exiting.",
            io.LOG_CRITICAL)
        exit()
Beispiel #13
0
def parseWormAuthorized(sig):
    global worms

    wormID = int(sig[1])
    try:
        if not worms[wormID].isAdmin:
            worms[wormID].isAdmin = True
            io.messageLog(("Worm %i (%s) added to admins" %
                           (wormID, worms[wormID].Name)), io.LOG_ADMIN)
            # TODO: Send the last part in a PM to the admin. (Needs new backend for private messaging. Add teamchat too!)
            io.authorizeWorm(wormID)
            io.privateMsg(
                wormID,
                "%s authenticated for admin! Type %shelp for command info" %
                (worms[wormID].Name, cfg.ADMIN_PREFIX))
    except KeyError:
        io.messageLog(
            "AdminAdd: Our local copy of wormses doesn't match the real list.",
            io.LOG_ERROR)
Beispiel #14
0
def init():

    checkConfigLists()
    initPresets()

    io.startLobby(cfg.SERVER_PORT)

    # if we load this script with already some worms on board, we have to update our worm list now
    for w in io.getWormList():
        parseNewWorm(w, io.getWormName(w))

    for f in cfg.GLOBAL_SETTINGS.keys():
        io.setvar(f, cfg.GLOBAL_SETTINGS[f])

    if io.getVar("GameOptions.GameInfo.AllowEmptyGames"
                 ) == "false" and cfg.MIN_PLAYERS < 2:
        io.messageLog(
            "GameOptions.GameInfo.AllowEmptyGames is false - setting cfg.MIN_PLAYERS to 2",
            io.LOG_WARN)
        cfg.MIN_PLAYERS = 2
Beispiel #15
0
def getNumberWormsInAllTeams():
    ret = [0, 0, 0, 0]
    for t in range(0, 4):
        ret[t] = getNumberWormsInTeam(t)
    #Check whether the handler and the game are reporting the same number of players per team
    if cfg.TEAMCHANGE_LOGGING:
        testret = [0, 0, 0, 0]
        for w in worms.values():
            testret[w.Team] += 1
        #Only 4 teams so we can do ugly hard-coded check
        if (ret[0] == testret[0] and ret[1] == testret[1]
                and ret[2] == testret[2] and ret[3] == testret[3]):
            testmsg = "everything is OK."
        else:
            testmsg = "THERE IS AN ERROR!"
        io.messageLog(
            "TEAMSTATUS: Game reports " + str(ret) + ", handler counts " +
            str(testret) + " -- " + testmsg, io.LOG_INFO)

    return ret
Beispiel #16
0
def shuffleTeams():
    global worms, shuffle_counter

    if cfg.TEAMCHANGE_LOGGING:
        io.messageLog("TEAMSHUFFLE: shuffleTeams called", io.LOG_INFO)

    # Create team mask
    tmask = []
    for k in range(0, len(worms)):
        tmask.append(k % cfg.MAX_TEAMS)
    # Shuffle it
    random.shuffle(tmask)

    # Assign teams
    k = 0
    for w in worms.values():
        setTeam(w.iID, tmask[k])
        k += 1

    #Advance counter
    shuffle_counter += 1
	def apply(self):
		if not self.curSelection: return
		StandardCiclerBase.apply(self)

		global availablePresets, presetDir

		sDefaults = os.path.join(presetDir,"Defaults")
		try:
			execfile(sDefaults)
		except:
			io.messageLog("Error in preset: " + str(formatExceptionInfo()),io.LOG_ERROR)

		sFile = os.path.join(presetDir,self.curSelection)
		try:
			fPreset = file(sFile,"r")
			line = fPreset.readline()
			if line.find("python") != -1:
				fPreset.close()
				execfile(sFile)
			else:
				print line.strip().replace('"','')
				for line in fPreset.readlines():
					print line.strip().replace('"','')
				fPreset.close()
		except IOError:
			# File does not exist, perhaps it was removed.
			io.messageLog(("Unable to load %s, forcing rehash of all presets" % sFile),io.LOG_WARN)
			initPresets()
		except:
			io.messageLog("Error in preset: " + str(formatExceptionInfo()),io.LOG_ERROR)
    def apply(self):
        if not self.curSelection: return
        StandardCiclerBase.apply(self)

        global availablePresets, presetDir

        sDefaults = os.path.join(presetDir, "Defaults")
        try:
            execfile(sDefaults)
        except:
            io.messageLog("Error in preset: " + str(formatExceptionInfo()),
                          io.LOG_ERROR)

        sFile = os.path.join(presetDir, self.curSelection)
        try:
            fPreset = file(sFile, "r")
            line = fPreset.readline()
            if line.find("python") != -1:
                fPreset.close()
                execfile(sFile)
            else:
                print line.strip().replace('"', '')
                for line in fPreset.readlines():
                    print line.strip().replace('"', '')
                fPreset.close()
        except IOError:
            # File does not exist, perhaps it was removed.
            io.messageLog(
                ("Unable to load %s, forcing rehash of all presets" % sFile),
                io.LOG_WARN)
            initPresets()
        except:
            io.messageLog("Error in preset: " + str(formatExceptionInfo()),
                          io.LOG_ERROR)
Beispiel #19
0
def balanceTeams(bmsg=""):
    global worms

    if cfg.TEAMCHANGE_LOGGING:
        if bmsg:
            io.messageLog("TEAMBALANCE: balanceTeams called: " + bmsg,
                          io.LOG_INFO)
        else:
            io.messageLog(
                "TEAMBALANCE: balanceTeams called without reason given",
                io.LOG_INFO)

    while True:
        team_status = getNumberWormsInAllTeams()
        team_status = team_status[0:cfg.MAX_TEAMS]  #truncate list
        if (max(team_status) - min(team_status)) > 1:
            maxteam = team_status.index(
                max(team_status))  #team with most members
            minteam = team_status.index(
                min(team_status))  #team with least members
            for w in worms.values():
                if io.getWormTeam(w.iID) == maxteam:
                    setTeam(
                        w.iID,
                        minteam)  #move player from biggest team to smallest
                    break
        else:  #If the difference is 1 or less, no need to do changes
            break
    #Log the team status after balancing
    if cfg.TEAMCHANGE_LOGGING:
        io.messageLog("TEAMBALANCE: balance ended, calling for teamstatus...",
                      io.LOG_INFO)
        getNumberWormsInAllTeams()
Beispiel #20
0
def ParseAuthInfo():

	try:
		rank_auth_file_path = io.getWriteFullFileName(cfg.RANKING_AUTH_FILE)
		f = open(rank_auth_file_path,"r")
	except IOError:
		io.messageLog("ParseAuthInfo: Unable to open ranking authentication file: " + cfg.RANKING_AUTH_FILE + " from path: " + rank_auth_file_path, io.LOG_ERROR)
		return {}

	authInfo = {}

	l = f.readline()
	while l != "":
		l = l.strip()
		if not (l.count("\t") == 1):
			l = f.readline()
			continue
		( worm, auth ) = l.split("\t")
		auth = auth.split(" ")
		authInfo[worm] = ( int(auth[0]), " ".join(auth[1:]).lower() )
		l = f.readline()
	f.close()
	return authInfo
def parseWormLeft(sig):
	global worms, scriptPaused

	wormID = int(sig[1])
	name = sig[2:]

	try:
		if worms[wormID].isAdmin:
			io.messageLog(("Worm %i (%s) removed from admins" % (wormID,name)),io.LOG_ADMIN)
	except KeyError:
		io.messageLog("AdminRemove: Our local copy of wormses doesn't match the real list.",io.LOG_ERROR)

	# Call last, that way we still have the data active.
	worms.pop(wormID)

	cmds.recheckVote()

	# If all admins left unpause ded server (or it will be unusable)
	isAdmins = False
	for w in worms.keys():
		if worms[w].isAdmin:
			isAdmins = True
	if not isAdmins:
		scriptPaused = False
Beispiel #22
0
def initPresets():
    global availablePresets

    # Reset - incase we get called a second time
    availablePresets = []

    if len(cfg.PRESETS) == 0:
        for f in presetcfg.MOD_PRESETS.keys():
            availablePresets.append(f)
    else:
        for p in cfg.PRESETS:
            if p not in presetcfg.MOD_PRESETS.keys():
                io.messageLog(
                    "Preset error - %s not found in preset table." % p,
                    io.LOG_WARN)
            else:
                if not p in availablePresets:
                    availablePresets.append(p)

    if (len(availablePresets) == 0):
        io.messageLog(
            "There are no presets available - nothing to do. Exiting.",
            io.LOG_CRITICAL)
        exit()
def signalHandler(sig):
	global gameState, oldGameState, scriptPaused, sentStartGame, worms

	oldGameState = gameState

	if len(sig) == 0:
		return False #Didn't get anything
		
	header = sig[0]
	
	try:
		if header == "newworm":
			parseNewWorm(int(sig[1]), sig[2])
		elif header == "wormleft":
			parseWormLeft(sig)
		elif header == "privatemessage":
			parsePrivateMessage(sig)
		elif header == "chatmessage":
			parseChatMessage(sig)
		elif header == "wormdied":
			parseWormDied(sig)
		elif header == "wormspawned":
			parseWormSpawned(sig)
		elif header == "wormauthorized":
			parseWormAuthorized(sig)
		elif header == "wormgotadmin":
			worms[int(sig[1])].isDedAdmin = True
			# no other difference to wormauthorized yet - and we also get wormauthorized, so nothing to do anymore
			pass
			
		## Check GameState ##
		elif header == "quit":
			gameState = GAME_QUIT
			exit()
	
		elif header == "backtolobby" or header == "lobbystarted":
			if cfg.RANKING:
				ranking.refreshRank()
			gameState = GAME_LOBBY
			sentStartGame = False
			controlHandler()
	
		elif header == "weaponselections":
			gameState = GAME_WEAPONS
			controlHandler()
		elif header == "gamestarted":
			gameState = GAME_PLAYING
			sentStartGame = False
			controlHandler()
		#TODO: gamestarted && gameloopstart are pretty much duplicates
		# Or are they? Check.
		# Same thing for gameloopend and backtolobby
		elif header == "gameloopstart": #Sent when game starts
			pass
		elif header == "gameloopend": #Sent at game end
			pass
		elif header == "gameloopend": #Sent when OLX starts
			pass
		elif header == "timer": # Sent once per second
			controlHandler()
			
		elif header == "custom":
			parseCustom(sig)
			
		else:
			io.messageLog(("I don't understand %s." % (sig)),io.LOG_ERROR)
	
	except Exception:
		traceback.print_exc(None, sys.stderr)

	return True
Beispiel #24
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=())
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()
Beispiel #26
0
		rank[k] = [oldrank[k][0],oldrank[k][1],oldrank[k][2],count]

def ParseAuthInfo():

	try:
		rank_auth_file_path = io.getWriteFullFileName(cfg.RANKING_AUTH_FILE)
		f = open(rank_auth_file_path,"r")
	except IOError:
		io.messageLog("ParseAuthInfo: Unable to open ranking authentication file: " + cfg.RANKING_AUTH_FILE + " from path: " + rank_auth_file_path, io.LOG_ERROR)
		return {}

	authInfo = {}

	l = f.readline()
	while l != "":
		l = l.strip()
		if not (l.count("\t") == 1):
			l = f.readline()
			continue
		( worm, auth ) = l.split("\t")
		auth = auth.split(" ")
		authInfo[worm] = ( int(auth[0]), " ".join(auth[1:]).lower() )
		l = f.readline()
	f.close()
	return authInfo

io.messageLog("Ranking: Parsing rank data")
rank = ParseRank()
auth = ParseAuthInfo()
io.messageLog("Ranking: Rank data parsing completed")
def parseUserCommand(wormid, message):
    global kickedUsers
    try:  # Do not check on msg size or anything, exception handling is further down
        if message in [
                "y", "n", "start", "stop", "rank", "toprank", "ranktotal"
        ]:
            # Single-word usercommands for faster typing
            cmd = message
        else:
            if (not message.startswith(cfg.USER_PREFIX)):
                return False  # normal chat

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

        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)

        if cfg.ALLOW_TEAM_CHANGE and cmd == "team":
            if not params:
                io.privateMsg(wormid, "You need to specify a team")
                raise Exception, "You need to specify a team"
            else:
                if params[0].lower() == "blue" or params[0].lower() == "b":
                    io.setWormTeam(wormid, 0)
                elif params[0].lower() == "red" or params[0].lower() == "r":
                    io.setWormTeam(wormid, 1)
                elif (params[0].lower() == "green"
                      or params[0].lower() == "g") and cfg.MAX_TEAMS >= 3:
                    io.setWormTeam(wormid, 2)
                elif (params[0].lower() == "yellow"
                      or params[0].lower() == "y") and cfg.MAX_TEAMS >= 4:
                    io.setWormTeam(wormid, 3)

        if cfg.RANKING:
            if cmd == "toprank":
                ranking.firstRank(wormid)
            if cmd == "rank":
                if wormid in hnd.worms:
                    wormName = hnd.worms[wormid].Name
                    if params:
                        wormName = " ".join(params)
                    ranking.myRank(wormName, wormid)
            if cmd == "ranktotal":
                io.privateMsg(
                    wormid, "There are " + str(len(ranking.rank)) +
                    " players in the ranking.")

        if cfg.VOTING:

            if cmd == "kick":
                kicked = int(params[0])
                if not kicked in hnd.worms.keys():
                    raise Exception, "Invalid worm ID"
                addVote(
                    "io.kickWorm(" + str(kicked) + ", 'You are kicked for " +
                    str(cfg.VOTING_KICK_TIME) + " minutes')", wormid,
                    "Kick %i: %s" % (kicked, hnd.worms[kicked].Name))
                hnd.worms[kicked].Voted = -1

            if cmd == "mute":
                if not kicked in hnd.worms.keys():
                    raise Exception, "Invalid worm ID"
                kicked = int(params[0])
                addVote("io.muteWorm(" + str(kicked) + ")", wormid,
                        "Mute %i: %s" % (kicked, hnd.worms[kicked].Name))
                hnd.worms[kicked].Voted = -1

            if cmd == "mod":

                # Users are proven to be stupid and can't tell the difference between mod and preset
                # so here we're first looking for a preset, and then looking for a mod with the same name if preset not found
                # (well, let's call that UI simplification)
                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:
                    addVote(
                        'hnd.selectPreset( Preset = "%s" )' %
                        hnd.availablePresets[preset], wormid,
                        "Preset %s" % hnd.availablePresets[preset])
                else:
                    mod = ""
                    for m in io.listMods():
                        if m.lower().find(" ".join(params[0:]).lower()) != -1:
                            mod = m
                            break
                    if mod == "":
                        io.privateMsg(
                            wormid, "Invalid mod, available mods: " +
                            ", ".join(hnd.availablePresets) +
                            ", ".join(io.listMods()))
                    else:
                        addVote('hnd.selectPreset( Mod = "%s" )' % mod, wormid,
                                "Mod %s" % mod)

            if cmd == "map":
                level = ""
                for l in io.listMaps():
                    if l.lower().find(" ".join(params[0:]).lower()) != -1:
                        level = l
                        break
                if level == "":
                    io.privateMsg(
                        wormid, "Invalid map, available maps: " +
                        ", ".join(io.listMaps()))
                else:
                    addVote('hnd.selectPreset( Level = "%s" )' % level, wormid,
                            "Map %s" % level)

            if cmd == "lt":
                addVote('hnd.selectPreset( LT = %i )' % int(params[0]), wormid,
                        "Loading time %i" % int(params[0]))

            if cmd == "start":
                addVote(
                    'hnd.lobbyWaitAfterGame = time.time(); hnd.lobbyWaitBeforeGame = time.time()',
                    wormid, "Start game now")

            if cmd == "stop":
                addVote('io.gotoLobby()', wormid, "Go to lobby")

            if (cmd == "y" or cmd == "yes"):
                if hnd.worms[wormid].Voted != 1:
                    hnd.worms[wormid].Voted = 1
                    recheckVote()
            if (cmd == "n" or cmd == "no"):
                if hnd.worms[wormid].Voted != -1:
                    hnd.worms[wormid].Voted = -1
                    recheckVote()

        elif parseUserCommand_Preset and parseUserCommand_Preset(
                wormid, cmd, params):
            pass
        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")
        io.messageLog(formatExceptionInfo(),
                      io.LOG_ERROR)  #Helps to fix errors
        return False
    return True
Beispiel #28
0
def ParseRank(useRatios = True):
	#io.messageLog("ParseRank: Opening ranking file: " + cfg.RANKING_FILE, io.LOG_INFO)
	try:
		rank_file_path = io.getWriteFullFileName(cfg.RANKING_FILE)
		f = open(rank_file_path,"r")
	except IOError:
		io.messageLog("ParseRank: Unable to open ranking file: " + cfg.RANKING_FILE + " from path: " + rank_file_path, io.LOG_ERROR)
		return {}
	l = f.readline()
	killers = {}
	deaders = {}
	while l != "":
		l = l.strip()
		#io.messageLog("ParseRank: line: " + l, io.LOG_INFO)
		if not (l.count("\t") == 2): # Don't show empty names or empty lines !
			l = f.readline()
			continue
		( date, deader, killer ) = l.split("\t")
		if not killer in killers.keys():
			killers[killer] = []
		if not deader in deaders.keys():
			deaders[deader] = []
		killers[killer].append(deader)
		deaders[deader].append(killer)
		l = f.readline()
	f.close()
	sorted = killers.keys()
	def sortFunc(s1, s2):
		suicides1 = killers[s1].count(s1)
		suicides2 = killers[s2].count(s2)
		kills1 = float(len(killers[s1]) - suicides1) # kills - suicides
		kills2 = float(len(killers[s2]) - suicides2)
		try:
			deaths1 = len(deaders[s1])
		except KeyError:
			deaths1 = 0
		try:
			deaths2 = len(deaders[s2])
		except KeyError:
			deaths2 = 0
		if useRatios: # You can change this to have the ratio you want... Here 2/3 is number of kill, and 1/3 is kills/deaths
			kills1 = kills1 / (deaths1 + 1 + suicides1) * kills1 * kills1
			kills2 = kills2 / (deaths2 + 1 + suicides2) * kills2 * kills2
		if kills1 < kills2: return 1
		if kills1 > kills2: return -1
		if deaths1 < deaths2: return -1
		if deaths1 > deaths2: return 1
		return 0
	sorted.sort(cmp=sortFunc)
	rank = 0
	total = {}
	for k in sorted:
		rank += 1
		kills = len(killers[k])
		try:
			deaths = len(deaders[k])
		except KeyError:
			deaths = 0
		suicides = killers[k].count(k)
		kills -= suicides
		deaths -= suicides
		total[k]=[kills,deaths,suicides,rank]
	#io.messageLog("ParseRank: rank " + str(total), io.LOG_INFO)
	return total
def parseUserCommand(wormid,message):
	global kickedUsers
	try: # Do not check on msg size or anything, exception handling is further down
		if message in [ "y", "n", "start", "stop", "rank", "toprank", "ranktotal" ]:
			# Single-word usercommands for faster typing
			cmd = message
		else:
			if (not message.startswith(cfg.USER_PREFIX)):
				return False # normal chat
			
			cmd = message.split(" ")[0]
			cmd = cmd.replace(cfg.USER_PREFIX,"",1).lower() #Remove the prefix
		
		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)
		
		if cfg.ALLOW_TEAM_CHANGE and cmd == "team":
			if not params:
				io.privateMsg(wormid, "You need to specify a team" )
				raise Exception, "You need to specify a team"
			else:
				if params[0].lower() == "blue" or params[0].lower() == "b":
					io.setWormTeam(wormid, 0)
				elif params[0].lower() == "red" or params[0].lower() == "r":
					io.setWormTeam(wormid, 1)
				elif ( params[0].lower() == "green" or params[0].lower() == "g" ) and cfg.MAX_TEAMS >= 3:
					io.setWormTeam(wormid, 2)
				elif ( params[0].lower() == "yellow" or params[0].lower() == "y" ) and cfg.MAX_TEAMS >= 4:
					io.setWormTeam(wormid, 3)
		
		if cfg.RANKING:
			if cmd == "toprank":
				ranking.firstRank(wormid)
			if cmd == "rank":
				if wormid in hnd.worms:
					wormName = hnd.worms[wormid].Name
					if params:
						wormName = " ".join(params)
					ranking.myRank(wormName, wormid)
			if cmd == "ranktotal":
				io.privateMsg(wormid, "There are " + str(len(ranking.rank)) + " players in the ranking.")
		
		if cfg.VOTING:
			
			if cmd == "kick":
				kicked = int( params[0] )
				if not kicked in hnd.worms.keys():
					raise Exception, "Invalid worm ID"
				addVote( "io.kickWorm(" + str(kicked) + 
							", 'You are kicked for " + str(cfg.VOTING_KICK_TIME) + " minutes')", 
							wormid, "Kick %i: %s" % ( kicked, hnd.worms[kicked].Name ) )
				hnd.worms[kicked].Voted = -1
			
			if cmd == "mute":
				if not kicked in hnd.worms.keys():
					raise Exception, "Invalid worm ID"
				kicked = int( params[0] )
				addVote( "io.muteWorm(" + str(kicked) +")", wormid, "Mute %i: %s" % ( kicked, hnd.worms[kicked].Name ) )
				hnd.worms[kicked].Voted = -1
			
			if cmd == "mod":
				
				# Users are proven to be stupid and can't tell the difference between mod and preset
				# so here we're first looking for a preset, and then looking for a mod with the same name if preset not found
				# (well, let's call that UI simplification)
				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:
					addVote( 'hnd.selectPreset( Preset = "%s" )' % hnd.availablePresets[preset], wormid, "Preset %s" % hnd.availablePresets[preset] )
				else:
					mod = ""
					for m in io.listMods():
						if m.lower().find(" ".join(params[0:]).lower()) != -1:
							mod = m
							break
					if mod == "":
						io.privateMsg(wormid,"Invalid mod, available mods: " + ", ".join(hnd.availablePresets) + ", ".join(io.listMods()))
					else:
						addVote( 'hnd.selectPreset( Mod = "%s" )' % mod, wormid, "Mod %s" % mod )
			
			if cmd == "map":
				level = ""
				for l in io.listMaps():
					if l.lower().find(" ".join(params[0:]).lower()) != -1:
						level = l
						break
				if level == "":
					io.privateMsg(wormid,"Invalid map, available maps: " + ", ".join(io.listMaps()))
				else:
					addVote( 'hnd.selectPreset( Level = "%s" )' % level, wormid, "Map %s" % level )
			
			if cmd == "lt":
				addVote( 'hnd.selectPreset( LT = %i )' % int(params[0]), wormid, "Loading time %i" % int(params[0]) )
			
			if cmd == "start":
				addVote( 'hnd.lobbyWaitAfterGame = time.time(); hnd.lobbyWaitBeforeGame = time.time()', wormid, "Start game now" )
			
			if cmd == "stop":
				addVote( 'io.gotoLobby()', wormid, "Go to lobby" )
			
			if ( cmd == "y" or cmd == "yes" ):
				if hnd.worms[wormid].Voted != 1:
					hnd.worms[wormid].Voted = 1
					recheckVote()
			if ( cmd == "n" or cmd == "no" ):
				if hnd.worms[wormid].Voted != -1:
					hnd.worms[wormid].Voted = -1
					recheckVote()
		
		elif parseUserCommand_Preset and parseUserCommand_Preset(wormid, cmd, params):
			pass
		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")
		io.messageLog(formatExceptionInfo(),io.LOG_ERROR) #Helps to fix errors
		return False
	return True
Beispiel #30
0
def parseNewWorm(wormID, name):
    global worms

    exists = False
    try:
        worm = worms[wormID]
        exists = True
    except KeyError:  #Worm doesn't exist.
        worm = Worm()

    worm.real_name = name  #NOTE: This is the name used by the server
    #Now prepare the name used by the script - used for ranking, for example
    name = name.replace("\t", " ").strip(
    )  # Do not allow tab in names, it will screw up our ranking tab-separated text-file database
    #Check if the player has quotation marks in his/her name
    quotemarks_in_nick = 0
    if "\"" in name:
        name = name.replace(
            "\"", "\'\'"
        )  #Double quotes (") cause problems with chat/private messages - convert to single quotes (')
        quotemarks_in_nick = 1

    worm.Name = name
    worm.iID = wormID
    worm.Ping = []

    wormIP = io.getWormIP(wormID).split(":")[
        0]  #Get worm IP address now - it will be needed later
    worm.Ip = wormIP

    worms[wormID] = worm

    #Set team for handler ##NOTE: OLX sets a team when the player joins - and it may not always be 0 (blue)!!! So get the team number now!
    #TEST: Log these initial teams
    if cfg.TEAMCHANGE_LOGGING:
        io.messageLog(
            "TEAMJOIN: Game reports team " + str(io.getWormTeam(wormID)) +
            " for joining worm " + str(name), io.LOG_INFO)
    worm.Team = io.getWormTeam(wormID)

    # io.messageLog("Curtime " + str(time.time()) + " IP " + str(wormIP) + " Kicked worms: " + str(kickedUsers), io.LOG_INFO)
    if wormIP in kickedUsers and kickedUsers[wormIP] > time.time():
        io.kickWorm(
            wormID, "You can join in " +
            str(int(kickedUsers[wormIP] - time.time()) / 60 + 1) + " minutes")
        return

    #Original ranking authentication based on skin color...
    #NOTE: This is a weak way of authentication
    if cfg.RANKING_AUTHENTICATION:
        if not name in ranking.auth:
            ranking.auth[name] = getWormSkin(wormID)
            try:
                rank_auth_file_path = io.getWriteFullFileName(
                    cfg.RANKING_AUTH_FILE)
                f = open(rank_auth_file_path, "a")
                try:
                    portalocker.lock(f, portalocker.LOCK_EX)
                except:
                    pass
                f.write(name + "\t" + str(ranking.auth[name][0]) + " " +
                        ranking.auth[name][1] + "\n")
                f.close()
            except IOError:
                io.messageLog(
                    "parseNewWorm: Unable to open ranking authentication file: "
                    + cfg.RANKING_AUTH_FILE + " from path: " +
                    rank_auth_file_path, io.LOG_ERROR)
        else:
            if ranking.auth[name] != getWormSkin(wormID):
                io.kickWorm(wormID,
                            "Player with name %s already registered" % name)
                return

    #Notify or kick players that have forbidden nicks
    if name in cfg.FORBIDDEN_NAMES:
        if cfg.NAME_CHECK_ACTION == 1:
            worm.Name = "random" + str(random.randint(
                0, cfg.NAME_CHECK_RANDOM))  #Assign random name
            io.privateMsg(wormID, cfg.NAME_CHECK_WARNMSG)
        elif cfg.NAME_CHECK_ACTION == 2:
            io.kickWorm(wormID, cfg.NAME_CHECK_KICKMSG)
            return

    #NEW: Kick players who have newline tags in their nicks - those can cause annoyance
    #NOTE: This may give false positives if there are nested tags, but it's an unlikely case
    if detectFormattingTags(name):
        io.kickWorm(
            wormID,
            "Please remove formatting tags ( <...> ) from your nickname - they cause problems"
        )
        return

    #Kick players with excessively long nicks.
    #NOTE: In 0.59, oversized name are truncated automatically so this becomes obsolete
    if len(name) > cfg.MAX_NAME_LENGTH:
        io.kickWorm(wormID, "name too long")
        return

    #Kick players with quotation marks in their name (only if configured!)
    #NOTE: This should not be needed anymore
    if quotemarks_in_nick == 1 and cfg.KICK_QUOTEMARKS == 1:
        io.kickWorm(
            wormID,
            "please remove quotation marks from your nickname - they screw up ranking."
        )
        return

    #If only one player per IP allowed, check if there is already a player from the IP
    #NOTE: This is a weak check and may cause more harm than good as it prevents people behind a shared IP from joining while not really preventing rank manipulation
    if cfg.ONE_PLAYER_PER_IP:
        for w in worms.keys():
            if worms[w].Ip == wormIP and w != wormID:
                io.kickWorm(wormID, "only one player per IP address allowed")
                return

    #Nag players to download the latest version. 0.58 rc3 may still be in use, and this is less harsh than kicking.
    #TODO: Do this in a better way?
    if cfg.VERSION_CHECK:
        ver = io.getWormVersion(wormID)
        newest_ver = io.getVar("GameOptions.State.NewestVersion")
        #Newest version, everything OK
        if distutils.version.LooseVersion(
                ver.lower()) == distutils.version.LooseVersion(
                    newest_ver.lower()):
            pass
        #Outdated 0.58 versions and older
        elif distutils.version.LooseVersion(
                ver.lower()) < distutils.version.LooseVersion(
                    newest_ver.lower()):
            io.privateMsg(
                wormID, "You're using an outdated version! Please download " +
                newest_ver.replace("/", " ").replace("_", " ") +
                " from http://openlierox.net/")
        #0.59 b10 and later are buggy
        elif distutils.version.LooseVersion(
                ver.lower()) >= distutils.version.LooseVersion(
                    "OpenLieroX/0.59_beta10".lower()):
            io.privateMsg(
                wormID,
                "You're using a buggy version of the game! You may want to download "
                + newest_ver.replace("/", " ").replace("_", " ") +
                " from http://openlierox.net/")
        #Other 0.59 versions are not as buggy but they lack the nice updates of 0.58 rc5
        else:
            io.privateMsg(
                wormID,
                "You seem to be using an experimental version of the game! You may want to download "
                + newest_ver.replace("/", " ").replace("_", " ") +
                " from http://openlierox.net/")

    #Assign team
    if io.getGameType() == 1:
        worms[
            wormID].votedTeams = 1  #Set vote status to 1 so that it will be TDM if it was TDM before this player joined
        io.privateMsg(
            wormID,
            "Game type is team deathmatch - say !noteams if you do not want teams for the next game"
        )
        #NOTE: The player is already assigned to a team by the game! - so assigning him to the smallest team here would lead to unbalancement
        # if the team status were, for example, [4, 4]. So check whether 1) teams are balanced (difference <=1) or not, and 2) the player is not in the smallest team
        #NOTE: Calling balanceTeams might look more elegant, but it might move other players as well, and it should not be called when we are not in lobby
        #NOTE: Be careful with RandomTeamForNewWorm option! It may cause an exception!
        team_status = getNumberWormsInAllTeams()  #Get team member counts
        team_status = team_status[
            0:cfg.MAX_TEAMS]  #Remove teams that are not used
        wormteam = io.getWormTeam(
            wormID)  #Could use worm.Team too, but this might be safer...
        if (max(team_status) - min(team_status)
            ) > 1 and wormteam != team_status.index(min(team_status)):
            setTeam(wormID, team_status.index(min(team_status)))

    #Update votes - this is needed if there are, let's say, 3 players who all vote for TDM but TDM requires 4 - now there are 4 and 3 of them vote so TDM should be selected!
    #No need to broadcast anything - TDM is broadcasted if the status changes.
    updateVotes()
Beispiel #31
0
def signalHandler(sig):
    global gameState, oldGameState, scriptPaused, sentStartGame, worms
    global vote_locked

    oldGameState = gameState

    if len(sig) == 0:
        return False  #Didn't get anything

    header = sig[0]

    try:
        if header == "newworm":
            parseNewWorm(int(sig[1]), sig[2])
        elif header == "wormleft":
            parseWormLeft(sig)
        elif header == "privatemessage":
            parsePrivateMessage(sig)
        elif header == "chatmessage":
            parseChatMessage(sig)
        elif header == "wormdied":
            parseWormDied(sig)
        elif header == "wormspawned":
            parseWormSpawned(sig)
        elif header == "wormauthorized":
            parseWormAuthorized(sig)
        elif header == "wormgotadmin":
            worms[int(sig[1])].isDedAdmin = True
            # no other difference to wormauthorized yet - and we also get wormauthorized, so nothing to do anymore
            pass

        ## Check GameState ##
        elif header == "quit":
            gameState = GAME_QUIT
            exit()

        elif header == "backtolobby" or header == "lobbystarted":
            if cfg.RANKING:
                ranking.refreshRank()
            gameState = GAME_LOBBY
            sentStartGame = False
            vote_locked = False  #Always unlock voting when back to lobby
            controlHandler()

        elif header == "weaponselections":
            gameState = GAME_WEAPONS
            controlHandler()
        elif header == "gamestarted":
            gameState = GAME_PLAYING
            sentStartGame = False
            controlHandler()
        #TODO: gamestarted && gameloopstart are pretty much duplicates
        # Or are they? Check.
        # Same thing for gameloopend and backtolobby
        elif header == "gameloopstart":  #Sent when game starts
            pass
            #io.messageLog("TEST -- SIGNAL: gameloopstart", io.LOG_INFO)	#TEST
        elif header == "gameloopend":  #Sent at game end
            pass
            #io.messageLog("TEST -- SIGNAL: gameloopend", io.LOG_INFO)	#TEST
        #elif header == "gameloopend": #Sent when OLX starts
        #	pass
        elif header == "timer":  # Sent once per second
            controlHandler()

        elif header == "custom":
            io.messageLog(("CUSTOMSIGNAL: %s" % (sig)), io.LOG_INFO)  #TEST
            parseCustom(sig)

        else:
            io.messageLog(("I don't understand %s." % (sig)), io.LOG_ERROR)

    except Exception:
        traceback.print_exc(None, sys.stderr)

    return True
def parseAdminCommand(wormid,message):
	global kickedUsers
	try: # Do not check on msg size or anything, exception handling is further down
		if (not message.startswith(cfg.ADMIN_PREFIX)):
			return False # normal chat

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

		if wormid >= 0:
			io.messageLog("%i:%s issued %s" % (wormid,hnd.worms[wormid].Name,cmd.replace(cfg.ADMIN_PREFIX,"",1)),io.LOG_ADMIN)
		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":
			adminCommandHelp(wormid)
		elif cmd == "kick":
			kickTime = cfg.VOTING_KICK_TIME
			if len(params) > 1: # Time for kick
				kickTime = float(params[1])
			wormIP = io.getWormIP(int( params[0] )).split(":")[0]
			if wormIP != "127.0.0.1":
				kickedUsers[ wormIP ] = time.time() + kickTime*60
			if len(params) > 2: # Given some reason
				io.kickWorm( int( params[0] ), " ".join(params[2:]) )
			else:
				io.kickWorm( int( params[0] ) )
		elif cmd == "ban":
			if len(params) > 1: # Given some reason
				io.banWorm( int( params[0] ), " ".join(params[1:]) )
			else:
				io.banWorm( int( params[0] ) )
		elif cmd == "mute":
			io.muteWorm( int( params[0] ) )
		elif cmd == "preset":
			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:
				io.privateMsg(wormid,"Invalid preset, available presets: " + ", ".join(hnd.availablePresets))
			else:
				hnd.selectPreset( Preset = hnd.availablePresets[preset] )
		elif cmd == "mod":
			mod = ""
			for m in io.listMods():
				if m.lower().find(" ".join(params[0:]).lower()) != -1:
					mod = m
					break
			if mod == "":
				io.privateMsg(wormid,"Invalid mod, available mods: " + ", ".join(io.listMods()))
			else:
				hnd.selectPreset( Mod = mod )
		elif cmd == "map":
			level = ""
			for l in io.listMaps():
				if l.lower().find(" ".join(params[0:]).lower()) != -1:
					level = l
					break
			if level == "":
				io.privateMsg(wormid,"Invalid map, available maps: " + ", ".join(io.listMaps()))
			else:
				hnd.selectPreset( Level = level )
		elif cmd == "lt":
			hnd.selectPreset( LT = int(params[0]) )
		elif cmd == "start":
			io.startGame()
		elif cmd == "stop":
			io.gotoLobby()
		elif cmd == "pause":
			io.privateMsg(wormid,"Ded script paused")
			hnd.scriptPaused = True
		elif cmd == "unpause":
			io.privateMsg(wormid,"Ded script continues")
			hnd.scriptPaused = False
		elif cmd == "setvar":
			io.setvar(params[0], " ".join(params[1:])) # In case value contains spaces
		elif cmd == "authorize":
			try:
				wormID = int(params[0])
				if not hnd.worms[wormID].isAdmin:
					hnd.worms[wormID].isAdmin = True
					io.authorizeWorm(wormID)
					io.messageLog( "Worm %i (%s) added to admins by %i (%s)" % (wormID,hnd.worms[wormID].Name,wormid,hnd.worms[wormid].Name),io.LOG_INFO)
					io.privateMsg(wormID, "%s made you admin! Type %shelp for commands" % (hnd.worms[wormid].Name,cfg.ADMIN_PREFIX))
					io.privateMsg(wormid, "%s added to admins." % hnd.worms[wormID].Name)
			except KeyError:
				io.messageLog("parseAdminCommand: Our local copy of wormses doesn't match the real list.",io.LOG_ERROR)
		elif parseAdminCommand_Preset and parseAdminCommand_Preset(wormid, cmd, params):
			pass
		else:
			raise Exception, "Invalid admin command"

	except: # All python classes derive from main "Exception", but confused me, this has the same effect.
		if wormid >= 0:
			io.privateMsg(wormid, "Invalid admin command")
		io.messageLog(formatExceptionInfo(),io.LOG_ERROR) #Helps to fix errors
		return False
	return True
    def __init__(self):
        StandardCiclerGameVar.__init__(self)
        self.gameVar = "GameOptions.GameInfo.ModName"

    def apply(self):
        if not self.curSelection: return
        StandardCiclerGameVar.apply(self)
        SetWeaponBans()


modCicler = ModCicler()
modCicler.list = cfg.MODS
if len(modCicler.list) == 0:
    modCicler.list = io.listMods()
if len(modCicler.list) == 0:
    io.messageLog("Waiting for mod list ...")
    while len(modCicler.list) == 0:
        modCicler.list = io.listMods()


class PresetCicler(StandardCiclerBase):
    def __init__(self):
        StandardCiclerBase.__init__(self)

    def apply(self):
        if not self.curSelection: return
        StandardCiclerBase.apply(self)

        global availablePresets, presetDir

        sDefaults = os.path.join(presetDir, "Defaults")
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()
Beispiel #35
0
def parseAdminCommand(wormid, message):
    try:  # Do not check on msg size or anything, exception handling is further down

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

        if wormid >= 0:
            io.messageLog(
                "%i:%s issued %s" % (wormid, hnd.worms[wormid].Name,
                                     cmd.replace(cfg.ADMIN_PREFIX, "", 1)),
                io.LOG_ADMIN)
        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":
            adminCommandHelp(wormid)

        elif cmd == "kick":
            wormid = int(params[0])
            wormIP = io.getWormIP(wormid).split(":")[0]
            if wormIP != "127.0.0.1":
                if len(params) > 1:  # Given some reason
                    hnd.kickWithTime(wormid, " ".join(params[2:]))
                else:
                    hnd.kickWithTime(wormid)

        elif cmd == "ban":
            if len(params) > 1:  # Given some reason
                io.banWorm(int(params[0]), " ".join(params[1:]))
            else:
                io.banWorm(int(params[0]))

        elif cmd == "mute":
            io.muteWorm(int(params[0]))

        elif cmd == "mod":
            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:
                io.privateMsg(
                    wormid, "Invalid preset, available presets: " +
                    ", ".join(hnd.availablePresets))
            else:
                hnd.loadPreset(availablePresets[p])

        elif cmd == "map":
            level = ""
            for l in io.listMaps():
                if l.lower().find(" ".join(params[0:]).lower()) != -1:
                    level = l
                    break
            if level == "":
                io.privateMsg(
                    wormid,
                    "Invalid map, available maps: " + ", ".join(io.listMaps()))
            else:
                hnd.loadMap(l)

        elif cmd == "pause":
            io.privateMsg(wormid, "Ded script paused")
            hnd.scriptPaused = True
        elif cmd == "unpause":
            io.privateMsg(wormid, "Ded script continues")
            hnd.scriptPaused = False

        else:
            raise Exception, "Invalid admin command"

    except:  # All python classes derive from main "Exception", but confused me, this has the same effect.
        if wormid >= 0:
            io.privateMsg(wormid, "Invalid admin command")
        io.messageLog(io.formatExceptionInfo(),
                      io.LOG_ERROR)  #Helps to fix errors
        return False
    return True
def parseAdminCommand(wormid, message):
    global kickedUsers
    try:  # Do not check on msg size or anything, exception handling is further down
        if (not message.startswith(cfg.ADMIN_PREFIX)):
            return False  # normal chat

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

        if wormid >= 0:
            io.messageLog(
                "%i:%s issued %s" % (wormid, hnd.worms[wormid].Name,
                                     cmd.replace(cfg.ADMIN_PREFIX, "", 1)),
                io.LOG_ADMIN)
        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":
            adminCommandHelp(wormid)
        elif cmd == "kick":
            kickTime = cfg.VOTING_KICK_TIME
            if len(params) > 1:  # Time for kick
                kickTime = float(params[1])
            wormIP = io.getWormIP(int(params[0])).split(":")[0]
            if wormIP != "127.0.0.1":
                kickedUsers[wormIP] = time.time() + kickTime * 60
            if len(params) > 2:  # Given some reason
                io.kickWorm(int(params[0]), " ".join(params[2:]))
            else:
                io.kickWorm(int(params[0]))
        elif cmd == "ban":
            if len(params) > 1:  # Given some reason
                io.banWorm(int(params[0]), " ".join(params[1:]))
            else:
                io.banWorm(int(params[0]))
        elif cmd == "mute":
            io.muteWorm(int(params[0]))
        elif cmd == "preset":
            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:
                io.privateMsg(
                    wormid, "Invalid preset, available presets: " +
                    ", ".join(hnd.availablePresets))
            else:
                hnd.selectPreset(Preset=hnd.availablePresets[preset])
        elif cmd == "mod":
            mod = ""
            for m in io.listMods():
                if m.lower().find(" ".join(params[0:]).lower()) != -1:
                    mod = m
                    break
            if mod == "":
                io.privateMsg(
                    wormid,
                    "Invalid mod, available mods: " + ", ".join(io.listMods()))
            else:
                hnd.selectPreset(Mod=mod)
        elif cmd == "map":
            level = ""
            for l in io.listMaps():
                if l.lower().find(" ".join(params[0:]).lower()) != -1:
                    level = l
                    break
            if level == "":
                io.privateMsg(
                    wormid,
                    "Invalid map, available maps: " + ", ".join(io.listMaps()))
            else:
                hnd.selectPreset(Level=level)
        elif cmd == "lt":
            hnd.selectPreset(LT=int(params[0]))
        elif cmd == "start":
            io.startGame()
        elif cmd == "stop":
            io.gotoLobby()
        elif cmd == "pause":
            io.privateMsg(wormid, "Ded script paused")
            hnd.scriptPaused = True
        elif cmd == "unpause":
            io.privateMsg(wormid, "Ded script continues")
            hnd.scriptPaused = False
        elif cmd == "setvar":
            io.setvar(params[0],
                      " ".join(params[1:]))  # In case value contains spaces
        elif cmd == "authorize":
            try:
                wormID = int(params[0])
                if not hnd.worms[wormID].isAdmin:
                    hnd.worms[wormID].isAdmin = True
                    io.authorizeWorm(wormID)
                    io.messageLog(
                        "Worm %i (%s) added to admins by %i (%s)" %
                        (wormID, hnd.worms[wormID].Name, wormid,
                         hnd.worms[wormid].Name), io.LOG_INFO)
                    io.privateMsg(
                        wormID, "%s made you admin! Type %shelp for commands" %
                        (hnd.worms[wormid].Name, cfg.ADMIN_PREFIX))
                    io.privateMsg(
                        wormid, "%s added to admins." % hnd.worms[wormID].Name)
            except KeyError:
                io.messageLog(
                    "parseAdminCommand: Our local copy of wormses doesn't match the real list.",
                    io.LOG_ERROR)
        elif parseAdminCommand_Preset and parseAdminCommand_Preset(
                wormid, cmd, params):
            pass
        else:
            raise Exception, "Invalid admin command"

    except:  # All python classes derive from main "Exception", but confused me, this has the same effect.
        if wormid >= 0:
            io.privateMsg(wormid, "Invalid admin command")
        io.messageLog(formatExceptionInfo(),
                      io.LOG_ERROR)  #Helps to fix errors
        return False
    return True
Beispiel #37
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
Beispiel #38
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"
	def __init__(self):
		StandardCiclerGameVar.__init__(self)
		self.gameVar = "GameOptions.GameInfo.ModName"
	
	def apply(self):
		if not self.curSelection: return
		StandardCiclerGameVar.apply(self)
		SetWeaponBans()


modCicler = ModCicler()
modCicler.list = cfg.MODS
if len(modCicler.list) == 0:
	modCicler.list = io.listMods()
if len(modCicler.list) == 0:
	io.messageLog("Waiting for mod list ...")
	while len(modCicler.list) == 0:
		modCicler.list = io.listMods()

class PresetCicler(StandardCiclerBase):
	def __init__(self):
		StandardCiclerBase.__init__(self)

	def apply(self):
		if not self.curSelection: return
		StandardCiclerBase.apply(self)

		global availablePresets, presetDir

		sDefaults = os.path.join(presetDir,"Defaults")
		try: