from objects.beatmap import Beatmap from objects.channel import Channel from objects.clan import ClanPrivileges from objects.match import MatchTeams from objects.match import MatchTeamTypes from objects.match import SlotStatus from objects.player import Action from objects.player import Player from objects.player import PresenceFilter from packets import BanchoPacket from packets import BanchoPacketReader from packets import Packets from utils.misc import make_safe_name """ Bancho: handle connections from the osu! client """ domain = Domain(re.compile(r'^c[e4-6]?\.ppy\.sh$')) @domain.route('/') async def bancho_http_handler(conn: Connection) -> bytes: """Handle a request from a web browser.""" packets = glob.bancho_packets['all'] return b'<!DOCTYPE html>' + '<br>'.join( (f'Running gulag v{glob.version}', f'Players online: {len(glob.players) - 1}', '<a href="https://github.com/cmyui/gulag">Source code</a>', '', f'<b>Packets handled ({len(packets)})</b>', '<br>'.join( [f'{p.name} ({p.value})' for p in packets]))).encode()
from objects.player import Action from objects.player import Player from objects.player import PresenceFilter from packets import BanchoPacket from packets import BanchoPacketReader from packets import Packets from utils.misc import make_safe_name try: from utils.private.localise import geoloc_fetch except ImportError: from utils.misc import geoloc_fetch """ Bancho: handle connections from the osu! client """ BASE_DOMAIN = glob.config.domain _domain_escaped = BASE_DOMAIN.replace('.', r'\.') domain = Domain(re.compile(rf'^c[e4-6]?\.({_domain_escaped})$')) @domain.route('/') async def bancho_http_handler(conn: Connection) -> bytes: # Handle requests from browser by returning html return b'<!DOCTYPE html>' + '<br>'.join( (f'Running gulag v{glob.version}', f'Players online: {len(glob.players) - 1}', '<a href="https://github.com/itekiosu/gulag">Source code</a>', '', f'<b>Packets handled ({len(glob.bancho_packets)})</b>', '<br>'.join( [f'{p.name} ({p.value})' for p in glob.bancho_packets]))).encode() @domain.route('/', methods=['POST'])
# -*- coding: utf-8 -*- import re import aiofiles from pathlib import Path from cmyui import Connection, Domain """ ava: avatar server (for both ingame & external) """ domain = Domain('a.ppy.sh') AVATARS_PATH = Path.cwd() / '.data/avatars' DEFAULT_AVATAR = AVATARS_PATH / 'default.jpg' @domain.route(re.compile(r'^/\d{1,10}(?:\.jpg)?$')) async def get_avatar(conn: Connection) -> None: path = AVATARS_PATH / f'{conn.path[1:]}.jpg' if not path.exists(): path = DEFAULT_AVATAR async with aiofiles.open(path, 'rb') as f: await conn.send(200, await f.read())
# -*- coding: utf-8 -*- import re from pathlib import Path from typing import Optional from cmyui import Connection from cmyui import Domain """ ava: avatar server (for both ingame & external) """ domain = Domain(['a.ppy.sh', 'a.miksu.pw']) AVATARS_PATH = Path.cwd() / '.data/avatars' BANNERS_PATH = Path.cwd() / '.data/banners' DEFAULT_AVATAR = AVATARS_PATH / 'default.png' DEFAULT_BANNER = BANNERS_PATH / 'default.png' @domain.route(re.compile(r'^/(?:\d{1,10}(?:\.(?:jpg|jpeg|png))?|favicon\.ico)?$')) async def get_avatar(conn: Connection) -> Optional[bytes]: filename = conn.path[1:] if '.' in filename: # user id & file extension provided path = AVATARS_PATH / filename if not path.exists(): path = DEFAULT_AVATAR elif filename not in ('', 'favicon.ico'): # user id provided - determine file extension for ext in ('jpg', 'jpeg', 'png'): path = AVATARS_PATH / f'{filename}.{ext}' if path.exists():
from constants.mods import Mods from constants import commands from constants import regexes from objects.match import MatchTeamTypes, SlotStatus, MatchTeams from objects.player import Player, PresenceFilter, Action from objects.channel import Channel from objects.beatmap import Beatmap from objects import glob from constants.privileges import Privileges from constants.gamemodes import GameMode """ Bancho: handle connections from the osu! client """ domain = Domain(re.compile(f'^c[e4-6]?(\.ppy\.sh|\.{config.domain})$')) @domain.route('/', methods=['POST']) async def bancho_handler(conn: Connection) -> bytes: if 'User-Agent' not in conn.headers: return if conn.headers['User-Agent'] != 'osu!': # most likely a request from a browser. return b'<!DOCTYPE html>' + '<br>'.join(( f'Running gulag v{glob.version}', f'Players online: {len(glob.players) - 1}', '<a href="https://github.com/cmyui/gulag">Source code</a>', '', '<b>Packets handled</b>', '<br>'.join(f'{p.name} ({p.value})' for p in glob.bancho_packets)
# -*- coding: utf-8 -*- import re import aiofiles from pathlib import Path from cmyui import Connection, Domain from objects.glob import config # just the config """ ava: avatar server (for both ingame & external) """ domain = Domain(re.compile(f'^a(\.ppy\.sh|\.{config.domain})$')) AVATARS_PATH = Path.cwd() / '.data/avatars' DEFAULT_AVATAR = AVATARS_PATH / 'default.jpg' @domain.route(re.compile(r'^/\d{1,10}(?:\.jpg)?$')) async def get_avatar(conn: Connection) -> None: path = AVATARS_PATH / f'{conn.path[1:]}.jpg' if not path.exists(): path = DEFAULT_AVATAR async with aiofiles.open(path, 'rb') as f: await conn.send(200, await f.read())
# -*- coding: utf-8 -*- import re from pathlib import Path from typing import Optional from cmyui import Connection from cmyui import Domain from objects import glob """ ava: avatar server (for both ingame & external) """ BASE_DOMAIN = glob.config.domain domain = Domain({f'a.{BASE_DOMAIN}', 'a.ppy.sh'}) AVATARS_PATH = Path.cwd() / '.data/avatars' DEFAULT_AVATAR = AVATARS_PATH / 'default.jpg' @domain.route( re.compile(r'^/(?:\d{1,10}(?:\.(?:jpg|jpeg|png))?|favicon\.ico)?$')) async def get_avatar(conn: Connection) -> Optional[bytes]: filename = conn.path[1:] if '.' in filename: # user id & file extension provided path = AVATARS_PATH / filename if not path.exists(): path = DEFAULT_AVATAR elif filename not in ('', 'favicon.ico'): # user id provided - determine file extension
# -*- coding: utf-8 -*- import re from typing import Optional from cmyui import Connection from cmyui import Domain from objects import glob """ bmap: static beatmap info (thumbnails, previews, etc.) """ BASE_DOMAIN = glob.config.domain domain = Domain({f'b.{BASE_DOMAIN}', 'b.ppy.sh'}) # for now, just send everything to osu! # eventually if we do bmap submission, we'll need this. @domain.route(re.compile(r'^.+$')) async def everything(conn: Connection) -> Optional[bytes]: conn.resp_headers['Location'] = f'https://b.ppy.sh{conn.path}' return (301, b'')
# -*- coding: utf-8 -*- import re from pathlib import Path from typing import Optional from cmyui import Connection from cmyui import Domain from objects import glob """ ava: avatar server (for both ingame & external) """ domain = Domain(f'a.{glob.config.domain}') AVATARS_PATH = Path.cwd() / '.data/avatars' DEFAULT_AVATAR = AVATARS_PATH / 'default.png' @domain.route(re.compile(r'^/(?:\d{1,10}(?:\.(?:jpg|jpeg|png|gif))?|favicon\.ico)?$')) async def get_avatar(conn: Connection) -> Optional[bytes]: filename = conn.path[1:] if '.' in filename: # user id & file extension provided path = AVATARS_PATH / filename if not path.exists(): path = DEFAULT_AVATAR elif filename not in ('', 'favicon.ico'): # user id provided - determine file extension for ext in ('jpg', 'jpeg', 'png'): path = AVATARS_PATH / f'{filename}.{ext}' if path.exists(): break else: