Пример #1
0
def handleUsernameChange(userID, newUsername, targetToken=None):
    try:
        userUtils.appendNotes(
            userID, "Username change: '{}' -> '{}'".format(
                userUtils.getUsername(userID), newUsername))
        userUtils.changeUsername(userID, newUsername=newUsername)
        if targetToken != None:
            targetToken.kick(
                "Your username has been changed to {}. Please log in again.".
                format(newUsername), "username_change")
    except userUtils.usernameAlreadyInUseError:
        log.rap(999,
                "Username change: {} is already in use!",
                through="Bancho")
        if targetToken != None:
            targetToken.kick(
                "There was a critical error while trying to change your username. Please contact a developer.",
                "username_change_fail")
    except userUtils.invalidUsernameError:
        log.rap(999,
                "Username change: {} is not a valid username!",
                through="Bancho")
        if targetToken != None:
            targetToken.kick(
                "There was a critical error while trying to change your username. Please contact a developer.",
                "username_change_fail")
Пример #2
0
    def setDataFromDict(self, data, rank=None):
        """
		Set this object's score data from dictionary
		Doesn't set playerUserID
		data -- score dictionarty
		rank -- rank in scoreboard. Optional.
		"""
        #print(str(data))
        self.scoreID = data["id"]
        if "username" in data:
            self.playerName = userUtils.getClan(data["userid"])
        else:
            self.playerName = userUtils.getUsername(data["userid"])
        self.playerUserID = data["userid"]
        self.score = data["score"]
        self.maxCombo = data["max_combo"]
        self.gameMode = data["play_mode"]
        self.c50 = data["50_count"]
        self.c100 = data["100_count"]
        self.c300 = data["300_count"]
        self.cMiss = data["misses_count"]
        self.cKatu = data["katus_count"]
        self.cGeki = data["gekis_count"]
        self.fullCombo = True if data["full_combo"] == 1 else False
        self.mods = data["mods"]
        self.rank = rank if rank is not None else ""
        self.date = data["time"]
        self.fileMd5 = data["beatmap_md5"]
        self.completed = data["completed"]
        #if "pp" in data:
        self.pp = data["pp"]
        self.calculateAccuracy()
Пример #3
0
def getRankInfo(userID, gameMode):
    """
	Get userID's current rank, user above us and pp/score difference

	:param userID: user
	:param gameMode: gameMode number
	:return: {"nextUsername": "", "difference": 0, "currentRank": 0}
	"""
    data = {"nextUsername": "", "difference": 0, "currentRank": 0}
    k = "ripple:leaderboard_auto:{}".format(
        scoreUtils.readableGameMode(gameMode))
    position = userUtils.getGameRankAP(userID, gameMode) - 1
    log.debug("Our position is {}".format(position))
    if position is not None and position > 0:
        aboveUs = glob.redis.zrevrange(k, position - 1, position)
        log.debug("{} is above us".format(aboveUs))
        if aboveUs is not None and len(aboveUs) > 0 and aboveUs[0].isdigit():
            # Get our rank, next rank username and pp/score difference
            myScore = glob.redis.zscore(k, userID)
            otherScore = glob.redis.zscore(k, aboveUs[0])
            nextUsername = userUtils.getUsername(aboveUs[0])
            if nextUsername is not None and myScore is not None and otherScore is not None:
                data["nextUsername"] = nextUsername
                data["difference"] = int(myScore) - int(otherScore)
    else:
        position = 0

    data["currentRank"] = position + 1
    return data
Пример #4
0
 def listReferee(response, token, sender, channel, message):
     _match = getCurrentMatch(channel)
     msg = "List of referees:"
     for refUserID in _match.referees:
         msg += "\n - {}".format(userUtils.getUsername(refUserID))
     msg += f"\n - {sender}"
     response.split_lines = True
     response.setContent(token, msg)
Пример #5
0
def connect():
    """
	Connect FokaBot to Bancho

	:return:
	"""
    glob.BOT_NAME = userUtils.getUsername(999)
    token = glob.tokens.addToken(999)
    glob.streams.broadcast("main", serverPackets.userPanel(999))
    glob.streams.broadcast("main", serverPackets.userStats(999))
Пример #6
0
def connect():
    """
	Connect FokaBot to Bancho.
	You can change FokaBot's name in RAP and FokaBot will still work as intended.

	:return:
	"""
    glob.BOT_NAME = userUtils.getUsername(999)
    token = glob.tokens.addToken(999)
    token.actionID = actions.IDLE
    glob.streams.broadcast("main", serverPackets.userPanel(999))
    glob.streams.broadcast("main", serverPackets.userStats(999))
Пример #7
0
def connect():
    """
	Connect FokaBot to Bancho

	:return:
	"""
    glob.BOT_NAME = userUtils.getUsername(999)
    token = glob.tokens.addToken(999)
    token.actionID = actions.UNKNOWN
    token.actionText = "\nWelcome to osu!minase have fun"
    glob.streams.broadcast("main", serverPackets.userPanel(999))
    glob.streams.broadcast("main", serverPackets.userStats(999))
Пример #8
0
def connect():
    """
	Connect FokaBot to Bancho

	:return:
	"""
    glob.BOT_NAME = userUtils.getUsername(999)
    token = glob.tokens.addToken(999)
    token.actionID = actions.IDLE
    token.actionText = "\nThank you for playing Ryumi! <3"
    glob.streams.broadcast("main", serverPackets.userPanel(999))
    glob.streams.broadcast("main", serverPackets.userStats(999))
Пример #9
0
def rap(userID, message, discord=False, through="FokaBot"):
	"""
	Log a message to Admin Logs.

	:param userID: admin user ID
	:param message: message content, without username
	:param discord: if True, send the message to discord
	:param through: through string. Default: FokaBot
	:return:
	"""
	glob.db.execute("INSERT INTO rap_logs (id, userid, text, datetime, through) VALUES (NULL, %s, %s, %s, %s)", [userID, message, int(time.time()), through])
	username = userUtils.getUsername(userID)
	logMessage("{} {}".format(username, message), discord=True)
Пример #10
0
def connect():
    """
	Connect FokaBot to Bancho.

	:return:
	"""
    glob.BOT_NAME = userUtils.getUsername(999)
    token = glob.tokens.addToken(999)
    token.actionID = actions.IDLE
    token.country = 244
    token.actionText = " Enjoy Mikoto v3"
    glob.streams.broadcast("main", serverPackets.userPanel(999))
    glob.streams.broadcast("main", serverPackets.userStats(999))
Пример #11
0
def connect(timeOffset=9):
    """
	Connect FokaBot to Bancho

	:return:
	"""
    glob.BOT_NAME = userUtils.getUsername(999)
    token = glob.tokens.addToken(999)
    token.actionID = actions.IDLE
    token.actionText = "\n-- Welcome to Ainu --"
    token.timeOffset = timeOffset
    token.timezone = 24 + token.timeOffset
    token.country = 111
    glob.streams.broadcast("main", serverPackets.userPanel(999))
    glob.streams.broadcast("main", serverPackets.userStats(999))
Пример #12
0
def connect(timeOffset = 9):
	"""
	Connect FokaBot to Bancho

	:return:
	"""
	glob.BOT_NAME = userUtils.getUsername(999)
	token = glob.tokens.addToken(999)
	token.actionID = actions.IDLE
	token.actionText = "\nChoo Choo"
	token.pp = 0
	token.accuracy = 0
	token.playcount = 0
	token.totalScore = 0
	token.timeOffset = timeOffset
	token.timezone = 24+token.timeOffset
	token.country = 111
	glob.streams.broadcast("main", serverPackets.userPanel(999))
	glob.streams.broadcast("main", serverPackets.userStats(999))
Пример #13
0
def connect():
    """
    Connect FokaBot to Bancho

    :return:
    """
    glob.BOT_NAME = userUtils.getUsername(999)
    token = glob.tokens.addToken(999)
    token.actionID = actions.IDLE
    token.actionText = "\n欢迎来到卡服"
    token.pp = 1
    token.accuracy = 0.997
    token.playcount = 2000
    token.totalScore = 940857703
    token.timeOffset = 0
    token.timezone = 24 + 8
    token.country = 48
    glob.streams.broadcast("main", serverPackets.userPanel(999))
    glob.streams.broadcast("main", serverPackets.userStats(999))
Пример #14
0
def connect(timeOffset=9):
    """
	Connect FokaBot to Bancho

	:return:
	"""
    commandBuckets.clear()
    glob.BOT_NAME = userUtils.getUsername(1)
    token = glob.tokens.addToken(1)
    token.actionID = actions.IDLE
    token.actionText = "\n-- Welcome to Datenshi --"
    #token.pp = 69
    #token.accuracy = 0.9885
    #token.playcount = 26956
    #token.totalScore = 237228316533
    token.timeOffset = timeOffset
    token.timezone = 24 + token.timeOffset
    token.country = 111
    glob.streams.broadcast("main", serverPackets.userPanel(1))
Пример #15
0
    def asyncGet(self):
        try:
            # Get request ip
            ip = self.getRequestIP()

            # Check arguments
            if not requestsManager.checkArguments(self.request.arguments,
                                                  ["c", "k"]):
                raise exceptions.invalidArgumentsException(MODULE_NAME)

            # Get arguments
            key = self.get_argument("k")
            targetID = self.get_argument("c")

            if key is None or key != generalUtils.stringMd5(
                    glob.conf.config["server"]["apikey"]):
                raise exceptions.invalidArgumentsException(MODULE_NAME)

            targetUsername = userUtils.getUsername(targetID)
            if (targetUsername is None):
                raise exceptions.invalidArgumentsException(MODULE_NAME)

            # Serve replay
            log.info("Serving {}.txt".format(targetUsername))
            fileName = ".data/pl/{}.txt".format(targetUsername)
            if os.path.isfile(fileName):
                with open(fileName, "rb") as f:
                    fileContent = f.read()
                self.write(fileContent)
                self.set_header("Content-length", len(fileContent))
                self.set_header("Content-Description", "File Transfer")
                self.set_header(
                    "Content-Disposition",
                    "attachment; filename=\"{}_trace.txt\"".format(
                        targetUsername))
            else:
                log.warning("Trace {} doesn't exist".format(targetUsername))
                self.write("")
        except exceptions.invalidArgumentsException:
            pass
        except exceptions.loginFailedException:
            pass
Пример #16
0
def connect():
    """
	Connect FokaBot to Bancho

	:return:
	"""
    glob.BOT_NAME = userUtils.getUsername(999)
    token = glob.tokens.addToken(999)
    token.actionID = actions.IDLE
    token.actionText = random.choice([
        "\n-- Sotarks is gay! --", "\n-- ck was here --",
        "\n-- Welcome to Kurikku --", "\n-- KotRik is not a gay --",
        "\n-- osu!godland is deprecated --", "\n-- rarenai #1 in 2019 --",
        "\n-- Plz don't use aoba switcher, it sucks --",
        "\n-- Maybe u wanna play HDDTHR? --", "\n-- 727pp isn't comming( --",
        "\n-- flipzky is too lazy to make tourney ;d --",
        "\n-- i wanna 100 players online ;d --"
    ])
    glob.streams.broadcast("main", serverPackets.userPanel(999))
    glob.streams.broadcast("main", serverPackets.userStats(999))
Пример #17
0
def connect():
    """
	Connect FokaBot to Bancho

	:return:
	"""
    glob.BOT_NAME = userUtils.getUsername(999)
    token = glob.tokens.addToken(999)
    token.actionID = actions.WATCHING
    token.actionText = "over RealistikOsu!"
    token.pp = 69
    token.accuracy = 0.69
    token.playcount = 69
    token.totalScore = 1337
    token.timeOffset = 0
    token.timezone = 24
    token.country = 2  #this is retared, f**k it im keeping it as europe, couldnt find the uk as its ordered stupidly
    token.location = (39.01955903386848, 125.75276158057767
                      )  # Pyongyang red square
    glob.streams.broadcast("main", serverPackets.userPanel(999))
    glob.streams.broadcast("main", serverPackets.userStats(999))
Пример #18
0
 def help(response, token, sender, channel, message):
     userID = userUtils.getID(sender)
     for command, command_data in commands.items():
         chat.sendMessage(
             glob.BOT_NAME, sender,
             f"mp {command} {command_data.syntax} {('(requires %s or higher)' % (command_data.perm,) if command_data.perm != 'basic' else '') if command_data.mpOnly else '*can be used outside mp room*'}"
             .strip())
     chat.sendMessage(
         glob.BOT_NAME, sender,
         "This command still underwent heavy rewriting, those ugly terms and such will go soon(TM)."
     )
     chat.sendMessage(
         glob.BOT_NAME, sender,
         "Let (us) me know about the bancho mimicking that I need to do, I'll do my best!"
     )
     gloryID = 3  # oi.
     if userID == gloryID:
         chat.sendMessage(glob.BOT_NAME, sender,
                          "-- a note that you left behind.")
     else:
         gloryName = userUtils.getUsername(gloryID)
         chat.sendMessage(glob.BOT_NAME, sender, f"-- {gloryName}.")
     pass
Пример #19
0
def call(m, *args, user_id=None, discord_m=False, embed_args=None):
    try:
        if flavours.config is None:
            cache_config()

        username = None
        if user_id != None:
            username = userUtils.getUsername(user_id)
            m = m.replace("USERNAME()", username)

        if flavours.config["webhook"]["enable"] and discord_m:
            if embed_args != None:
                embed = Webhook(flavours.config["webhook"]["url"],
                                **embed_args,
                                footer="Caker by Sunpy @osufx",
                                footer_icon="http://i.imgur.com/NCYspz8.png")
            else:
                embed = Webhook(flavours.config["webhook"]["url"], msg=m)

            embed.post()
    except Exception as e:
        s_print("Unable to call police; {}".format(str(e)))

    s_print(m)
Пример #20
0
def getRankInfo(userID, gameMode, mode='normal'):
    """
	Get userID's current rank, user above us and pp/score difference

	:param userID: user
	:param gameMode: gameMode number
	:return: {"nextUsername": "", "difference": 0, "currentRank": 0}
	"""
    data = {"nextUsername": "", "difference": 0, "currentRank": 0}
    if features.RANKING_SCOREV2 and mode == 'alternative':
        k = "ripple:leaderboard_alt:{}"
        position = userUtils.getGameRankAlt(userID, gameMode) - 1
    elif mode == 'relax':
        k = "ripple:leaderboard_relax:{}"
        position = userUtils.getGameRankRx(userID, gameMode) - 1
    else:
        k = "ripple:leaderboard:{}"
        position = userUtils.getGameRank(userID, gameMode) - 1
    k = k.format(scoreUtils.readableGameMode(gameMode))
    log.debug("Our position is {}".format(position))
    if position is not None and position > 0:
        aboveUs = glob.redis.zrevrange(k, position - 1, position)
        log.debug("{} is above us".format(aboveUs))
        if aboveUs is not None and len(aboveUs) > 0 and aboveUs[0].isdigit():
            # Get our rank, next rank username and pp/score difference
            myScore = glob.redis.zscore(k, userID)
            otherScore = glob.redis.zscore(k, aboveUs[0])
            nextUsername = userUtils.getUsername(aboveUs[0])
            if nextUsername is not None and myScore is not None and otherScore is not None:
                data["nextUsername"] = nextUsername
                data["difference"] = int(myScore) - int(otherScore)
    else:
        position = 0

    data["currentRank"] = position + 1
    return data
Пример #21
0
    def __init__(self,
                 userID,
                 token_=None,
                 ip="",
                 irc=False,
                 timeOffset=0,
                 tournament=False):
        """
		Create a token object and set userID and token

		:param userID: user associated to this token
		:param token_: 	if passed, set token to that value
						if not passed, token will be generated
		:param ip: client ip. optional.
		:param irc: if True, set this token as IRC client. Default: False.
		:param timeOffset: the time offset from UTC for this user. Default: 0.
		:param tournament: if True, flag this client as a tournement client. Default: True.
		"""
        # Set stuff
        self.userID = userID
        self.username = userUtils.getUsername(self.userID)
        self.safeUsername = userUtils.getSafeUsername(self.userID)
        self.privileges = userUtils.getPrivileges(self.userID)
        self.admin = userUtils.isInPrivilegeGroup(self.userID, "developer")\
            or userUtils.isInPrivilegeGroup(self.userID, "community manager")\
            or userUtils.isInPrivilegeGroup(self.userID, "chat mod")
        self.irc = irc
        self.kicked = False
        self.restricted = userUtils.isRestricted(self.userID)
        self.loginTime = int(time.time())
        self.pingTime = self.loginTime
        self.timeOffset = timeOffset
        self.streams = []
        self.tournament = tournament
        self.messagesBuffer = []

        # Default variables
        self.spectators = []

        # TODO: Move those two vars to a class
        self.spectating = None
        self.spectatingUserID = 0  # we need this in case we the host gets DCed

        self.location = [0, 0]
        self.joinedChannels = []
        self.ip = ip
        self.country = 0
        self.location = [0, 0]
        self.awayMessage = ""
        self.sentAway = []
        self.matchID = -1
        self.tillerino = [0, 0, -1.0]  # beatmap, mods, acc
        self.silenceEndTime = 0
        self.queue = bytes()

        # Spam protection
        self.spamRate = 0

        # Stats cache
        if userID == 1000:
            self.actionID = actions.WATCHING
        else:
            self.actionID = actions.IDLE
        if userID == 1000:
            self.actionText = "HentaiHaven"
        else:
            self.actionText = ""
        self.actionMd5 = ""
        self.actionMods = 0
        self.gameMode = gameModes.STD
        self.beatmapID = 0
        self.rankedScore = 0
        self.accuracy = 0.0
        self.playcount = 0
        self.totalScore = 0
        self.gameRank = 0
        self.pp = 0

        # Relax
        self.relaxing = False
        self.relaxAnnounce = False

        # Generate/set token
        if token_ is not None:
            self.token = token_
        else:
            self.token = str(uuid.uuid4())

        # Locks
        self.processingLock = threading.Lock(
        )  # Acquired while there's an incoming packet from this user
        self._bufferLock = threading.Lock(
        )  # Acquired while writing to packets buffer
        self._spectLock = threading.RLock()

        # Set stats
        self.updateCachedStats()

        # If we have a valid ip, save bancho session in DB so we can cache LETS logins
        if ip != "":
            userUtils.saveBanchoSession(self.userID, self.ip)

        # Join main stream
        self.joinStream("main")
Пример #22
0
def eat(score, processes, detected, flags):
    if flavours.config is None:
        police.cache_config()

    do_restrict = False
    for toppings in detected:
        if toppings["ban"]:
            do_restrict = True

    tag_list = [x["tag"] for x in detected]

    hax_flags = flags & ~ice_coffee.IGNORE_HAX_FLAGS
    beatmap_id = get_beatmap_id(score.fileMd5)["beatmap_id"]

    username = userUtils.getUsername(score.playerUserID)

    fields = [{
        "name":
        "BeatmapID: {}".format(beatmap_id),
        "value":
        "[Download Beatmap](http://{}/b/{})".format(
            flavours.config["urls"]["main_domain"], beatmap_id),
        "inline":
        True
    }, {
        "name":
        "ScoreID: {}".format(score.scoreID),
        "value":
        "[Download Replay](http://{}/web/replays/{})".format(
            flavours.config["urls"]["main_domain"], score.scoreID),
        "inline":
        True
    }]

    if len(detected) > 0:
        reason = " & ".join(tag_list)
        if len(reason) > 86:
            reason = "reasons..."

        extra_data = ""
        if hax_flags != 0:
            extra_data = "\nHad bad flags: ({}) -> ({})".format(
                flags, make_flags_string(flags))

        if do_restrict:
            userUtils.restrict(score.playerUserID)
            userUtils.appendNotes(score.playerUserID,
                                  "Restricted due to {}".format(reason))
            police.call("{} was restricted for: {} {}".format(
                username, reason, extra_data),
                        discord_m=True,
                        embed_args={
                            "color":
                            0xd9534f,
                            "title":
                            "Bad cake detected",
                            "title_url":
                            "http://old.{}/index.php?p=129&sid={}".format(
                                flavours.config["urls"]["main_domain"],
                                score.scoreID),
                            "desc":
                            "Restricted for: {} {}".format(reason, extra_data),
                            "author":
                            username,
                            "author_icon":
                            "http://a.{}/{}".format(
                                flavours.config["urls"]["main_domain"],
                                score.playerUserID),
                            "author_url":
                            "http://{}/u/{}".format(
                                flavours.config["urls"]["main_domain"],
                                score.playerUserID),
                            "thumbnail":
                            flavours.config["images"]["bad_cake_ban"],
                            "fields":
                            fields
                        })
        else:
            userUtils.appendNotes(score.playerUserID, reason)
            police.call("{} submitted bad cake: {} {}".format(
                username, reason, extra_data),
                        discord_m=True,
                        embed_args={
                            "color":
                            0xf0ad4e,
                            "title":
                            "Bad cake detected",
                            "title_url":
                            "http://old.{}/index.php?p=129&sid={}".format(
                                flavours.config["urls"]["main_domain"],
                                score.scoreID),
                            "desc":
                            "Had bad cake: {} {}".format(reason, extra_data),
                            "author":
                            username,
                            "author_icon":
                            "http://a.{}/{}".format(
                                flavours.config["urls"]["main_domain"],
                                score.playerUserID),
                            "author_url":
                            "http://{}/u/{}".format(
                                flavours.config["urls"]["main_domain"],
                                score.playerUserID),
                            "thumbnail":
                            flavours.config["images"]["bad_cake"],
                            "fields":
                            fields
                        })
    elif hax_flags != 0:
        police.call(
            "{} submitted bad flags: ({}) -> ({})".format(
                username, flags, make_flags_string(flags)),
            discord_m=True,
            embed_args={
                "color":
                0xf0ad4e,
                "title":
                "Bad flags detected",
                "title_url":
                "http://old.{}/index.php?p=129&sid={}".format(
                    flavours.config["urls"]["main_domain"], score.scoreID),
                "desc":
                "({}) -> ({})".format(flags, make_flags_string(flags)),
                "author":
                username,
                "author_icon":
                "http://a.{}/{}".format(flavours.config["urls"]["main_domain"],
                                        score.playerUserID),
                "author_url":
                "http://{}/u/{}".format(flavours.config["urls"]["main_domain"],
                                        score.playerUserID),
                "thumbnail":
                flavours.config["images"]["bad_flag"],
                "fields":
                fields
            })

    glob.db.execute(
        "INSERT INTO cakes(id, userid, score_id, processes, detected, flags) VALUES (NULL,%s,%s,%s,%s,%s)",
        [
            score.playerUserID, score.scoreID,
            json.dumps(processes),
            json.dumps(tag_list), flags
        ])
Пример #23
0
def edit_map(fro, chan, message): # Edit maps ranking status ingame. // Added by cmyui :) // cmyui why u dont like PEP8?
    messages = [m.lower() for m in message]
    rank_type = message[0]
    map_type = message[1]
    map_id = message[2]

    # Get persons username & ID
    user_id = userUtils.getID(fro)
    name = userUtils.getUsername(user_id)

    typeBM = None

    # Figure out what to do
    if rank_type == 'rank':
        rank_typed_str = 'ranke'
        rank_type_id = 2
        freeze_status = 1
    elif rank_type == 'love':
        rank_typed_str = 'love'
        rank_type_id = 5
        freeze_status = 1
    elif rank_type == 'unrank':
        rank_typed_str = 'unranke'
        rank_type_id = 0
        freeze_status = 0

    # Grab beatmap_data from db
    beatmap_data = glob.db.fetch("SELECT * FROM beatmaps WHERE beatmap_id = {} LIMIT 1".format(map_id))

    if map_type == 'set':
        glob.db.execute(
            "UPDATE beatmaps SET ranked = {}, ranked_status_freezed = {} WHERE beatmapset_id = {} LIMIT 100".format(
                rank_type_id, freeze_status, beatmap_data["beatmapset_id"]))
        if freeze_status == 1:
            glob.db.execute("""UPDATE scores s JOIN (SELECT userid, MAX(score) maxscore FROM scores JOIN beatmaps ON scores.beatmap_md5 = beatmaps.beatmap_md5 WHERE beatmaps.beatmap_md5 = (SELECT beatmap_md5 FROM beatmaps
					WHERE beatmapset_id = {} LIMIT 1) GROUP BY userid) s2 ON s.score = s2.maxscore AND s.userid = s2.userid SET completed = 3""".format(
                beatmap_data["beatmapset_id"]))
        typeBM = 'set'
    elif map_type == 'map':
        glob.db.execute(
            "UPDATE beatmaps SET ranked = {}, ranked_status_freezed = {} WHERE beatmap_id = {} LIMIT 1".format(
                rank_type_id, freeze_status, map_id))
        if freeze_status == 1:
            glob.db.execute("""UPDATE scores s JOIN (SELECT userid, MAX(score) maxscore FROM scores JOIN beatmaps ON scores.beatmap_md5 = beatmaps.beatmap_md5 WHERE beatmaps.beatmap_md5 = (SELECT beatmap_md5 FROM beatmaps
					WHERE beatmap_id = {} LIMIT 1) GROUP BY userid) s2 ON s.score = s2.maxscore AND s.userid = s2.userid SET completed = 3""".format(
                beatmap_data["beatmap_id"]))
        typeBM = 'beatmap'
    else:
        return "Please specify whether it is a set/map. eg: '!map unrank/rank/love set/map 123456'"

    # Announce / Log to AP logs when ranked status is changed
    if rank_type == "love":
        log.rap(user_id,
                "has {}d beatmap ({}): {} ({}).".format(rank_type, map_type, beatmap_data["song_name"], map_id),
                True)
        if map_type == 'set':
            msg = "{} has loved beatmap set: [https://osu.ppy.sh/s/{} {}]".format(name, beatmap_data["beatmapset_id"],
                                                                                  beatmap_data["song_name"])
        else:
            msg = "{} has loved beatmap: [https://osu.ppy.sh/s/{} {}]".format(name, map_id, beatmap_data["song_name"])

        glob.db.execute(
            "UPDATE scores s JOIN (SELECT userid, MAX(score) maxscore FROM scores JOIN beatmaps ON scores.beatmap_md5 = beatmaps.beatmap_md5 WHERE beatmaps.beatmap_md5 = (SELECT beatmap_md5 FROM beatmaps WHERE beatmap_id = {} LIMIT 1) GROUP BY userid) s2 ON s.score = s2.maxscore AND s.userid = s2.userid SET completed = 2".format(
                beatmap_data["beatmap_id"]))
    elif rank_type == "rank":
        log.rap(user_id,
                "has {}ed beatmap ({}): {} ({}).".format(rank_type, map_type, beatmap_data["song_name"], map_id),
                True)
        if map_type == 'set':
            msg = "{} has {}ed beatmap set: [https://osu.ppy.sh/s/{} {}]".format(name, rank_type,
                                                                                 beatmap_data["beatmapset_id"],
                                                                                 beatmap_data["song_name"])
        else:
            msg = "{} has {}ed beatmap: [https://osu.ppy.sh/s/{} {}]".format(name, rank_type, map_id,
                                                                             beatmap_data["song_name"])
        glob.db.execute(
            "UPDATE scores s JOIN (SELECT userid, MAX(score) maxscore FROM scores JOIN beatmaps ON scores.beatmap_md5 = beatmaps.beatmap_md5 WHERE beatmaps.beatmap_md5 = (SELECT beatmap_md5 FROM beatmaps WHERE beatmap_id = {} LIMIT 1) GROUP BY userid) s2 ON s.score = s2.maxscore AND s.userid = s2.userid SET completed = 2".format(
                beatmap_data["beatmap_id"]))
    else:
        log.rap(user_id,
                "has {}ed beatmap ({}): {} ({}).".format(rank_type, map_type, beatmap_data["song_name"], map_id),
                True)
        if map_type == 'set':
            msg = "{} has {}ed beatmap set: [https://osu.ppy.sh/s/{} {}]".format(name, rank_type,
                                                                                 beatmap_data["beatmapset_id"],
                                                                                 beatmap_data["song_name"])
        else:
            msg = "{} has {}ed beatmap: [https://osu.ppy.sh/s/{} {}]".format(name, rank_type, map_id,
                                                                             beatmap_data["song_name"])

            glob.db.execute(
                "UPDATE scores s JOIN (SELECT userid, MAX(score) maxscore FROM scores JOIN beatmaps ON scores.beatmap_md5 = beatmaps.beatmap_md5 WHERE beatmaps.beatmap_md5 = (SELECT beatmap_md5 FROM beatmaps WHERE beatmap_id = {} LIMIT 1) GROUP BY userid) s2 ON s.score = s2.maxscore AND s.userid = s2.userid SET completed = 2".format(
                    beatmap_data["beatmap_id"]))

    need_params = {
        'token': glob.conf.config["discord"]["krbotToken"],
        'poster': fro,
        'type': rank_typed_str
    }
    if typeBM == 'set':
        need_params['sid'] = beatmap_data["beatmapset_id"]
    else:
        need_params['bid'] = beatmap_data["beatmap_id"]
    requests.get(glob.conf.config["discord"]["krbot"] + "api/v1/submitMap", params=need_params)

    chat.sendMessage(glob.BOT_NAME, "#nowranked", msg)
    return msg
Пример #24
0
    def __init__(self,
                 userID,
                 token_=None,
                 ip="",
                 irc=False,
                 timeOffset=0,
                 tournament=False,
                 ignoreDM=False):
        """
		Create a token object and set userID and token

		:param userID: user associated to this token
		:param token_: 	if passed, set token to that value
						if not passed, token will be generated
		:param ip: client ip. optional.
		:param irc: if True, set this token as IRC client. Default: False.
		:param timeOffset: the time offset from UTC for this user. Default: 0.
		:param tournament: if True, flag this client as a tournement client. Default: True.
		"""
        # Set stuff
        self.userID = userID
        self.username = userUtils.getUsername(self.userID)
        self.safeUsername = userUtils.getSafeUsername(self.userID)
        self.privileges = userUtils.getPrivileges(self.userID)
        self.admin = userUtils.isInPrivilegeGroup(self.userID, "Developer")\
            or userUtils.isInPrivilegeGroup(self.userID, "Community Manager")\
            or userUtils.isInPrivilegeGroup(self.userID, "Chat Moderators")
        self.irc = irc
        self.kicked = False
        self.restricted = userUtils.isRestricted(self.userID)
        self.loginTime = int(time.time())
        self.pingTime = self.loginTime
        self.timeOffset = timeOffset
        self.streams = []
        self.tournament = tournament
        self.messagesBuffer = []

        # Default variables
        self.spectators = []

        # TODO: Move those two vars to a class
        self.spectating = None
        self.spectatingUserID = 0  # we need this in case we the host gets DCed

        self.location = [0, 0]
        self.joinedChannels = []
        self.ip = ip
        self.country = 0
        self.location = [0, 0]
        self.awayMessage = ""
        self.sentAway = []
        self.matchID = -1
        self.tillerino = [0, 0, -1.0]  # beatmap, mods, acc
        self.silenceEndTime = 0
        self.queue = bytes()

        # Spam protection
        self.spamRate = 0

        # Stats cache
        def check_hax_initial():
            stmt = [
                "SELECT initial_status_type as aid, initial_status_text as atxt",
                "FROM bancho_status_hax", "WHERE user_id = %s AND NOT",
                "(initial_status_type IS NULL OR initial_status_text IS NULL OR length(initial_status_text) < 1)"
            ]
            result = glob.db.fetch(" ".join(stmt), [userID])
            if result is None:
                self.actionID, self.actionText = actions.IDLE, ""
            else:
                self.actionID, self.actionText = result['aid'], result['atxt']
            pass

        check_hax_initial()
        self.actionMd5 = ""
        self.actionMods = 0
        self.gameMode = gameModes.STD
        self.beatmapID = 0
        self.rankedScore = 0
        self.accuracy = 0.0
        self.playcount = 0
        self.totalScore = 0
        self.gameRank = 0

        self.noticeFlags = []

        self.pp = 0
        self._ignoreDM = ignoreDM

        self.specialMode = 0

        # Generate/set token
        if token_ is not None:
            self.token = token_
        else:
            self.token = str(uuid.uuid4())

        # Locks
        self.processingLock = threading.Lock(
        )  # Acquired while there's an incoming packet from this user
        self._bufferLock = threading.Lock(
        )  # Acquired while writing to packets buffer
        self._spectLock = threading.RLock()

        # Set stats
        self.updateCachedStats()

        # If we have a valid ip, save bancho session in DB so we can cache LETS logins
        if ip != "":
            userUtils.saveBanchoSession(self.userID, self.ip)

        # Join main stream
        self.joinStream("main")
Пример #25
0
    def allPlayersCompleted(self):
        """
		Cleanup match stuff and send match end packet to everyone

		:return:
		"""
        # Collect some info about the match that just ended to send to the api
        infoToSend = {
            "id": self.matchID,
            "name": self.matchName,
            "beatmap_id": self.beatmapID,
            "mods": self.mods,
            "game_mode": self.gameMode,
            "host_id": self.hostUserID,
            "host_user_name": userUtils.getUsername(self.hostUserID),
            "game_type": self.matchTeamType,
            "game_score_condition": self.matchScoringType,
            "game_mod_mode": self.matchModMode,
            "scores": {}
        }

        # Add score info for each player
        for i in range(0, 16):
            if self.slots[i].user is not None and self.slots[
                    i].status == slotStatuses.PLAYING:
                infoToSend["scores"][glob.tokens.tokens[
                    self.slots[i].user].userID] = {
                        "score":
                        self.slots[i].score,
                        "mods":
                        self.slots[i].mods,
                        "failed":
                        self.slots[i].failed,
                        "pass":
                        self.slots[i].passed,
                        "team":
                        self.slots[i].team,
                        "username":
                        userUtils.getUsername(glob.tokens.tokens[
                            self.slots[i].user].userID)  # vinse shit ;3
                    }

        # Send the info to the api
        glob.redis.publish("api:mp_complete_match", json.dumps(infoToSend))
        self.games.append(json.dumps(infoToSend))

        # Reset inProgress
        self.inProgress = False

        # Reset slots
        self.resetSlots()

        # Send match update
        self.sendUpdates()

        # Send match complete
        glob.streams.broadcast(self.streamName, serverPackets.matchComplete())

        # Destroy playing stream
        glob.streams.dispose(self.playingStreamName)
        glob.streams.remove(self.playingStreamName)

        # Console output
        log.info("MPROOM{}: Match completed".format(self.matchID))

        # If this is a tournament match, then we send a notification in the chat
        # saying that the match has completed.
        chanName = "#multi_{}".format(self.matchID)
        if self.isTourney and (chanName in glob.channels.channels):
            chat.sendMessage(glob.BOT_NAME, chanName,
                             "Match has just finished.")