Skip to content

Commit

Permalink
project *= 2
Browse files Browse the repository at this point in the history
  • Loading branch information
cmyui committed Jul 1, 2020
1 parent ec46989 commit 1903de3
Show file tree
Hide file tree
Showing 8 changed files with 596 additions and 174 deletions.
61 changes: 49 additions & 12 deletions constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ class Privileges(IntFlag):
Supporter = 1 << 5 # Has tier 1 donor
Premium = 1 << 6 # Has tier 2 donor

Mod = 1 << 9 # Can use basic moderation tools (silence, kick).
Nominator = 1 << 10 # Can change the ranked-status of beatmaps.
Nominator = 1 << 9 # Can change the ranked-status of beatmaps.
Mod = 1 << 10 # Can use basic moderation tools (silence, kick).

Admin = 1 << 14 # Can access user information, and restrict/ban/etc.
Dangerous = 1 << 18 # Can access potentially dangerous information
Expand All @@ -31,14 +31,51 @@ class BanchoPrivileges(IntFlag):

@unique
class Type(IntEnum):
i8 = 0 # even needed?
i16 = 1
u16 = 2
i32 = 3
u32 = 4
i64 = 5
u64 = 6

i32_list = 8
string = 10
i8 = 0
u8 = 1
i16 = 2
u16 = 3
i32 = 4
u32 = 5
f32 = 6
i64 = 7
u64 = 8
f64 = 9

i32_list = 10
string = 11
raw = 12

@unique
class Mods(IntEnum):
NOMOD = 0
NOFAIL = 1 << 0
EASY = 1 << 1
TOUCHSCREEN = 1 << 2
HIDDEN = 1 << 3
HARDROCK = 1 << 4
SUDDENDEATH = 1 << 5
DOUBLETIME = 1 << 6
RELAX = 1 << 7
HALFTIME = 1 << 8
NIGHTCORE = 1 << 9
FLASHLIGHT = 1 << 10
AUTOPLAY = 1 << 11
SPUNOUT = 1 << 12
RELAX2 = 1 << 13
PERFECT = 1 << 14
KEY4 = 1 << 15
KEY5 = 1 << 16
KEY6 = 1 << 17
KEY7 = 1 << 18
KEY8 = 1 << 19
KEYMOD = 1 << 20
FADEIN = 1 << 21
RANDOM = 1 << 22
LASTMOD = 1 << 23
KEY9 = 1 << 24
KEY10 = 1 << 25
KEY1 = 1 << 26
KEY3 = 1 << 27
KEY2 = 1 << 28
SCOREV2 = 1 << 29
63 changes: 63 additions & 0 deletions db.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
create table stats
(
id int auto_increment
primary key,
tscore_vn_std int not null,
tscore_vn_taiko int not null,
tscore_vn_catch int not null,
tscore_vn_mania int not null,
tscore_rx_std int not null,
tscore_rx_taiko int not null,
tscore_rx_catch int not null,
tscore_rx_mania int null,
rscore_vn_std int not null,
rscore_vn_taiko int not null,
rscore_vn_catch int not null,
rscore_vn_mania int not null,
rscore_rx_std int not null,
rscore_rx_taiko int not null,
rscore_rx_catch int not null,
rscore_rx_mania int null,
pp_vn_std smallint(6) not null,
pp_vn_taiko smallint(6) not null,
pp_vn_catch smallint(6) not null,
pp_vn_mania smallint(6) not null,
pp_rx_std smallint(6) not null,
pp_rx_taiko smallint(6) not null,
pp_rx_catch smallint(6) not null,
pp_rx_mania smallint(6) null,
playcount_vn_std int not null,
playcount_vn_taiko int not null,
playcount_vn_catch int not null,
playcount_vn_mania int not null,
playcount_rx_std int not null,
playcount_rx_taiko int not null,
playcount_rx_catch int not null,
playcount_rx_mania int null,
playtime_vn_std int not null,
playtime_vn_taiko int not null,
playtime_vn_catch int not null,
playtime_vn_mania int not null,
playtime_rx_std int not null,
playtime_rx_taiko int not null,
playtime_rx_catch int not null,
playtime_rx_mania int null,
acc_vn_std float(5,3) not null,
acc_vn_taiko float(5,3) not null,
acc_vn_catch float(5,3) not null,
acc_vn_mania float(5,3) not null,
acc_rx_std float(5,3) not null,
acc_rx_taiko float(5,3) not null,
acc_rx_catch float(5,3) not null,
acc_rx_mania float(5,3) null,
maxcombo_vn_std int not null,
maxcombo_vn_taiko int not null,
maxcombo_vn_catch int not null,
maxcombo_vn_mania int not null,
maxcombo_rx_std int not null,
maxcombo_rx_taiko int not null,
maxcombo_rx_catch int not null,
maxcombo_rx_mania int null,
constraint stats_users_id_fk
foreign key (id) references users (id)
);
57 changes: 57 additions & 0 deletions objects/collections.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
from typing import Tuple
from objects.player import Player
from objects.channel import Channel
from constants import Privileges

class ChannelList:
def __init__(self):
self.channels = []

def get(self, name: str) -> Channel:
for c in self.channels:
if c.name == name:
return c

def add(self, p: Channel) -> None: # bool ret success?
if p in self.channels:
print(f'{p.name} already in channels list!')
return
print(f'Adding {p.name} to channels list.')
self.channels.append(p)

def remove(self, p: Channel) -> None:
print(f'Removing {p.name} from channels list.')
self.channels.remove(p)

class PlayerList:
def __init__(self):
self.players = []

@property
def ids(self) -> Tuple[int]:
return (p.id for p in self.players)

def broadcast(self, data: bytes) -> None:
for p in self.players: # no idea if it takes ref
p.enqueue(data)

def get(self, token: str) -> Player:
for p in self.players: # might copy
if p.token == token:
return p

def get_by_id(self, id: int) -> Player:
for p in self.players: # might copy
if p.id == id:
return p

def add(self, p: Player) -> None: # bool ret success?
if p in self.players:
print(f'{p.name} ({p.id}) already in players list!')
return
print(f'Adding {p.name} ({p.id}) to players list.')
self.players.append(p)

def remove(self, p: Player) -> None:
print(f'Removing {p.name} ({p.id}) from players list.')
self.players.remove(p)
5 changes: 5 additions & 0 deletions objects/glob.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from objects.collections import PlayerList, ChannelList

players = PlayerList()
channels = ChannelList()
db = None # too lazy
142 changes: 98 additions & 44 deletions objects/player.py
Original file line number Diff line number Diff line change
@@ -1,37 +1,85 @@
from typing import Tuple
from random import choices
from string import ascii_lowercase
from constants import Privileges, BanchoPrivileges
import config

from objects import glob
from enum import IntEnum
from queue import SimpleQueue

class ModeData:
def __init__(self):
self.total_score = 0
self.ranked_score = 0
self.tscore = 0
self.rscore = 0
self.pp = 0
self.play_count = 0
self.playcount = 0
self.acc = 0.0
self.rank = 0
self.max_combo = 0

class Stats:
def __init__(self):
self.vanilla = [ModeData] * 4
self.relax = [ModeData] * 3

def from_sql(self, ID: int) -> None:
if not (res := config.db.execute(
'SELECT '
)):
pass
def update(self, **kwargs) -> None:
self.tscore = kwargs.get('tscore', 0)
self.rscore = kwargs.get('rscore', 0)
self.pp = kwargs.get('pp', 0)
self.playcount = kwargs.get('playcount', 0)
self.acc = kwargs.get('acc', 0.0)
self.rank = kwargs.get('rank', 0)
self.max_combo = kwargs.get('max_combo', 0)

class GameMode(IntEnum):
# This is another place where some
# inspiration was taken from rumoi/ruri.
vn_std = 0,
vn_taiko = 1,
vn_catch = 2,
vn_mania = 3,
rx_std = 4,
rx_taiko = 5,
rx_catch = 6

def __str__(self) -> str:
return {
0: 'vn!std',
1: 'vn!taiko',
2: 'vn!catch',
3: 'vn!mania',

4: 'rx!std',
5: 'rx!taiko',
6: 'rx!catch'
}[self.value]

def __format__(self, format: str) -> str:
# lmao
return {
0: 'vn_std',
1: 'vn_taiko',
2: 'vn_catch',
3: 'vn_mania',

4: 'rx_std',
5: 'rx_taiko',
6: 'rx_catch'
}[self.value] if format == 'sql' else str(self.value)

class Status:
def __init__(self):
self.action = None
self.info_text = None
self.beatmap_md5 = None
self.mods = None
self.game_mode = None
self.beatmap = None
self.action = 0 # byte
self.info_text = '' # string
self.beatmap_md5 = '' # string
self.mods = 0 # i32
self.game_mode = 0 # byte
self.beatmap_id = 0 # i32

def update(self, action, info_text, beatmap_md5,
mods, game_mode, beatmap_id) -> None:
self.action = action
self.info_text = info_text
self.beatmap_md5 = beatmap_md5
self.mods = mods
self.game_mode = game_mode
self.beatmap_id = beatmap_id

class Player:
def __init__(self, *args, **kwargs) -> None:
Expand All @@ -42,14 +90,19 @@ def __init__(self, *args, **kwargs) -> None:
self.safe_name = self.ensure_safe(self.name) if self.name else None
self.priv = Privileges(kwargs.get('priv', Privileges.Banned))

self.stats = Stats()
self.rx = False # stored for ez use
self.stats = [ModeData()] * 7 # disclude mania rx
self.stats_from_sql_full() # yeet?
self.status = Status()
self.channels = []

self.country = kwargs.get('country', None)
self.utc_offset = kwargs.get('utc_offset', 0)
self.pm_private = kwargs.get('pm_private', False)

# Packet queue
self._queue = SimpleQueue()

self.ping_time = 0

def join_channel(self, chan) -> None:
Expand All @@ -60,6 +113,9 @@ def leave_channel(self, chan) -> None:
print(f'{self.name} ({self.id}) left {chan.name}.')
self.channels.remove(chan)

def enqueue(self, b: bytes) -> None:
self._queue.put_nowait(b)

@staticmethod
def ensure_safe(name: str) -> str:
return name.lower().replace(' ', '_')
Expand All @@ -79,27 +135,25 @@ def bancho_priv(self) -> int:
ret |= BanchoPrivileges.Owner
return ret

class PlayerManager:
def __init__(self):
self.players = []

def get(self, token: str) -> Player:
for p in self.players: # might copy
if p.token == token:
return p

def get_by_id(self, id: int) -> Player:
for p in self.players: # might copy
if p.id == id:
return p

def add(self, p: Player) -> None: # bool ret success?
if p in self.players:
print(f'{p.name} ({p.id}) already in players list!')
return
print(f'Adding {p.name} ({p.id}) to players list.')
self.players.append(p)

def remove(self, p: Player) -> None:
print(f'Removing {p.name} ({p.id}) from players list.')
self.players.remove(p)
##
### User stats
##

def stats_from_sql_full(self) -> None:
for gm in GameMode:
if not (res := glob.db.fetch(
'SELECT tscore_{0:sql} tscore, rscore_{0:sql} rscore, '
'pp_{0:sql} pp, playcount_{0:sql} playcount, acc_{0:sql} acc, '
'maxcombo_{0:sql} FROM stats WHERE id = %s'.format(gm), [self.id])
): raise Exception(f"Failed to fetch {self.id}'s {gm!s} user stats.")

self.stats[gm].update(**res)

def stats_from_db(self, id: int, gm: int) -> None:
if not (res := glob.db.fetch(
'SELECT tscore_{0:sql} tscore, rscore_{0:sql} rscore, '
'pp_{0:sql} pp, playcount_{0:sql} playcount, acc_{0:sql} acc, '
'maxcombo_{0:sql} FROM stats WHERE id = %s'.format(gm), [id])
): raise Exception(f"Failed to fetch {id}'s {gm} user stats.")

self.stats[gm].update(**res)
10 changes: 0 additions & 10 deletions objects/status.py

This file was deleted.

0 comments on commit 1903de3

Please sign in to comment.