def parseNewWorm(wormID, name):
	global worms

	name = name.replace("\t", " ").strip() # Do not allow tab in names, it will screw up our ranking tab-separated text-file database
	exists = False
	try:
		worm = worms[wormID]
		exists = True
	except KeyError: #Worm doesn't exist.
		worm = Worm()
	worm.Name = name
	worm.iID = wormID
	worm.Ping = []

	worms[wormID] = worm

	if io.getGameType() == "Hide and Seek":
		minSeekers = 1
		if len(worms.values()) >= 4: minSeekers = 2
		if io.getNumberWormsInTeam(1) < minSeekers:
			io.setWormTeam(wormID, 1) # Seeker
		else:
			io.setWormTeam(wormID, 0) # Hider		
	else:
		# Balance teams
		teams = [0,0,0,0]
		for w in worms.keys():
			teams[worms[w].Team] += 1
		minTeam = 0
		minTeamCount = teams[0]
		for f in range(cfg.MAX_TEAMS):
			if minTeamCount > teams[f]:
				minTeamCount = teams[f]
				minTeam = f

		io.setWormTeam(wormID, minTeam)

	if cfg.RANKING_AUTHENTICATION:
		if not name in ranking.auth:
			ranking.auth[name] = getWormSkin(wormID)
			try:
				f = open(io.getFullFileName("pwn0meter_auth.txt"),"r")
				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:
				msg("ERROR: Unable to open pwn0meter_auth.txt")
		else:
			if ranking.auth[name] != getWormSkin(wormID):
				io.kickWorm(wormID, "Player with name %s already registered" % name)

	wormIP = io.getWormIP(wormID).split(":")[0]
	# io.messageLog("Curtime " + str(time.time()) + " IP " + str(wormIP) + " Kicked worms: " + str(cmds.kickedUsers), io.LOG_INFO)
	if wormIP in cmds.kickedUsers and cmds.kickedUsers[ wormIP ] > time.time():
			io.kickWorm( wormID, "You can join in " + str(int(cmds.kickedUsers[ wormIP ] - time.time())/60 + 1) + " minutes" )
			return
	cmds.recheckVote()
Esempio n. 2
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
Esempio n. 4
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()
def parseNewWorm(wormID, name):
    global worms

    name = name.replace("\t", " ").strip(
    )  # Do not allow tab in names, it will screw up our ranking tab-separated text-file database
    exists = False
    try:
        worm = worms[wormID]
        exists = True
    except KeyError:  #Worm doesn't exist.
        worm = Worm()
    worm.Name = name
    worm.iID = wormID
    worm.Ping = []

    worms[wormID] = worm

    if io.getGameType() == "Hide and Seek":
        minSeekers = 1
        if len(worms.values()) >= 4: minSeekers = 2
        if io.getNumberWormsInTeam(1) < minSeekers:
            io.setWormTeam(wormID, 1)  # Seeker
        else:
            io.setWormTeam(wormID, 0)  # Hider
    else:
        # Balance teams
        teams = [0, 0, 0, 0]
        for w in worms.keys():
            teams[worms[w].Team] += 1
        minTeam = 0
        minTeamCount = teams[0]
        for f in range(cfg.MAX_TEAMS):
            if minTeamCount > teams[f]:
                minTeamCount = teams[f]
                minTeam = f

        io.setWormTeam(wormID, minTeam)

    if cfg.RANKING_AUTHENTICATION:
        if not name in ranking.auth:
            ranking.auth[name] = getWormSkin(wormID)
            try:
                f = open(io.getFullFileName("pwn0meter_auth.txt"), "r")
                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:
                msg("ERROR: Unable to open pwn0meter_auth.txt")
        else:
            if ranking.auth[name] != getWormSkin(wormID):
                io.kickWorm(wormID,
                            "Player with name %s already registered" % name)

    wormIP = io.getWormIP(wormID).split(":")[0]
    # io.messageLog("Curtime " + str(time.time()) + " IP " + str(wormIP) + " Kicked worms: " + str(cmds.kickedUsers), io.LOG_INFO)
    if wormIP in cmds.kickedUsers and cmds.kickedUsers[wormIP] > time.time():
        io.kickWorm(
            wormID, "You can join in " +
            str(int(cmds.kickedUsers[wormIP] - time.time()) / 60 + 1) +
            " minutes")
        return
    cmds.recheckVote()
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