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 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 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 updateVotes(send_msg=()): global gameState, oldGameState global vote_locked global worms, availablePresets votedMaps = {} votedPresets = {} teams_voted = 0 teams_ready = False gametype_old = io.getGameType() #Reset kick vote counters to zero for w in worms.keys(): worms[w].resetKickVotes() #Count all votes for w in worms.keys(): #Count map votes if worms[w].votedMap: if not worms[w].votedMap in votedMaps.keys(): votedMaps[worms[w].votedMap] = 1 else: votedMaps[worms[w].votedMap] += 1 #Count mod (preset) votes if worms[w].votedPreset: if not worms[w].votedPreset in votedPresets.keys(): votedPresets[worms[w].votedPreset] = 1 else: votedPresets[worms[w].votedPreset] += 1 #Count kick votes for each player if worms[w].votedKick in worms.keys(): worms[worms[w].votedKick].kickVoted += 1 else: worms[ w].votedKick = None #If player is not on the server, remove vote #Count team votes if worms[w].votedTeams: teams_voted += 1 #Find most voted ones mostVotedMap = "" mostVotedPreset = "" for m in votedMaps.keys(): if not mostVotedMap: mostVotedMap = m else: if votedMaps[m] > votedMaps[mostVotedMap]: mostVotedMap = m for p in votedPresets.keys(): if not mostVotedPreset: mostVotedPreset = p else: if votedPresets[p] > votedPresets[mostVotedPreset]: mostVotedPreset = p #Announce voting status if "map" in send_msg and mostVotedMap: io.chatMsg("Most voted map: " + mostVotedMap) if "mod" in send_msg and mostVotedPreset: io.chatMsg("Most voted preset: " + mostVotedPreset) #Check teamgame votes if len(worms) != 0 and (float(teams_voted) / float( len(worms))) * 100 >= cfg.VOTING_PERCENT and len( worms) >= cfg.MIN_PLAYERS_TEAMS: teams_ready = True else: teams_ready = False #Announce team voting status if "teams" in send_msg and teams_voted != 0: if teams_ready: io.chatMsg( "Team voting status: Looks like the next game will be Team Deathmatch!" ) elif len(worms) < cfg.MIN_PLAYERS_TEAMS: io.chatMsg( "Team voting status: Not enough players for team game (" + str(cfg.MIN_PLAYERS_TEAMS) + " is minimum)") elif (float(teams_voted) / float(len(worms))) * 100 < cfg.VOTING_PERCENT: io.chatMsg( "Team voting status: Not enough votes for team game yet") #Check kick votes for w in worms.keys(): if (float(worms[w].kickVoted) / float(len(worms))) * 100 > cfg.VOTING_PERCENT: kickWithTime(w, "other players voted to kick you") #If we are safely in lobby, load settings if gameState == GAME_LOBBY and not vote_locked: #Set map and preset if mostVotedMap: loadMap(mostVotedMap) if mostVotedPreset: loadPreset(mostVotedPreset) #Set team game if teams_ready: if io.getGameType() == 0: io.setvar("GameOptions.GameInfo.GameType", 1) setupTeams() else: io.setvar("GameOptions.GameInfo.GameType", 0) #Announce team game status if 1) it has not been announced and 2) game type has been changed if not "teams" in send_msg and gametype_old != io.getGameType(): if teams_ready: io.chatMsg( "Team voting status: Looks like the next game will be Team Deathmatch!" ) elif len(worms) < cfg.MIN_PLAYERS_TEAMS: io.chatMsg( "Team voting status: Not enough players for team game (" + str(cfg.MIN_PLAYERS_TEAMS) + " is minimum)") elif (float(teams_voted) / float(len(worms))) * 100 < cfg.VOTING_PERCENT: io.chatMsg("Team voting status: Not enough votes for team game") return (mostVotedMap, mostVotedPreset, int(teams_ready))
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 controlHandlerDefault(): global worms, gameState, lobbyChangePresetTimeout, lobbyWaitBeforeGame, lobbyWaitAfterGame global lobbyWaitGeneral, lobbyEnoughPlayers, oldGameState, scriptPaused, sentStartGame global currentAutocyclePreset, currentAutocycleMap global vote_locked, shuffle_counter if scriptPaused: return curTime = time.time() if gameState == GAME_LOBBY: # Do not check ping in lobby - it's wrong if oldGameState != GAME_LOBBY: lobbyEnoughPlayers = False # reset the state lobbyWaitGeneral = curTime + cfg.WAIT_BEFORE_SPAMMING_TOO_FEW_PLAYERS_MESSAGE lobbyWaitAfterGame = curTime if oldGameState == GAME_PLAYING: lobbyWaitAfterGame = curTime + cfg.WAIT_AFTER_GAME #Reset shuffle counter shuffle_counter = 0 #Update votes when game ends updateResult = updateVotes(send_msg=("map", "mod", "teams")) #Autocycle if not voted #Advance autocycle counters first if not updateResult[0]: currentAutocycleMap += 1 if currentAutocycleMap >= len(cfg.LEVELS): currentAutocycleMap = 0 if not updateResult[1]: currentAutocyclePreset += 1 if currentAutocyclePreset >= len(cfg.PRESETS): currentAutocyclePreset = 0 ##Map if not updateResult[0]: io.setvar("GameOptions.GameInfo.LevelName", cfg.LEVELS[currentAutocycleMap]) ##Mod (preset) if not updateResult[1]: loadPreset(cfg.PRESETS[currentAutocyclePreset]) #Check if teams are balanced ##This should be done because teams may become uneven if people leave during game and BALANCE_TEAMS_INGAME is not set if io.getGameType() == 1: io.chatMsg("Checking if teams are even...") balanceTeams(bmsg="game ended") if lobbyWaitAfterGame <= curTime: if not lobbyEnoughPlayers and lobbyWaitGeneral <= curTime: lobbyWaitGeneral = curTime + cfg.WAIT_BEFORE_SPAMMING_TOO_FEW_PLAYERS_MESSAGE io.chatMsg(cfg.TOO_FEW_PLAYERS_MESSAGE) if not lobbyEnoughPlayers and len( worms ) >= cfg.MIN_PLAYERS: # Enough players already - start game lobbyEnoughPlayers = True io.chatMsg(cfg.WAIT_BEFORE_GAME_MESSAGE) lobbyWaitBeforeGame = curTime + cfg.WAIT_BEFORE_GAME if lobbyEnoughPlayers and len( worms ) < cfg.MIN_PLAYERS: # Some players left when game not yet started lobbyEnoughPlayers = False io.chatMsg(cfg.TOO_FEW_PLAYERS_MESSAGE) if lobbyEnoughPlayers and not sentStartGame: if lobbyWaitBeforeGame <= curTime: # Start the game #Starting game... ##NOTE Removed team check from here - teams should be assigned before the round starts if io.startGame(): if cfg.ALLOW_TEAM_CHANGE and len( worms) >= cfg.MIN_PLAYERS_TEAMS: io.chatMsg(cfg.TEAM_CHANGE_MESSAGE) sentStartGame = True vote_locked = True #Lock vote-able settings when starting clearVotes() #Clear votes when starting else: io.messageLog("Game could not be started", io.LOG_ERROR) #Log these errors! io.chatMsg("Game could not be started") oldGameState == GAME_PLAYING # hack that it resets at next control handler call if gameState == GAME_WEAPONS: # if we allow empty games, ignore this check if len(worms) < cfg.MIN_PLAYERS and not io.getVar( "GameOptions.GameInfo.AllowEmptyGames" ): # Some players left when game not yet started io.chatMsg("Too few players -> back to lobby") io.gotoLobby() sentStartGame = False if gameState == GAME_PLAYING: if cfg.PING_CHECK: checkMaxPing() #Unlock voting when the game is safely running if (gameState == GAME_WEAPONS or gameState == GAME_PLAYING) and oldGameState != GAME_LOBBY and vote_locked: vote_locked = False
def controlHandlerDefault(): global worms, gameState, lobbyChangePresetTimeout, lobbyWaitBeforeGame, lobbyWaitAfterGame global lobbyWaitGeneral, lobbyEnoughPlayers, oldGameState, scriptPaused, sentStartGame global presetCicler, modCicler, mapCicler, LT_Cicler global videoRecorder, videoRecorderSignalTime if scriptPaused: return curTime = time.time() cmds.recheckVote(False) if gameState == GAME_LOBBY: # Do not check ping in lobby - it's wrong if oldGameState != GAME_LOBBY: mapCicler.check() modCicler.check() LT_Cicler.check() presetCicler.check() lobbyEnoughPlayers = False # reset the state lobbyWaitGeneral = curTime + cfg.WAIT_BEFORE_SPAMMING_TOO_FEW_PLAYERS_MESSAGE lobbyWaitAfterGame = curTime if oldGameState == GAME_PLAYING: lobbyWaitAfterGame = curTime + cfg.WAIT_AFTER_GAME if videoRecorder: os.kill( videoRecorder.pid, signal.SIGINT ) # videoRecorder.send_signal(signal.SIGINT) # This is available only on Python 2.6 videoRecorderSignalTime = time.time() io.chatMsg("Waiting for video recorder to finish") canStart = True if videoRecorder and videoRecorder.returncode == None: canStart = False videoRecorder.poll() if time.time( ) - videoRecorderSignalTime > cfg.TIME_TO_KILL_VIDEORECORDER: io.chatMsg("Video recorder stalled, killing") os.kill(videoRecorder.pid, signal.SIGKILL) videoRecorder.poll() if videoRecorder.returncode != None: io.chatMsg("Video recorder encoding took " + str(int(time.time() - videoRecorderSignalTime)) + " secs") canStart = True videoRecorder = None if lobbyWaitAfterGame <= curTime: if not lobbyEnoughPlayers and lobbyWaitGeneral <= curTime: lobbyWaitGeneral = curTime + cfg.WAIT_BEFORE_SPAMMING_TOO_FEW_PLAYERS_MESSAGE io.chatMsg(cfg.TOO_FEW_PLAYERS_MESSAGE) if not lobbyEnoughPlayers and len( worms ) >= cfg.MIN_PLAYERS: # Enough players already - start game lobbyEnoughPlayers = True io.chatMsg(cfg.WAIT_BEFORE_GAME_MESSAGE) lobbyWaitBeforeGame = curTime + cfg.WAIT_BEFORE_GAME if lobbyEnoughPlayers and len( worms ) < cfg.MIN_PLAYERS: # Some players left when game not yet started lobbyEnoughPlayers = False io.chatMsg(cfg.TOO_FEW_PLAYERS_MESSAGE) if lobbyEnoughPlayers and not sentStartGame: if lobbyWaitBeforeGame <= curTime and canStart: # Start the game if io.getGameType() in ["Death Match", "Team Death Match"]: if len(worms ) >= cfg.MIN_PLAYERS_TEAMS: # Split in teams setvar("GameOptions.GameInfo.GameType", "Team Death Match") if not cfg.ALLOW_TEAM_CHANGE: counter = 0 for w in worms.values(): if w.iID != -1: io.setWormTeam(w.iID, counter % cfg.MAX_TEAMS) counter += 1 else: io.setvar("GameOptions.GameInfo.GameType", "Death Match") if io.startGame(): if cfg.ALLOW_TEAM_CHANGE and len( worms) >= cfg.MIN_PLAYERS_TEAMS: io.chatMsg(cfg.TEAM_CHANGE_MESSAGE) sentStartGame = True if cfg.RECORD_VIDEO: try: #io.messageLog("Running dedicated-video-record.sh, curdir " + os.path.abspath(os.path.curdir) ,io.LOG_INFO) videoRecorder = subprocess.Popen( [ "./dedicated-video-record.sh", "./dedicated-video-record.sh" ], stdin=open("/dev/null", "r"), stdout=open("../../../dedicatedVideo.log", "w"), stderr=subprocess.STDOUT, cwd="..") except: io.messageLog(formatExceptionInfo(), io.LOG_ERROR) else: io.chatMsg("Game could not be started") oldGameState == GAME_PLAYING # hack that it resets at next control handler call if gameState == GAME_WEAPONS: #checkMaxPing() # if we allow empty games, ignore this check if len(worms) < cfg.MIN_PLAYERS and not io.getVar( "GameOptions.GameInfo.AllowEmptyGames" ): # Some players left when game not yet started io.chatMsg("Too less players -> back to lobby") io.gotoLobby() sentStartGame = False if gameState == GAME_PLAYING: checkMaxPing()
def 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 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()