chore(dev): update develop environment
This commit is contained in:
56
.devcontainer/devcontainer.json
Normal file
56
.devcontainer/devcontainer.json
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
{
|
||||||
|
"name": "OSU Lazer API",
|
||||||
|
"dockerComposeFile": "docker-compose.yml",
|
||||||
|
"service": "devcontainer",
|
||||||
|
"shutdownAction": "stopCompose",
|
||||||
|
"workspaceFolder": "/workspaces/osu_lazer_api",
|
||||||
|
"customizations": {
|
||||||
|
"vscode": {
|
||||||
|
"extensions": [
|
||||||
|
"ms-python.python",
|
||||||
|
"ms-python.vscode-pylance",
|
||||||
|
"detachhead.basedpyright",
|
||||||
|
"charliermarsh.ruff",
|
||||||
|
"ms-python.debugpy",
|
||||||
|
"ms-vscode.vscode-json",
|
||||||
|
"redhat.vscode-yaml",
|
||||||
|
"ms-vscode.docker"
|
||||||
|
],
|
||||||
|
"settings": {
|
||||||
|
"python.defaultInterpreterPath": "/usr/local/bin/python",
|
||||||
|
"python.terminal.activateEnvironment": true,
|
||||||
|
"python.linting.enabled": true,
|
||||||
|
"python.linting.pylintEnabled": false,
|
||||||
|
"python.linting.flake8Enabled": false,
|
||||||
|
"python.formatting.provider": "none",
|
||||||
|
"[python]": {
|
||||||
|
"editor.defaultFormatter": "charliermarsh.ruff",
|
||||||
|
"editor.formatOnSave": true,
|
||||||
|
"editor.codeActionsOnSave": {
|
||||||
|
"source.organizeImports": "explicit"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ruff.enable": true,
|
||||||
|
"ruff.lint.enable": true,
|
||||||
|
"ruff.format.enable": true,
|
||||||
|
"ruff.importStrategy": "fromEnvironment",
|
||||||
|
"files.exclude": {
|
||||||
|
"**/__pycache__": true,
|
||||||
|
"**/*.pyc": true
|
||||||
|
},
|
||||||
|
"python.testing.pytestEnabled": true,
|
||||||
|
"python.testing.unittestEnabled": false,
|
||||||
|
"python.testing.pytestArgs": [
|
||||||
|
"."
|
||||||
|
],
|
||||||
|
"terminal.integrated.defaultProfile.linux": "bash"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"features": {
|
||||||
|
"ghcr.io/va-h/devcontainers-features/uv:1": {}
|
||||||
|
},
|
||||||
|
"forwardPorts": [8000, 3306, 6379],
|
||||||
|
"postCreateCommand": "uv sync --dev && uv run pre-commit install",
|
||||||
|
"remoteUser": "vscode"
|
||||||
|
}
|
||||||
56
.devcontainer/docker-compose.yml
Normal file
56
.devcontainer/docker-compose.yml
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
version: '3.8'
|
||||||
|
|
||||||
|
services:
|
||||||
|
devcontainer:
|
||||||
|
image: mcr.microsoft.com/devcontainers/python:3.13
|
||||||
|
volumes:
|
||||||
|
- ../..:/workspaces:cached
|
||||||
|
- ~/.ssh:/home/vscode/.ssh:ro
|
||||||
|
command: sleep infinity
|
||||||
|
networks:
|
||||||
|
- devcontainer-network
|
||||||
|
depends_on:
|
||||||
|
- mysql
|
||||||
|
- redis
|
||||||
|
environment:
|
||||||
|
DATABASE_URL: mysql+aiomysql://osu_user:osu_password@mysql:3306/osu_api
|
||||||
|
REDIS_URL: redis://redis:6379/0
|
||||||
|
SECRET_KEY: dev-secret-key-change-in-production
|
||||||
|
OSU_CLIENT_ID: "5"
|
||||||
|
OSU_CLIENT_SECRET: "FGc9GAtyHzeQDshWP5Ah7dega8hJACAJpQtw6OXk"
|
||||||
|
|
||||||
|
mysql:
|
||||||
|
image: mysql:8.0
|
||||||
|
restart: unless-stopped
|
||||||
|
environment:
|
||||||
|
MYSQL_ROOT_PASSWORD: password
|
||||||
|
MYSQL_DATABASE: osu_api
|
||||||
|
MYSQL_USER: osu_user
|
||||||
|
MYSQL_PASSWORD: osu_password
|
||||||
|
ports:
|
||||||
|
- "3306:3306"
|
||||||
|
volumes:
|
||||||
|
- mysql-data:/var/lib/mysql
|
||||||
|
- ../mysql-init:/docker-entrypoint-initdb.d:cached
|
||||||
|
networks:
|
||||||
|
- devcontainer-network
|
||||||
|
command: --default-authentication-plugin=mysql_native_password
|
||||||
|
|
||||||
|
redis:
|
||||||
|
image: redis:7-alpine
|
||||||
|
restart: unless-stopped
|
||||||
|
ports:
|
||||||
|
- "6379:6379"
|
||||||
|
volumes:
|
||||||
|
- redis-data:/data
|
||||||
|
networks:
|
||||||
|
- devcontainer-network
|
||||||
|
command: redis-server --appendonly yes
|
||||||
|
|
||||||
|
networks:
|
||||||
|
devcontainer-network:
|
||||||
|
driver: bridge
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
mysql-data:
|
||||||
|
redis-data:
|
||||||
28
.editorconfig
Normal file
28
.editorconfig
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
# http://editorconfig.org
|
||||||
|
root = true
|
||||||
|
|
||||||
|
[*]
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 2
|
||||||
|
end_of_line = lf
|
||||||
|
charset = utf-8
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
insert_final_newline = true
|
||||||
|
|
||||||
|
# Makefiles always use tabs for indentation
|
||||||
|
[Makefile]
|
||||||
|
indent_style = tab
|
||||||
|
|
||||||
|
# Batch files use tabs for indentation
|
||||||
|
[*.bat]
|
||||||
|
indent_style = tab
|
||||||
|
|
||||||
|
[*.md]
|
||||||
|
trim_trailing_whitespace = false
|
||||||
|
|
||||||
|
# Matches the exact files either package.json or .travis.yml
|
||||||
|
[{package.json,.travis.yml}]
|
||||||
|
indent_size = 2
|
||||||
|
|
||||||
|
[{*.py,*.pyi}]
|
||||||
|
indent_size = 4
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
# osu! API 客户端配置
|
# osu! API 客户端配置
|
||||||
OSU_CLIENT_ID=5
|
OSU_CLIENT_ID=5
|
||||||
OSU_CLIENT_SECRET=FGc9GAtyHzeQDshWP5Ah7dega8hJACAJpQtw6OXk
|
OSU_CLIENT_SECRET=FGc9GAtyHzeQDshWP5Ah7dega8hJACAJpQtw6OXk
|
||||||
OSU_API_URL=http://localhost:8000
|
OSU_API_URL=http://localhost:8000
|
||||||
|
|||||||
418
.gitignore
vendored
418
.gitignore
vendored
@@ -1,209 +1,209 @@
|
|||||||
# Byte-compiled / optimized / DLL files
|
# Byte-compiled / optimized / DLL files
|
||||||
__pycache__/
|
__pycache__/
|
||||||
*.py[codz]
|
*.py[codz]
|
||||||
*$py.class
|
*$py.class
|
||||||
|
|
||||||
# C extensions
|
# C extensions
|
||||||
*.so
|
*.so
|
||||||
|
|
||||||
# Distribution / packaging
|
# Distribution / packaging
|
||||||
.Python
|
.Python
|
||||||
build/
|
build/
|
||||||
develop-eggs/
|
develop-eggs/
|
||||||
dist/
|
dist/
|
||||||
downloads/
|
downloads/
|
||||||
eggs/
|
eggs/
|
||||||
.eggs/
|
.eggs/
|
||||||
lib/
|
lib/
|
||||||
lib64/
|
lib64/
|
||||||
parts/
|
parts/
|
||||||
sdist/
|
sdist/
|
||||||
var/
|
var/
|
||||||
wheels/
|
wheels/
|
||||||
share/python-wheels/
|
share/python-wheels/
|
||||||
*.egg-info/
|
*.egg-info/
|
||||||
.installed.cfg
|
.installed.cfg
|
||||||
*.egg
|
*.egg
|
||||||
MANIFEST
|
MANIFEST
|
||||||
|
|
||||||
# PyInstaller
|
# PyInstaller
|
||||||
# Usually these files are written by a python script from a template
|
# Usually these files are written by a python script from a template
|
||||||
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||||
*.manifest
|
*.manifest
|
||||||
*.spec
|
*.spec
|
||||||
|
|
||||||
# Installer logs
|
# Installer logs
|
||||||
pip-log.txt
|
pip-log.txt
|
||||||
pip-delete-this-directory.txt
|
pip-delete-this-directory.txt
|
||||||
|
|
||||||
# Unit test / coverage reports
|
# Unit test / coverage reports
|
||||||
htmlcov/
|
htmlcov/
|
||||||
.tox/
|
.tox/
|
||||||
.nox/
|
.nox/
|
||||||
.coverage
|
.coverage
|
||||||
.coverage.*
|
.coverage.*
|
||||||
.cache
|
.cache
|
||||||
nosetests.xml
|
nosetests.xml
|
||||||
coverage.xml
|
coverage.xml
|
||||||
*.cover
|
*.cover
|
||||||
*.py.cover
|
*.py.cover
|
||||||
.hypothesis/
|
.hypothesis/
|
||||||
.pytest_cache/
|
.pytest_cache/
|
||||||
cover/
|
cover/
|
||||||
|
|
||||||
# Translations
|
# Translations
|
||||||
*.mo
|
*.mo
|
||||||
*.pot
|
*.pot
|
||||||
|
|
||||||
# Django stuff:
|
# Django stuff:
|
||||||
*.log
|
*.log
|
||||||
local_settings.py
|
local_settings.py
|
||||||
db.sqlite3
|
db.sqlite3
|
||||||
db.sqlite3-journal
|
db.sqlite3-journal
|
||||||
|
|
||||||
# Flask stuff:
|
# Flask stuff:
|
||||||
instance/
|
instance/
|
||||||
.webassets-cache
|
.webassets-cache
|
||||||
|
|
||||||
# Scrapy stuff:
|
# Scrapy stuff:
|
||||||
.scrapy
|
.scrapy
|
||||||
|
|
||||||
# Sphinx documentation
|
# Sphinx documentation
|
||||||
docs/_build/
|
docs/_build/
|
||||||
|
|
||||||
# PyBuilder
|
# PyBuilder
|
||||||
.pybuilder/
|
.pybuilder/
|
||||||
target/
|
target/
|
||||||
|
|
||||||
# Jupyter Notebook
|
# Jupyter Notebook
|
||||||
.ipynb_checkpoints
|
.ipynb_checkpoints
|
||||||
|
|
||||||
# IPython
|
# IPython
|
||||||
profile_default/
|
profile_default/
|
||||||
ipython_config.py
|
ipython_config.py
|
||||||
|
|
||||||
# pyenv
|
# pyenv
|
||||||
# For a library or package, you might want to ignore these files since the code is
|
# For a library or package, you might want to ignore these files since the code is
|
||||||
# intended to run in multiple environments; otherwise, check them in:
|
# intended to run in multiple environments; otherwise, check them in:
|
||||||
# .python-version
|
# .python-version
|
||||||
|
|
||||||
# pipenv
|
# pipenv
|
||||||
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
||||||
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
||||||
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
||||||
# install all needed dependencies.
|
# install all needed dependencies.
|
||||||
#Pipfile.lock
|
#Pipfile.lock
|
||||||
|
|
||||||
# UV
|
# UV
|
||||||
# Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
|
# Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
|
||||||
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
||||||
# commonly ignored for libraries.
|
# commonly ignored for libraries.
|
||||||
#uv.lock
|
#uv.lock
|
||||||
|
|
||||||
# poetry
|
# poetry
|
||||||
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
||||||
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
||||||
# commonly ignored for libraries.
|
# commonly ignored for libraries.
|
||||||
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
||||||
#poetry.lock
|
#poetry.lock
|
||||||
#poetry.toml
|
#poetry.toml
|
||||||
|
|
||||||
# pdm
|
# pdm
|
||||||
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
||||||
# pdm recommends including project-wide configuration in pdm.toml, but excluding .pdm-python.
|
# pdm recommends including project-wide configuration in pdm.toml, but excluding .pdm-python.
|
||||||
# https://pdm-project.org/en/latest/usage/project/#working-with-version-control
|
# https://pdm-project.org/en/latest/usage/project/#working-with-version-control
|
||||||
#pdm.lock
|
#pdm.lock
|
||||||
#pdm.toml
|
#pdm.toml
|
||||||
.pdm-python
|
.pdm-python
|
||||||
.pdm-build/
|
.pdm-build/
|
||||||
|
|
||||||
# pixi
|
# pixi
|
||||||
# Similar to Pipfile.lock, it is generally recommended to include pixi.lock in version control.
|
# Similar to Pipfile.lock, it is generally recommended to include pixi.lock in version control.
|
||||||
#pixi.lock
|
#pixi.lock
|
||||||
# Pixi creates a virtual environment in the .pixi directory, just like venv module creates one
|
# Pixi creates a virtual environment in the .pixi directory, just like venv module creates one
|
||||||
# in the .venv directory. It is recommended not to include this directory in version control.
|
# in the .venv directory. It is recommended not to include this directory in version control.
|
||||||
.pixi
|
.pixi
|
||||||
|
|
||||||
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
||||||
__pypackages__/
|
__pypackages__/
|
||||||
|
|
||||||
# Celery stuff
|
# Celery stuff
|
||||||
celerybeat-schedule
|
celerybeat-schedule
|
||||||
celerybeat.pid
|
celerybeat.pid
|
||||||
|
|
||||||
# SageMath parsed files
|
# SageMath parsed files
|
||||||
*.sage.py
|
*.sage.py
|
||||||
|
|
||||||
# Environments
|
# Environments
|
||||||
.env
|
.env
|
||||||
.envrc
|
.envrc
|
||||||
.venv
|
.venv
|
||||||
env/
|
env/
|
||||||
venv/
|
venv/
|
||||||
ENV/
|
ENV/
|
||||||
env.bak/
|
env.bak/
|
||||||
venv.bak/
|
venv.bak/
|
||||||
|
|
||||||
# Spyder project settings
|
# Spyder project settings
|
||||||
.spyderproject
|
.spyderproject
|
||||||
.spyproject
|
.spyproject
|
||||||
|
|
||||||
# Rope project settings
|
# Rope project settings
|
||||||
.ropeproject
|
.ropeproject
|
||||||
|
|
||||||
# mkdocs documentation
|
# mkdocs documentation
|
||||||
/site
|
/site
|
||||||
|
|
||||||
# mypy
|
# mypy
|
||||||
.mypy_cache/
|
.mypy_cache/
|
||||||
.dmypy.json
|
.dmypy.json
|
||||||
dmypy.json
|
dmypy.json
|
||||||
|
|
||||||
# Pyre type checker
|
# Pyre type checker
|
||||||
.pyre/
|
.pyre/
|
||||||
|
|
||||||
# pytype static type analyzer
|
# pytype static type analyzer
|
||||||
.pytype/
|
.pytype/
|
||||||
|
|
||||||
# Cython debug symbols
|
# Cython debug symbols
|
||||||
cython_debug/
|
cython_debug/
|
||||||
|
|
||||||
# PyCharm
|
# PyCharm
|
||||||
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
||||||
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
||||||
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
||||||
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
||||||
#.idea/
|
#.idea/
|
||||||
|
|
||||||
# Abstra
|
# Abstra
|
||||||
# Abstra is an AI-powered process automation framework.
|
# Abstra is an AI-powered process automation framework.
|
||||||
# Ignore directories containing user credentials, local state, and settings.
|
# Ignore directories containing user credentials, local state, and settings.
|
||||||
# Learn more at https://abstra.io/docs
|
# Learn more at https://abstra.io/docs
|
||||||
.abstra/
|
.abstra/
|
||||||
|
|
||||||
# Visual Studio Code
|
# Visual Studio Code
|
||||||
# Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore
|
# Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore
|
||||||
# that can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore
|
# that can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore
|
||||||
# and can be added to the global gitignore or merged into this file. However, if you prefer,
|
# and can be added to the global gitignore or merged into this file. However, if you prefer,
|
||||||
# you could uncomment the following to ignore the entire vscode folder
|
# you could uncomment the following to ignore the entire vscode folder
|
||||||
# .vscode/
|
# .vscode/
|
||||||
|
|
||||||
# Ruff stuff:
|
# Ruff stuff:
|
||||||
.ruff_cache/
|
.ruff_cache/
|
||||||
|
|
||||||
# PyPI configuration file
|
# PyPI configuration file
|
||||||
.pypirc
|
.pypirc
|
||||||
|
|
||||||
# Cursor
|
# Cursor
|
||||||
# Cursor is an AI-powered code editor. `.cursorignore` specifies files/directories to
|
# Cursor is an AI-powered code editor. `.cursorignore` specifies files/directories to
|
||||||
# exclude from AI features like autocomplete and code analysis. Recommended for sensitive data
|
# exclude from AI features like autocomplete and code analysis. Recommended for sensitive data
|
||||||
# refer to https://docs.cursor.com/context/ignore-files
|
# refer to https://docs.cursor.com/context/ignore-files
|
||||||
.cursorignore
|
.cursorignore
|
||||||
.cursorindexingignore
|
.cursorindexingignore
|
||||||
|
|
||||||
# Marimo
|
# Marimo
|
||||||
marimo/_static/
|
marimo/_static/
|
||||||
marimo/_lsp/
|
marimo/_lsp/
|
||||||
__marimo__/
|
__marimo__/
|
||||||
bancho.py-master/*
|
bancho.py-master/*
|
||||||
.vscode/settings.json
|
.vscode/settings.json
|
||||||
|
|||||||
6
.idea/.gitignore
generated
vendored
6
.idea/.gitignore
generated
vendored
@@ -1,3 +1,3 @@
|
|||||||
# 默认忽略的文件
|
# 默认忽略的文件
|
||||||
/shelf/
|
/shelf/
|
||||||
/workspace.xml
|
/workspace.xml
|
||||||
|
|||||||
32
.idea/inspectionProfiles/Project_Default.xml
generated
32
.idea/inspectionProfiles/Project_Default.xml
generated
@@ -1,17 +1,17 @@
|
|||||||
<component name="InspectionProjectProfileManager">
|
<component name="InspectionProjectProfileManager">
|
||||||
<profile version="1.0">
|
<profile version="1.0">
|
||||||
<option name="myName" value="Project Default" />
|
<option name="myName" value="Project Default" />
|
||||||
<inspection_tool class="PyCompatibilityInspection" enabled="true" level="WARNING" enabled_by_default="true">
|
<inspection_tool class="PyCompatibilityInspection" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
<option name="ourVersions">
|
<option name="ourVersions">
|
||||||
<value>
|
<value>
|
||||||
<list size="4">
|
<list size="4">
|
||||||
<item index="0" class="java.lang.String" itemvalue="3.7" />
|
<item index="0" class="java.lang.String" itemvalue="3.7" />
|
||||||
<item index="1" class="java.lang.String" itemvalue="3.11" />
|
<item index="1" class="java.lang.String" itemvalue="3.11" />
|
||||||
<item index="2" class="java.lang.String" itemvalue="3.12" />
|
<item index="2" class="java.lang.String" itemvalue="3.12" />
|
||||||
<item index="3" class="java.lang.String" itemvalue="3.13" />
|
<item index="3" class="java.lang.String" itemvalue="3.13" />
|
||||||
</list>
|
</list>
|
||||||
</value>
|
</value>
|
||||||
</option>
|
</option>
|
||||||
</inspection_tool>
|
</inspection_tool>
|
||||||
</profile>
|
</profile>
|
||||||
</component>
|
</component>
|
||||||
10
.idea/inspectionProfiles/profiles_settings.xml
generated
10
.idea/inspectionProfiles/profiles_settings.xml
generated
@@ -1,6 +1,6 @@
|
|||||||
<component name="InspectionProjectProfileManager">
|
<component name="InspectionProjectProfileManager">
|
||||||
<settings>
|
<settings>
|
||||||
<option name="USE_PROJECT_PROFILE" value="false" />
|
<option name="USE_PROJECT_PROFILE" value="false" />
|
||||||
<version value="1.0" />
|
<version value="1.0" />
|
||||||
</settings>
|
</settings>
|
||||||
</component>
|
</component>
|
||||||
18
.idea/misc.xml
generated
18
.idea/misc.xml
generated
@@ -1,10 +1,10 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="Black">
|
<component name="Black">
|
||||||
<option name="sdkName" value="osu_lazer_api" />
|
<option name="sdkName" value="osu_lazer_api" />
|
||||||
</component>
|
</component>
|
||||||
<component name="ProjectRootManager" version="2" project-jdk-name="uv (osu_lazer_api)" project-jdk-type="Python SDK" />
|
<component name="ProjectRootManager" version="2" project-jdk-name="uv (osu_lazer_api)" project-jdk-type="Python SDK" />
|
||||||
<component name="PythonCompatibilityInspectionAdvertiser">
|
<component name="PythonCompatibilityInspectionAdvertiser">
|
||||||
<option name="version" value="3" />
|
<option name="version" value="3" />
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
||||||
14
.idea/modules.xml
generated
14
.idea/modules.xml
generated
@@ -1,8 +1,8 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="ProjectModuleManager">
|
<component name="ProjectModuleManager">
|
||||||
<modules>
|
<modules>
|
||||||
<module fileurl="file://$PROJECT_DIR$/.idea/osu_lazer_api.iml" filepath="$PROJECT_DIR$/.idea/osu_lazer_api.iml" />
|
<module fileurl="file://$PROJECT_DIR$/.idea/osu_lazer_api.iml" filepath="$PROJECT_DIR$/.idea/osu_lazer_api.iml" />
|
||||||
</modules>
|
</modules>
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
||||||
26
.idea/osu_lazer_api.iml
generated
26
.idea/osu_lazer_api.iml
generated
@@ -1,14 +1,14 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<module type="PYTHON_MODULE" version="4">
|
<module type="PYTHON_MODULE" version="4">
|
||||||
<component name="NewModuleRootManager">
|
<component name="NewModuleRootManager">
|
||||||
<content url="file://$MODULE_DIR$">
|
<content url="file://$MODULE_DIR$">
|
||||||
<excludeFolder url="file://$MODULE_DIR$/.venv" />
|
<excludeFolder url="file://$MODULE_DIR$/.venv" />
|
||||||
</content>
|
</content>
|
||||||
<orderEntry type="jdk" jdkName="uv (osu_lazer_api)" jdkType="Python SDK" />
|
<orderEntry type="jdk" jdkName="uv (osu_lazer_api)" jdkType="Python SDK" />
|
||||||
<orderEntry type="sourceFolder" forTests="false" />
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
</component>
|
</component>
|
||||||
<component name="PyDocumentationSettings">
|
<component name="PyDocumentationSettings">
|
||||||
<option name="format" value="PLAIN" />
|
<option name="format" value="PLAIN" />
|
||||||
<option name="myDocStringFormat" value="Plain" />
|
<option name="myDocStringFormat" value="Plain" />
|
||||||
</component>
|
</component>
|
||||||
</module>
|
</module>
|
||||||
10
.idea/vcs.xml
generated
10
.idea/vcs.xml
generated
@@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="VcsDirectoryMappings">
|
<component name="VcsDirectoryMappings">
|
||||||
<mapping directory="" vcs="Git" />
|
<mapping directory="" vcs="Git" />
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
||||||
@@ -1,16 +1,16 @@
|
|||||||
default_install_hook_types: [pre-commit, prepare-commit-msg]
|
default_install_hook_types: [pre-commit, prepare-commit-msg]
|
||||||
ci:
|
ci:
|
||||||
autofix_commit_msg: "chore(deps): auto fix by pre-commit hooks"
|
autofix_commit_msg: "chore(deps): auto fix by pre-commit hooks"
|
||||||
autofix_prs: true
|
autofix_prs: true
|
||||||
autoupdate_branch: master
|
autoupdate_branch: master
|
||||||
autoupdate_schedule: monthly
|
autoupdate_schedule: monthly
|
||||||
autoupdate_commit_msg: "chore(deps): auto update by pre-commit hooks"
|
autoupdate_commit_msg: "chore(deps): auto update by pre-commit hooks"
|
||||||
repos:
|
repos:
|
||||||
- repo: https://github.com/astral-sh/ruff-pre-commit
|
- repo: https://github.com/astral-sh/ruff-pre-commit
|
||||||
rev: v0.12.2
|
rev: v0.12.2
|
||||||
hooks:
|
hooks:
|
||||||
- id: ruff-check
|
- id: ruff-check
|
||||||
args: [--fix]
|
args: [--fix]
|
||||||
stages: [pre-commit]
|
stages: [pre-commit]
|
||||||
- id: ruff-format
|
- id: ruff-format
|
||||||
stages: [pre-commit]
|
stages: [pre-commit]
|
||||||
|
|||||||
25
.vscode/launch.json
vendored
25
.vscode/launch.json
vendored
@@ -1,14 +1,13 @@
|
|||||||
{
|
{
|
||||||
"version": "0.2.0",
|
"version": "0.2.0",
|
||||||
"configurations": [
|
"configurations": [
|
||||||
|
{
|
||||||
{
|
"name": "Server",
|
||||||
"name": "Server",
|
"type": "debugpy",
|
||||||
"type": "debugpy",
|
"request": "launch",
|
||||||
"request": "launch",
|
"program": "main.py",
|
||||||
"program": "main.py",
|
"console": "integratedTerminal",
|
||||||
"console": "integratedTerminal",
|
"justMyCode": true
|
||||||
"justMyCode": true
|
}
|
||||||
}
|
]
|
||||||
]
|
|
||||||
}
|
}
|
||||||
@@ -1,140 +1,140 @@
|
|||||||
# Lazer API 数据同步指南
|
# Lazer API 数据同步指南
|
||||||
|
|
||||||
本指南将帮助您将现有的 bancho.py 数据库数据同步到新的 Lazer API 专用表中。
|
本指南将帮助您将现有的 bancho.py 数据库数据同步到新的 Lazer API 专用表中。
|
||||||
|
|
||||||
## 文件说明
|
## 文件说明
|
||||||
|
|
||||||
1. **`migrations/add_missing_fields.sql`** - 创建 Lazer API 专用表结构
|
1. **`migrations/add_missing_fields.sql`** - 创建 Lazer API 专用表结构
|
||||||
2. **`migrations/sync_legacy_data.sql`** - 数据同步脚本
|
2. **`migrations/sync_legacy_data.sql`** - 数据同步脚本
|
||||||
3. **`sync_data.py`** - 交互式数据同步工具
|
3. **`sync_data.py`** - 交互式数据同步工具
|
||||||
4. **`quick_sync.py`** - 快速同步脚本(使用项目配置)
|
4. **`quick_sync.py`** - 快速同步脚本(使用项目配置)
|
||||||
|
|
||||||
## 使用方法
|
## 使用方法
|
||||||
|
|
||||||
### 方法一:快速同步(推荐)
|
### 方法一:快速同步(推荐)
|
||||||
|
|
||||||
如果您已经配置好了项目的数据库连接,可以直接使用快速同步脚本:
|
如果您已经配置好了项目的数据库连接,可以直接使用快速同步脚本:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
python quick_sync.py
|
python quick_sync.py
|
||||||
```
|
```
|
||||||
|
|
||||||
此脚本会:
|
此脚本会:
|
||||||
1. 自动读取项目配置中的数据库连接信息
|
1. 自动读取项目配置中的数据库连接信息
|
||||||
2. 创建 Lazer API 专用表结构
|
2. 创建 Lazer API 专用表结构
|
||||||
3. 同步现有数据到新表
|
3. 同步现有数据到新表
|
||||||
|
|
||||||
### 方法二:交互式同步
|
### 方法二:交互式同步
|
||||||
|
|
||||||
如果需要使用不同的数据库连接配置:
|
如果需要使用不同的数据库连接配置:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
python sync_data.py
|
python sync_data.py
|
||||||
```
|
```
|
||||||
|
|
||||||
此脚本会:
|
此脚本会:
|
||||||
1. 交互式地询问数据库连接信息
|
1. 交互式地询问数据库连接信息
|
||||||
2. 检查必要表是否存在
|
2. 检查必要表是否存在
|
||||||
3. 显示详细的同步过程和结果
|
3. 显示详细的同步过程和结果
|
||||||
|
|
||||||
### 方法三:手动执行 SQL
|
### 方法三:手动执行 SQL
|
||||||
|
|
||||||
如果您熟悉 SQL 操作,可以手动执行:
|
如果您熟悉 SQL 操作,可以手动执行:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# 1. 创建表结构
|
# 1. 创建表结构
|
||||||
mysql -u username -p database_name < migrations/add_missing_fields.sql
|
mysql -u username -p database_name < migrations/add_missing_fields.sql
|
||||||
|
|
||||||
# 2. 同步数据
|
# 2. 同步数据
|
||||||
mysql -u username -p database_name < migrations/sync_legacy_data.sql
|
mysql -u username -p database_name < migrations/sync_legacy_data.sql
|
||||||
```
|
```
|
||||||
|
|
||||||
## 同步内容
|
## 同步内容
|
||||||
|
|
||||||
### 创建的新表
|
### 创建的新表
|
||||||
|
|
||||||
- `lazer_user_profiles` - 用户扩展资料
|
- `lazer_user_profiles` - 用户扩展资料
|
||||||
- `lazer_user_countries` - 用户国家信息
|
- `lazer_user_countries` - 用户国家信息
|
||||||
- `lazer_user_kudosu` - 用户 Kudosu 统计
|
- `lazer_user_kudosu` - 用户 Kudosu 统计
|
||||||
- `lazer_user_counts` - 用户各项计数统计
|
- `lazer_user_counts` - 用户各项计数统计
|
||||||
- `lazer_user_statistics` - 用户游戏统计(按模式)
|
- `lazer_user_statistics` - 用户游戏统计(按模式)
|
||||||
- `lazer_user_achievements` - 用户成就
|
- `lazer_user_achievements` - 用户成就
|
||||||
- `lazer_oauth_tokens` - OAuth 访问令牌
|
- `lazer_oauth_tokens` - OAuth 访问令牌
|
||||||
- 其他相关表...
|
- 其他相关表...
|
||||||
|
|
||||||
### 同步的数据
|
### 同步的数据
|
||||||
|
|
||||||
1. **用户基本信息**
|
1. **用户基本信息**
|
||||||
- 从 `users` 表同步基本资料
|
- 从 `users` 表同步基本资料
|
||||||
- 自动转换时间戳格式
|
- 自动转换时间戳格式
|
||||||
- 设置合理的默认值
|
- 设置合理的默认值
|
||||||
|
|
||||||
2. **游戏统计**
|
2. **游戏统计**
|
||||||
- 从 `stats` 表同步各模式的游戏数据
|
- 从 `stats` 表同步各模式的游戏数据
|
||||||
- 计算命中精度和其他衍生统计
|
- 计算命中精度和其他衍生统计
|
||||||
|
|
||||||
3. **用户成就**
|
3. **用户成就**
|
||||||
- 从 `user_achievements` 表同步成就数据(如果存在)
|
- 从 `user_achievements` 表同步成就数据(如果存在)
|
||||||
|
|
||||||
## 注意事项
|
## 注意事项
|
||||||
|
|
||||||
1. **安全性**
|
1. **安全性**
|
||||||
- 脚本只会创建新表和插入数据
|
- 脚本只会创建新表和插入数据
|
||||||
- 不会修改或删除现有的原始表数据
|
- 不会修改或删除现有的原始表数据
|
||||||
- 使用 `ON DUPLICATE KEY UPDATE` 避免重复插入
|
- 使用 `ON DUPLICATE KEY UPDATE` 避免重复插入
|
||||||
|
|
||||||
2. **兼容性**
|
2. **兼容性**
|
||||||
- 兼容现有的 bancho.py 数据库结构
|
- 兼容现有的 bancho.py 数据库结构
|
||||||
- 支持标准的 osu! 数据格式
|
- 支持标准的 osu! 数据格式
|
||||||
|
|
||||||
3. **性能**
|
3. **性能**
|
||||||
- 大量数据可能需要较长时间
|
- 大量数据可能需要较长时间
|
||||||
- 建议在维护窗口期间执行
|
- 建议在维护窗口期间执行
|
||||||
|
|
||||||
## 故障排除
|
## 故障排除
|
||||||
|
|
||||||
### 常见错误
|
### 常见错误
|
||||||
|
|
||||||
1. **"Unknown column" 错误**
|
1. **"Unknown column" 错误**
|
||||||
```
|
```
|
||||||
ERROR 1054: Unknown column 'users.is_active' in 'field list'
|
ERROR 1054: Unknown column 'users.is_active' in 'field list'
|
||||||
```
|
```
|
||||||
**解决方案**: 确保先执行了 `add_missing_fields.sql` 创建表结构
|
**解决方案**: 确保先执行了 `add_missing_fields.sql` 创建表结构
|
||||||
|
|
||||||
2. **"Table doesn't exist" 错误**
|
2. **"Table doesn't exist" 错误**
|
||||||
```
|
```
|
||||||
ERROR 1146: Table 'database.users' doesn't exist
|
ERROR 1146: Table 'database.users' doesn't exist
|
||||||
```
|
```
|
||||||
**解决方案**: 确认数据库中存在 bancho.py 的原始表
|
**解决方案**: 确认数据库中存在 bancho.py 的原始表
|
||||||
|
|
||||||
3. **连接错误**
|
3. **连接错误**
|
||||||
```
|
```
|
||||||
ERROR 2003: Can't connect to MySQL server
|
ERROR 2003: Can't connect to MySQL server
|
||||||
```
|
```
|
||||||
**解决方案**: 检查数据库连接配置和权限
|
**解决方案**: 检查数据库连接配置和权限
|
||||||
|
|
||||||
### 验证同步结果
|
### 验证同步结果
|
||||||
|
|
||||||
同步完成后,可以执行以下查询验证结果:
|
同步完成后,可以执行以下查询验证结果:
|
||||||
|
|
||||||
```sql
|
```sql
|
||||||
-- 检查同步的用户数量
|
-- 检查同步的用户数量
|
||||||
SELECT COUNT(*) FROM lazer_user_profiles;
|
SELECT COUNT(*) FROM lazer_user_profiles;
|
||||||
|
|
||||||
-- 查看样本数据
|
-- 查看样本数据
|
||||||
SELECT
|
SELECT
|
||||||
u.id, u.name,
|
u.id, u.name,
|
||||||
lup.playmode, lup.is_supporter,
|
lup.playmode, lup.is_supporter,
|
||||||
lus.pp, lus.play_count
|
lus.pp, lus.play_count
|
||||||
FROM users u
|
FROM users u
|
||||||
LEFT JOIN lazer_user_profiles lup ON u.id = lup.user_id
|
LEFT JOIN lazer_user_profiles lup ON u.id = lup.user_id
|
||||||
LEFT JOIN lazer_user_statistics lus ON u.id = lus.user_id AND lus.mode = 'osu'
|
LEFT JOIN lazer_user_statistics lus ON u.id = lus.user_id AND lus.mode = 'osu'
|
||||||
LIMIT 5;
|
LIMIT 5;
|
||||||
```
|
```
|
||||||
|
|
||||||
## 支持
|
## 支持
|
||||||
|
|
||||||
如果遇到问题,请:
|
如果遇到问题,请:
|
||||||
1. 检查日志文件 `data_sync.log`
|
1. 检查日志文件 `data_sync.log`
|
||||||
2. 确认数据库权限
|
2. 确认数据库权限
|
||||||
3. 验证原始表数据完整性
|
3. 验证原始表数据完整性
|
||||||
|
|||||||
56
Dockerfile
56
Dockerfile
@@ -1,28 +1,28 @@
|
|||||||
FROM ghcr.io/astral-sh/uv:python3.12-bookworm-slim
|
FROM ghcr.io/astral-sh/uv:python3.12-bookworm-slim
|
||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
ENV UV_PROJECT_ENVIRONMENT=syncvenv
|
ENV UV_PROJECT_ENVIRONMENT=syncvenv
|
||||||
|
|
||||||
# 安装系统依赖
|
# 安装系统依赖
|
||||||
RUN apt-get update && apt-get install -y \
|
RUN apt-get update && apt-get install -y \
|
||||||
gcc \
|
gcc \
|
||||||
pkg-config \
|
pkg-config \
|
||||||
default-libmysqlclient-dev \
|
default-libmysqlclient-dev \
|
||||||
&& rm -rf /var/lib/apt/lists/*
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
# 复制依赖文件
|
# 复制依赖文件
|
||||||
COPY uv.lock .
|
COPY uv.lock .
|
||||||
COPY pyproject.toml .
|
COPY pyproject.toml .
|
||||||
COPY requirements.txt .
|
COPY requirements.txt .
|
||||||
|
|
||||||
# 安装Python依赖
|
# 安装Python依赖
|
||||||
RUN pip install -r requirements.txt
|
RUN pip install -r requirements.txt
|
||||||
|
|
||||||
# 复制应用代码
|
# 复制应用代码
|
||||||
COPY . .
|
COPY . .
|
||||||
|
|
||||||
# 暴露端口
|
# 暴露端口
|
||||||
EXPOSE 8000
|
EXPOSE 8000
|
||||||
|
|
||||||
# 启动命令
|
# 启动命令
|
||||||
CMD ["uv", "run", "uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
|
CMD ["uv", "run", "uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
|
||||||
|
|||||||
428
README.md
428
README.md
@@ -1,214 +1,214 @@
|
|||||||
# osu! API 模拟服务器
|
# osu! API 模拟服务器
|
||||||
|
|
||||||
这是一个使用 FastAPI + MySQL + Redis 实现的 osu! API 模拟服务器,提供了完整的用户认证和数据管理功能。
|
这是一个使用 FastAPI + MySQL + Redis 实现的 osu! API 模拟服务器,提供了完整的用户认证和数据管理功能。
|
||||||
|
|
||||||
## 功能特性
|
## 功能特性
|
||||||
|
|
||||||
- **OAuth 2.0 认证**: 支持密码流和刷新令牌流
|
- **OAuth 2.0 认证**: 支持密码流和刷新令牌流
|
||||||
- **用户数据管理**: 完整的用户信息、统计数据、成就等
|
- **用户数据管理**: 完整的用户信息、统计数据、成就等
|
||||||
- **多游戏模式支持**: osu!, taiko, fruits, mania
|
- **多游戏模式支持**: osu!, taiko, fruits, mania
|
||||||
- **数据库持久化**: MySQL 存储用户数据
|
- **数据库持久化**: MySQL 存储用户数据
|
||||||
- **缓存支持**: Redis 缓存令牌和会话信息
|
- **缓存支持**: Redis 缓存令牌和会话信息
|
||||||
- **容器化部署**: Docker 和 Docker Compose 支持
|
- **容器化部署**: Docker 和 Docker Compose 支持
|
||||||
|
|
||||||
## API 端点
|
## API 端点
|
||||||
|
|
||||||
### 认证端点
|
### 认证端点
|
||||||
- `POST /oauth/token` - OAuth 令牌获取/刷新
|
- `POST /oauth/token` - OAuth 令牌获取/刷新
|
||||||
|
|
||||||
### 用户端点
|
### 用户端点
|
||||||
- `GET /api/v2/me/{ruleset}` - 获取当前用户信息
|
- `GET /api/v2/me/{ruleset}` - 获取当前用户信息
|
||||||
|
|
||||||
### 其他端点
|
### 其他端点
|
||||||
- `GET /` - 根端点
|
- `GET /` - 根端点
|
||||||
- `GET /health` - 健康检查
|
- `GET /health` - 健康检查
|
||||||
|
|
||||||
## 快速开始
|
## 快速开始
|
||||||
|
|
||||||
### 使用 Docker Compose (推荐)
|
### 使用 Docker Compose (推荐)
|
||||||
|
|
||||||
1. 克隆项目
|
1. 克隆项目
|
||||||
```bash
|
```bash
|
||||||
git clone <repository-url>
|
git clone <repository-url>
|
||||||
cd osu_lazer_api
|
cd osu_lazer_api
|
||||||
```
|
```
|
||||||
|
|
||||||
2. 启动服务
|
2. 启动服务
|
||||||
```bash
|
```bash
|
||||||
docker-compose up -d
|
docker-compose up -d
|
||||||
```
|
```
|
||||||
|
|
||||||
3. 创建示例数据
|
3. 创建示例数据
|
||||||
```bash
|
```bash
|
||||||
docker-compose exec api python create_sample_data.py
|
docker-compose exec api python create_sample_data.py
|
||||||
```
|
```
|
||||||
|
|
||||||
4. 测试 API
|
4. 测试 API
|
||||||
```bash
|
```bash
|
||||||
# 获取访问令牌
|
# 获取访问令牌
|
||||||
curl -X POST http://localhost:8000/oauth/token \
|
curl -X POST http://localhost:8000/oauth/token \
|
||||||
-H "Content-Type: application/x-www-form-urlencoded" \
|
-H "Content-Type: application/x-www-form-urlencoded" \
|
||||||
-d "grant_type=password&username=Googujiang&password=password123&client_id=5&client_secret=FGc9GAtyHzeQDshWP5Ah7dega8hJACAJpQtw6OXk&scope=*"
|
-d "grant_type=password&username=Googujiang&password=password123&client_id=5&client_secret=FGc9GAtyHzeQDshWP5Ah7dega8hJACAJpQtw6OXk&scope=*"
|
||||||
|
|
||||||
# 使用令牌获取用户信息
|
# 使用令牌获取用户信息
|
||||||
curl -X GET http://localhost:8000/api/v2/me/osu \
|
curl -X GET http://localhost:8000/api/v2/me/osu \
|
||||||
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
|
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
|
||||||
```
|
```
|
||||||
|
|
||||||
### 本地开发
|
### 本地开发
|
||||||
|
|
||||||
1. 安装依赖
|
1. 安装依赖
|
||||||
```bash
|
```bash
|
||||||
pip install -r requirements.txt
|
pip install -r requirements.txt
|
||||||
```
|
```
|
||||||
|
|
||||||
2. 配置环境变量
|
2. 配置环境变量
|
||||||
```bash
|
```bash
|
||||||
# 复制服务器配置文件
|
# 复制服务器配置文件
|
||||||
cp .env .env.local
|
cp .env .env.local
|
||||||
|
|
||||||
# 复制客户端配置文件(用于测试脚本)
|
# 复制客户端配置文件(用于测试脚本)
|
||||||
cp .env.client .env.client.local
|
cp .env.client .env.client.local
|
||||||
```
|
```
|
||||||
|
|
||||||
3. 启动 MySQL 和 Redis
|
3. 启动 MySQL 和 Redis
|
||||||
```bash
|
```bash
|
||||||
# 使用 Docker
|
# 使用 Docker
|
||||||
docker run -d --name mysql -e MYSQL_ROOT_PASSWORD=password -e MYSQL_DATABASE=osu_api -p 3306:3306 mysql:8.0
|
docker run -d --name mysql -e MYSQL_ROOT_PASSWORD=password -e MYSQL_DATABASE=osu_api -p 3306:3306 mysql:8.0
|
||||||
docker run -d --name redis -p 6379:6379 redis:7-alpine
|
docker run -d --name redis -p 6379:6379 redis:7-alpine
|
||||||
```
|
```
|
||||||
|
|
||||||
4. 创建示例数据
|
4. 创建示例数据
|
||||||
```bash
|
```bash
|
||||||
python create_sample_data.py
|
python create_sample_data.py
|
||||||
```
|
```
|
||||||
|
|
||||||
5. 启动应用
|
5. 启动应用
|
||||||
```bash
|
```bash
|
||||||
uvicorn main:app --reload
|
uvicorn main:app --reload
|
||||||
```
|
```
|
||||||
|
|
||||||
6. 测试 API
|
6. 测试 API
|
||||||
```bash
|
```bash
|
||||||
# 使用测试脚本(会自动加载 .env 文件)
|
# 使用测试脚本(会自动加载 .env 文件)
|
||||||
python test_api.py
|
python test_api.py
|
||||||
|
|
||||||
# 或使用原始示例脚本
|
# 或使用原始示例脚本
|
||||||
python osu_api_example.py
|
python osu_api_example.py
|
||||||
```
|
```
|
||||||
|
|
||||||
## 项目结构
|
## 项目结构
|
||||||
|
|
||||||
```
|
```
|
||||||
osu_lazer_api/
|
osu_lazer_api/
|
||||||
├── app/
|
├── app/
|
||||||
│ ├── __init__.py
|
│ ├── __init__.py
|
||||||
│ ├── models.py # Pydantic 数据模型
|
│ ├── models.py # Pydantic 数据模型
|
||||||
│ ├── database.py # SQLAlchemy 数据库模型
|
│ ├── database.py # SQLAlchemy 数据库模型
|
||||||
│ ├── config.py # 配置设置
|
│ ├── config.py # 配置设置
|
||||||
│ ├── dependencies.py # 依赖注入
|
│ ├── dependencies.py # 依赖注入
|
||||||
│ ├── auth.py # 认证和令牌管理
|
│ ├── auth.py # 认证和令牌管理
|
||||||
│ └── utils.py # 工具函数
|
│ └── utils.py # 工具函数
|
||||||
├── main.py # FastAPI 应用主文件
|
├── main.py # FastAPI 应用主文件
|
||||||
├── create_sample_data.py # 示例数据创建脚本
|
├── create_sample_data.py # 示例数据创建脚本
|
||||||
├── requirements.txt # Python 依赖
|
├── requirements.txt # Python 依赖
|
||||||
├── .env # 环境变量配置
|
├── .env # 环境变量配置
|
||||||
├── docker-compose.yml # Docker Compose 配置
|
├── docker-compose.yml # Docker Compose 配置
|
||||||
├── Dockerfile # Docker 镜像配置
|
├── Dockerfile # Docker 镜像配置
|
||||||
└── README.md # 项目说明
|
└── README.md # 项目说明
|
||||||
```
|
```
|
||||||
|
|
||||||
## 示例用户
|
## 示例用户
|
||||||
|
|
||||||
创建示例数据后,您可以使用以下凭据进行测试:
|
创建示例数据后,您可以使用以下凭据进行测试:
|
||||||
|
|
||||||
- **用户名**: `Googujiang`
|
- **用户名**: `Googujiang`
|
||||||
- **密码**: `password123`
|
- **密码**: `password123`
|
||||||
- **用户ID**: `15651670`
|
- **用户ID**: `15651670`
|
||||||
|
|
||||||
## 环境变量配置
|
## 环境变量配置
|
||||||
|
|
||||||
项目包含两个环境配置文件:
|
项目包含两个环境配置文件:
|
||||||
|
|
||||||
### 服务器配置 (`.env`)
|
### 服务器配置 (`.env`)
|
||||||
用于配置 FastAPI 服务器的运行参数:
|
用于配置 FastAPI 服务器的运行参数:
|
||||||
|
|
||||||
| 变量名 | 描述 | 默认值 |
|
| 变量名 | 描述 | 默认值 |
|
||||||
|--------|------|--------|
|
|--------|------|--------|
|
||||||
| `DATABASE_URL` | MySQL 数据库连接字符串 | `mysql+pymysql://root:password@localhost:3306/osu_api` |
|
| `DATABASE_URL` | MySQL 数据库连接字符串 | `mysql+pymysql://root:password@localhost:3306/osu_api` |
|
||||||
| `REDIS_URL` | Redis 连接字符串 | `redis://localhost:6379/0` |
|
| `REDIS_URL` | Redis 连接字符串 | `redis://localhost:6379/0` |
|
||||||
| `SECRET_KEY` | JWT 签名密钥 | `your-secret-key-here` |
|
| `SECRET_KEY` | JWT 签名密钥 | `your-secret-key-here` |
|
||||||
| `ACCESS_TOKEN_EXPIRE_MINUTES` | 访问令牌过期时间(分钟) | `1440` |
|
| `ACCESS_TOKEN_EXPIRE_MINUTES` | 访问令牌过期时间(分钟) | `1440` |
|
||||||
| `OSU_CLIENT_ID` | OAuth 客户端 ID | `5` |
|
| `OSU_CLIENT_ID` | OAuth 客户端 ID | `5` |
|
||||||
| `OSU_CLIENT_SECRET` | OAuth 客户端密钥 | `FGc9GAtyHzeQDshWP5Ah7dega8hJACAJpQtw6OXk` |
|
| `OSU_CLIENT_SECRET` | OAuth 客户端密钥 | `FGc9GAtyHzeQDshWP5Ah7dega8hJACAJpQtw6OXk` |
|
||||||
| `HOST` | 服务器监听地址 | `0.0.0.0` |
|
| `HOST` | 服务器监听地址 | `0.0.0.0` |
|
||||||
| `PORT` | 服务器监听端口 | `8000` |
|
| `PORT` | 服务器监听端口 | `8000` |
|
||||||
| `DEBUG` | 调试模式 | `True` |
|
| `DEBUG` | 调试模式 | `True` |
|
||||||
|
|
||||||
### 客户端配置 (`.env.client`)
|
### 客户端配置 (`.env.client`)
|
||||||
用于配置客户端脚本的 API 连接参数:
|
用于配置客户端脚本的 API 连接参数:
|
||||||
|
|
||||||
| 变量名 | 描述 | 默认值 |
|
| 变量名 | 描述 | 默认值 |
|
||||||
|--------|------|--------|
|
|--------|------|--------|
|
||||||
| `OSU_CLIENT_ID` | OAuth 客户端 ID | `5` |
|
| `OSU_CLIENT_ID` | OAuth 客户端 ID | `5` |
|
||||||
| `OSU_CLIENT_SECRET` | OAuth 客户端密钥 | `FGc9GAtyHzeQDshWP5Ah7dega8hJACAJpQtw6OXk` |
|
| `OSU_CLIENT_SECRET` | OAuth 客户端密钥 | `FGc9GAtyHzeQDshWP5Ah7dega8hJACAJpQtw6OXk` |
|
||||||
| `OSU_API_URL` | API 服务器地址 | `http://localhost:8000` |
|
| `OSU_API_URL` | API 服务器地址 | `http://localhost:8000` |
|
||||||
|
|
||||||
> **注意**: 在生产环境中,请务必更改默认的密钥和密码!
|
> **注意**: 在生产环境中,请务必更改默认的密钥和密码!
|
||||||
|
|
||||||
## API 使用示例
|
## API 使用示例
|
||||||
|
|
||||||
### 获取访问令牌
|
### 获取访问令牌
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
curl -X POST http://localhost:8000/oauth/token \
|
curl -X POST http://localhost:8000/oauth/token \
|
||||||
-H "Content-Type: application/x-www-form-urlencoded" \
|
-H "Content-Type: application/x-www-form-urlencoded" \
|
||||||
-d "grant_type=password&username=Googujiang&password=password123&client_id=5&client_secret=FGc9GAtyHzeQDshWP5Ah7dega8hJACAJpQtw6OXk&scope=*"
|
-d "grant_type=password&username=Googujiang&password=password123&client_id=5&client_secret=FGc9GAtyHzeQDshWP5Ah7dega8hJACAJpQtw6OXk&scope=*"
|
||||||
```
|
```
|
||||||
|
|
||||||
响应:
|
响应:
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...",
|
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...",
|
||||||
"token_type": "Bearer",
|
"token_type": "Bearer",
|
||||||
"expires_in": 86400,
|
"expires_in": 86400,
|
||||||
"refresh_token": "abc123...",
|
"refresh_token": "abc123...",
|
||||||
"scope": "*"
|
"scope": "*"
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### 获取用户信息
|
### 获取用户信息
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
curl -X GET http://localhost:8000/api/v2/me/osu \
|
curl -X GET http://localhost:8000/api/v2/me/osu \
|
||||||
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
|
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
|
||||||
```
|
```
|
||||||
|
|
||||||
### 刷新令牌
|
### 刷新令牌
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
curl -X POST http://localhost:8000/oauth/token \
|
curl -X POST http://localhost:8000/oauth/token \
|
||||||
-H "Content-Type: application/x-www-form-urlencoded" \
|
-H "Content-Type: application/x-www-form-urlencoded" \
|
||||||
-d "grant_type=refresh_token&refresh_token=YOUR_REFRESH_TOKEN&client_id=5&client_secret=FGc9GAtyHzeQDshWP5Ah7dega8hJACAJpQtw6OXk"
|
-d "grant_type=refresh_token&refresh_token=YOUR_REFRESH_TOKEN&client_id=5&client_secret=FGc9GAtyHzeQDshWP5Ah7dega8hJACAJpQtw6OXk"
|
||||||
```
|
```
|
||||||
|
|
||||||
## 开发
|
## 开发
|
||||||
|
|
||||||
### 添加新用户
|
### 添加新用户
|
||||||
|
|
||||||
您可以通过修改 `create_sample_data.py` 文件来添加更多示例用户,或者扩展 API 来支持用户注册功能。
|
您可以通过修改 `create_sample_data.py` 文件来添加更多示例用户,或者扩展 API 来支持用户注册功能。
|
||||||
|
|
||||||
### 扩展功能
|
### 扩展功能
|
||||||
|
|
||||||
- 添加更多 API 端点(排行榜、谱面信息等)
|
- 添加更多 API 端点(排行榜、谱面信息等)
|
||||||
- 实现实时功能(WebSocket)
|
- 实现实时功能(WebSocket)
|
||||||
- 添加管理面板
|
- 添加管理面板
|
||||||
- 实现数据导入/导出功能
|
- 实现数据导入/导出功能
|
||||||
|
|
||||||
## 许可证
|
## 许可证
|
||||||
|
|
||||||
MIT License
|
MIT License
|
||||||
|
|
||||||
## 贡献
|
## 贡献
|
||||||
|
|
||||||
欢迎提交 Issue 和 Pull Request!
|
欢迎提交 Issue 和 Pull Request!
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from .router import router as signalr_router
|
from .router import router as signalr_router
|
||||||
|
|
||||||
|
__all__ = ["signalr_router"]
|
||||||
|
|||||||
@@ -127,7 +127,7 @@ class Hub:
|
|||||||
args: list[Any] | None = packet[3]
|
args: list[Any] | None = packet[3]
|
||||||
if args is None:
|
if args is None:
|
||||||
args = []
|
args = []
|
||||||
streams: list[str] | None = packet[4] # TODO: stream support
|
# streams: list[str] | None = packet[4] # TODO: stream support
|
||||||
code = ResultKind.VOID
|
code = ResultKind.VOID
|
||||||
result = None
|
result = None
|
||||||
try:
|
try:
|
||||||
|
|||||||
@@ -1,50 +1,50 @@
|
|||||||
version: '3.8'
|
version: '3.8'
|
||||||
|
|
||||||
services:
|
services:
|
||||||
mysql:
|
mysql:
|
||||||
image: mysql:8.0
|
image: mysql:8.0
|
||||||
container_name: osu_api_mysql
|
container_name: osu_api_mysql
|
||||||
environment:
|
environment:
|
||||||
MYSQL_ROOT_PASSWORD: password
|
MYSQL_ROOT_PASSWORD: password
|
||||||
MYSQL_DATABASE: osu_api
|
MYSQL_DATABASE: osu_api
|
||||||
MYSQL_USER: osu_user
|
MYSQL_USER: osu_user
|
||||||
MYSQL_PASSWORD: osu_password
|
MYSQL_PASSWORD: osu_password
|
||||||
ports:
|
ports:
|
||||||
- "3306:3306"
|
- "3306:3306"
|
||||||
volumes:
|
volumes:
|
||||||
- mysql_data:/var/lib/mysql
|
- mysql_data:/var/lib/mysql
|
||||||
- ./mysql-init:/docker-entrypoint-initdb.d
|
- ./mysql-init:/docker-entrypoint-initdb.d
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
|
||||||
redis:
|
redis:
|
||||||
image: redis:7-alpine
|
image: redis:7-alpine
|
||||||
container_name: osu_api_redis
|
container_name: osu_api_redis
|
||||||
ports:
|
ports:
|
||||||
- "6379:6379"
|
- "6379:6379"
|
||||||
volumes:
|
volumes:
|
||||||
- redis_data:/data
|
- redis_data:/data
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
command: redis-server --appendonly yes
|
command: redis-server --appendonly yes
|
||||||
|
|
||||||
api:
|
api:
|
||||||
build: .
|
build: .
|
||||||
container_name: osu_api_server
|
container_name: osu_api_server
|
||||||
ports:
|
ports:
|
||||||
- "8000:8000"
|
- "8000:8000"
|
||||||
environment:
|
environment:
|
||||||
DATABASE_URL: mysql+aiomysql://osu_user:osu_password@mysql:3306/osu_api
|
DATABASE_URL: mysql+aiomysql://osu_user:osu_password@mysql:3306/osu_api
|
||||||
REDIS_URL: redis://redis:6379/0
|
REDIS_URL: redis://redis:6379/0
|
||||||
SECRET_KEY: your-production-secret-key-here
|
SECRET_KEY: your-production-secret-key-here
|
||||||
OSU_CLIENT_ID: "5"
|
OSU_CLIENT_ID: "5"
|
||||||
OSU_CLIENT_SECRET: "FGc9GAtyHzeQDshWP5Ah7dega8hJACAJpQtw6OXk"
|
OSU_CLIENT_SECRET: "FGc9GAtyHzeQDshWP5Ah7dega8hJACAJpQtw6OXk"
|
||||||
depends_on:
|
depends_on:
|
||||||
- mysql
|
- mysql
|
||||||
- redis
|
- redis
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
volumes:
|
volumes:
|
||||||
- ./:/app
|
- ./:/app
|
||||||
command: uvicorn main:app --host 0.0.0.0 --port 8000 --reload
|
command: uvicorn main:app --host 0.0.0.0 --port 8000 --reload
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
mysql_data:
|
mysql_data:
|
||||||
redis_data:
|
redis_data:
|
||||||
|
|||||||
@@ -1,16 +1,16 @@
|
|||||||
-- 创建迁移日志表(如果不存在)
|
-- 创建迁移日志表(如果不存在)
|
||||||
CREATE TABLE IF NOT EXISTS `migration_logs` (
|
CREATE TABLE IF NOT EXISTS `migration_logs` (
|
||||||
`id` INT AUTO_INCREMENT PRIMARY KEY,
|
`id` INT AUTO_INCREMENT PRIMARY KEY,
|
||||||
`version` VARCHAR(50) NOT NULL,
|
`version` VARCHAR(50) NOT NULL,
|
||||||
`description` VARCHAR(255) NOT NULL,
|
`description` VARCHAR(255) NOT NULL,
|
||||||
`timestamp` DATETIME NOT NULL
|
`timestamp` DATETIME NOT NULL
|
||||||
);
|
);
|
||||||
|
|
||||||
-- 向 lazer_user_statistics 表添加缺失的字段
|
-- 向 lazer_user_statistics 表添加缺失的字段
|
||||||
ALTER TABLE `lazer_user_statistics`
|
ALTER TABLE `lazer_user_statistics`
|
||||||
ADD COLUMN IF NOT EXISTS `rank_highest` INT NULL COMMENT '最高排名' AFTER `grade_a`,
|
ADD COLUMN IF NOT EXISTS `rank_highest` INT NULL COMMENT '最高排名' AFTER `grade_a`,
|
||||||
ADD COLUMN IF NOT EXISTS `rank_highest_updated_at` DATETIME NULL COMMENT '最高排名更新时间' AFTER `rank_highest`;
|
ADD COLUMN IF NOT EXISTS `rank_highest_updated_at` DATETIME NULL COMMENT '最高排名更新时间' AFTER `rank_highest`;
|
||||||
|
|
||||||
-- 更新日志
|
-- 更新日志
|
||||||
INSERT INTO `migration_logs` (`version`, `description`, `timestamp`)
|
INSERT INTO `migration_logs` (`version`, `description`, `timestamp`)
|
||||||
VALUES ('20250719', '向 lazer_user_statistics 表添加缺失的字段', NOW());
|
VALUES ('20250719', '向 lazer_user_statistics 表添加缺失的字段', NOW());
|
||||||
|
|||||||
@@ -1,421 +1,421 @@
|
|||||||
-- Lazer API 专用数据表创建脚本
|
-- Lazer API 专用数据表创建脚本
|
||||||
-- 基于真实 osu! API 返回数据设计的表结构
|
-- 基于真实 osu! API 返回数据设计的表结构
|
||||||
-- 完全不修改 bancho.py 原有表结构,创建全新的 lazer 专用表
|
-- 完全不修改 bancho.py 原有表结构,创建全新的 lazer 专用表
|
||||||
|
|
||||||
-- ============================================
|
-- ============================================
|
||||||
-- Lazer API 专用扩展表
|
-- Lazer API 专用扩展表
|
||||||
-- ============================================
|
-- ============================================
|
||||||
|
|
||||||
-- Lazer 用户扩展信息表
|
-- Lazer 用户扩展信息表
|
||||||
CREATE TABLE IF NOT EXISTS lazer_user_profiles (
|
CREATE TABLE IF NOT EXISTS lazer_user_profiles (
|
||||||
user_id INT PRIMARY KEY COMMENT '关联 users.id',
|
user_id INT PRIMARY KEY COMMENT '关联 users.id',
|
||||||
|
|
||||||
-- 基本状态字段
|
-- 基本状态字段
|
||||||
is_active TINYINT(1) DEFAULT 1 COMMENT '用户是否激活',
|
is_active TINYINT(1) DEFAULT 1 COMMENT '用户是否激活',
|
||||||
is_bot TINYINT(1) DEFAULT 0 COMMENT '是否为机器人账户',
|
is_bot TINYINT(1) DEFAULT 0 COMMENT '是否为机器人账户',
|
||||||
is_deleted TINYINT(1) DEFAULT 0 COMMENT '是否已删除',
|
is_deleted TINYINT(1) DEFAULT 0 COMMENT '是否已删除',
|
||||||
is_online TINYINT(1) DEFAULT 1 COMMENT '是否在线',
|
is_online TINYINT(1) DEFAULT 1 COMMENT '是否在线',
|
||||||
is_supporter TINYINT(1) DEFAULT 0 COMMENT '是否为支持者',
|
is_supporter TINYINT(1) DEFAULT 0 COMMENT '是否为支持者',
|
||||||
is_restricted TINYINT(1) DEFAULT 0 COMMENT '是否被限制',
|
is_restricted TINYINT(1) DEFAULT 0 COMMENT '是否被限制',
|
||||||
session_verified TINYINT(1) DEFAULT 0 COMMENT '会话是否已验证',
|
session_verified TINYINT(1) DEFAULT 0 COMMENT '会话是否已验证',
|
||||||
has_supported TINYINT(1) DEFAULT 0 COMMENT '是否曾经支持过',
|
has_supported TINYINT(1) DEFAULT 0 COMMENT '是否曾经支持过',
|
||||||
pm_friends_only TINYINT(1) DEFAULT 0 COMMENT '是否只接受好友私信',
|
pm_friends_only TINYINT(1) DEFAULT 0 COMMENT '是否只接受好友私信',
|
||||||
|
|
||||||
-- 基本资料字段
|
-- 基本资料字段
|
||||||
default_group VARCHAR(50) DEFAULT 'default' COMMENT '默认用户组',
|
default_group VARCHAR(50) DEFAULT 'default' COMMENT '默认用户组',
|
||||||
last_visit DATETIME NULL COMMENT '最后访问时间',
|
last_visit DATETIME NULL COMMENT '最后访问时间',
|
||||||
join_date DATETIME NULL COMMENT '加入日期',
|
join_date DATETIME NULL COMMENT '加入日期',
|
||||||
profile_colour VARCHAR(7) NULL COMMENT '个人资料颜色',
|
profile_colour VARCHAR(7) NULL COMMENT '个人资料颜色',
|
||||||
profile_hue INT NULL COMMENT '个人资料色调',
|
profile_hue INT NULL COMMENT '个人资料色调',
|
||||||
|
|
||||||
-- 社交媒体和个人资料字段
|
-- 社交媒体和个人资料字段
|
||||||
avatar_url VARCHAR(500) NULL COMMENT '头像URL',
|
avatar_url VARCHAR(500) NULL COMMENT '头像URL',
|
||||||
cover_url VARCHAR(500) NULL COMMENT '封面URL',
|
cover_url VARCHAR(500) NULL COMMENT '封面URL',
|
||||||
discord VARCHAR(100) NULL COMMENT 'Discord用户名',
|
discord VARCHAR(100) NULL COMMENT 'Discord用户名',
|
||||||
twitter VARCHAR(100) NULL COMMENT 'Twitter用户名',
|
twitter VARCHAR(100) NULL COMMENT 'Twitter用户名',
|
||||||
website VARCHAR(500) NULL COMMENT '个人网站',
|
website VARCHAR(500) NULL COMMENT '个人网站',
|
||||||
title VARCHAR(100) NULL COMMENT '用户称号',
|
title VARCHAR(100) NULL COMMENT '用户称号',
|
||||||
title_url VARCHAR(500) NULL COMMENT '称号链接',
|
title_url VARCHAR(500) NULL COMMENT '称号链接',
|
||||||
interests TEXT NULL COMMENT '兴趣爱好',
|
interests TEXT NULL COMMENT '兴趣爱好',
|
||||||
location VARCHAR(100) NULL COMMENT '地理位置',
|
location VARCHAR(100) NULL COMMENT '地理位置',
|
||||||
occupation VARCHAR(100) NULL COMMENT '职业',
|
occupation VARCHAR(100) NULL COMMENT '职业',
|
||||||
|
|
||||||
-- 游戏相关字段
|
-- 游戏相关字段
|
||||||
playmode VARCHAR(10) DEFAULT 'osu' COMMENT '主要游戏模式',
|
playmode VARCHAR(10) DEFAULT 'osu' COMMENT '主要游戏模式',
|
||||||
support_level INT DEFAULT 0 COMMENT '支持者等级',
|
support_level INT DEFAULT 0 COMMENT '支持者等级',
|
||||||
max_blocks INT DEFAULT 100 COMMENT '最大屏蔽数量',
|
max_blocks INT DEFAULT 100 COMMENT '最大屏蔽数量',
|
||||||
max_friends INT DEFAULT 500 COMMENT '最大好友数量',
|
max_friends INT DEFAULT 500 COMMENT '最大好友数量',
|
||||||
post_count INT DEFAULT 0 COMMENT '帖子数量',
|
post_count INT DEFAULT 0 COMMENT '帖子数量',
|
||||||
|
|
||||||
-- 页面内容
|
-- 页面内容
|
||||||
page_html TEXT NULL COMMENT '个人页面HTML',
|
page_html TEXT NULL COMMENT '个人页面HTML',
|
||||||
page_raw TEXT NULL COMMENT '个人页面原始内容',
|
page_raw TEXT NULL COMMENT '个人页面原始内容',
|
||||||
|
|
||||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||||
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||||
|
|
||||||
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
|
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='Lazer API 用户扩展资料表';
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='Lazer API 用户扩展资料表';
|
||||||
|
|
||||||
-- 用户封面信息表
|
-- 用户封面信息表
|
||||||
CREATE TABLE IF NOT EXISTS lazer_user_covers (
|
CREATE TABLE IF NOT EXISTS lazer_user_covers (
|
||||||
user_id INT PRIMARY KEY COMMENT '关联 users.id',
|
user_id INT PRIMARY KEY COMMENT '关联 users.id',
|
||||||
custom_url VARCHAR(500) NULL COMMENT '自定义封面URL',
|
custom_url VARCHAR(500) NULL COMMENT '自定义封面URL',
|
||||||
url VARCHAR(500) NULL COMMENT '封面URL',
|
url VARCHAR(500) NULL COMMENT '封面URL',
|
||||||
cover_id INT NULL COMMENT '封面ID',
|
cover_id INT NULL COMMENT '封面ID',
|
||||||
|
|
||||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||||
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||||
|
|
||||||
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
|
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户封面信息表';
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户封面信息表';
|
||||||
|
|
||||||
-- 用户国家信息表
|
-- 用户国家信息表
|
||||||
CREATE TABLE IF NOT EXISTS lazer_user_countries (
|
CREATE TABLE IF NOT EXISTS lazer_user_countries (
|
||||||
user_id INT PRIMARY KEY COMMENT '关联 users.id',
|
user_id INT PRIMARY KEY COMMENT '关联 users.id',
|
||||||
code VARCHAR(2) NOT NULL COMMENT '国家代码',
|
code VARCHAR(2) NOT NULL COMMENT '国家代码',
|
||||||
name VARCHAR(100) NOT NULL COMMENT '国家名称',
|
name VARCHAR(100) NOT NULL COMMENT '国家名称',
|
||||||
|
|
||||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||||
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||||
|
|
||||||
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
|
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户国家信息表';
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户国家信息表';
|
||||||
|
|
||||||
-- 用户 Kudosu 表
|
-- 用户 Kudosu 表
|
||||||
CREATE TABLE IF NOT EXISTS lazer_user_kudosu (
|
CREATE TABLE IF NOT EXISTS lazer_user_kudosu (
|
||||||
user_id INT PRIMARY KEY COMMENT '关联 users.id',
|
user_id INT PRIMARY KEY COMMENT '关联 users.id',
|
||||||
available INT DEFAULT 0 COMMENT '可用 Kudosu',
|
available INT DEFAULT 0 COMMENT '可用 Kudosu',
|
||||||
total INT DEFAULT 0 COMMENT '总 Kudosu',
|
total INT DEFAULT 0 COMMENT '总 Kudosu',
|
||||||
|
|
||||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||||
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||||
|
|
||||||
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
|
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户 Kudosu 表';
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户 Kudosu 表';
|
||||||
|
|
||||||
-- 用户统计计数表
|
-- 用户统计计数表
|
||||||
CREATE TABLE IF NOT EXISTS lazer_user_counts (
|
CREATE TABLE IF NOT EXISTS lazer_user_counts (
|
||||||
user_id INT PRIMARY KEY COMMENT '关联 users.id',
|
user_id INT PRIMARY KEY COMMENT '关联 users.id',
|
||||||
|
|
||||||
-- 统计计数字段
|
-- 统计计数字段
|
||||||
beatmap_playcounts_count INT DEFAULT 0 COMMENT '谱面游玩次数统计',
|
beatmap_playcounts_count INT DEFAULT 0 COMMENT '谱面游玩次数统计',
|
||||||
comments_count INT DEFAULT 0 COMMENT '评论数量',
|
comments_count INT DEFAULT 0 COMMENT '评论数量',
|
||||||
favourite_beatmapset_count INT DEFAULT 0 COMMENT '收藏谱面集数量',
|
favourite_beatmapset_count INT DEFAULT 0 COMMENT '收藏谱面集数量',
|
||||||
follower_count INT DEFAULT 0 COMMENT '关注者数量',
|
follower_count INT DEFAULT 0 COMMENT '关注者数量',
|
||||||
graveyard_beatmapset_count INT DEFAULT 0 COMMENT '坟场谱面集数量',
|
graveyard_beatmapset_count INT DEFAULT 0 COMMENT '坟场谱面集数量',
|
||||||
guest_beatmapset_count INT DEFAULT 0 COMMENT '客串谱面集数量',
|
guest_beatmapset_count INT DEFAULT 0 COMMENT '客串谱面集数量',
|
||||||
loved_beatmapset_count INT DEFAULT 0 COMMENT '被喜爱谱面集数量',
|
loved_beatmapset_count INT DEFAULT 0 COMMENT '被喜爱谱面集数量',
|
||||||
mapping_follower_count INT DEFAULT 0 COMMENT '作图关注者数量',
|
mapping_follower_count INT DEFAULT 0 COMMENT '作图关注者数量',
|
||||||
nominated_beatmapset_count INT DEFAULT 0 COMMENT '提名谱面集数量',
|
nominated_beatmapset_count INT DEFAULT 0 COMMENT '提名谱面集数量',
|
||||||
pending_beatmapset_count INT DEFAULT 0 COMMENT '待审核谱面集数量',
|
pending_beatmapset_count INT DEFAULT 0 COMMENT '待审核谱面集数量',
|
||||||
ranked_beatmapset_count INT DEFAULT 0 COMMENT 'Ranked谱面集数量',
|
ranked_beatmapset_count INT DEFAULT 0 COMMENT 'Ranked谱面集数量',
|
||||||
ranked_and_approved_beatmapset_count INT DEFAULT 0 COMMENT 'Ranked+Approved谱面集数量',
|
ranked_and_approved_beatmapset_count INT DEFAULT 0 COMMENT 'Ranked+Approved谱面集数量',
|
||||||
unranked_beatmapset_count INT DEFAULT 0 COMMENT '未Ranked谱面集数量',
|
unranked_beatmapset_count INT DEFAULT 0 COMMENT '未Ranked谱面集数量',
|
||||||
scores_best_count INT DEFAULT 0 COMMENT '最佳成绩数量',
|
scores_best_count INT DEFAULT 0 COMMENT '最佳成绩数量',
|
||||||
scores_first_count INT DEFAULT 0 COMMENT '第一名成绩数量',
|
scores_first_count INT DEFAULT 0 COMMENT '第一名成绩数量',
|
||||||
scores_pinned_count INT DEFAULT 0 COMMENT '置顶成绩数量',
|
scores_pinned_count INT DEFAULT 0 COMMENT '置顶成绩数量',
|
||||||
scores_recent_count INT DEFAULT 0 COMMENT '最近成绩数量',
|
scores_recent_count INT DEFAULT 0 COMMENT '最近成绩数量',
|
||||||
|
|
||||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||||
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||||
|
|
||||||
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
|
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='Lazer API 用户统计计数表';
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='Lazer API 用户统计计数表';
|
||||||
|
|
||||||
-- 用户游戏风格表 (替代 playstyle JSON)
|
-- 用户游戏风格表 (替代 playstyle JSON)
|
||||||
CREATE TABLE IF NOT EXISTS lazer_user_playstyles (
|
CREATE TABLE IF NOT EXISTS lazer_user_playstyles (
|
||||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||||
user_id INT NOT NULL COMMENT '关联 users.id',
|
user_id INT NOT NULL COMMENT '关联 users.id',
|
||||||
style VARCHAR(50) NOT NULL COMMENT '游戏风格: mouse, keyboard, tablet, touch',
|
style VARCHAR(50) NOT NULL COMMENT '游戏风格: mouse, keyboard, tablet, touch',
|
||||||
|
|
||||||
INDEX idx_user_id (user_id),
|
INDEX idx_user_id (user_id),
|
||||||
UNIQUE KEY unique_user_style (user_id, style),
|
UNIQUE KEY unique_user_style (user_id, style),
|
||||||
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
|
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户游戏风格表';
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户游戏风格表';
|
||||||
|
|
||||||
-- 用户个人资料显示顺序表 (替代 profile_order JSON)
|
-- 用户个人资料显示顺序表 (替代 profile_order JSON)
|
||||||
CREATE TABLE IF NOT EXISTS lazer_user_profile_sections (
|
CREATE TABLE IF NOT EXISTS lazer_user_profile_sections (
|
||||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||||
user_id INT NOT NULL COMMENT '关联 users.id',
|
user_id INT NOT NULL COMMENT '关联 users.id',
|
||||||
section_name VARCHAR(50) NOT NULL COMMENT '部分名称',
|
section_name VARCHAR(50) NOT NULL COMMENT '部分名称',
|
||||||
display_order INT DEFAULT 0 COMMENT '显示顺序',
|
display_order INT DEFAULT 0 COMMENT '显示顺序',
|
||||||
|
|
||||||
INDEX idx_user_id (user_id),
|
INDEX idx_user_id (user_id),
|
||||||
INDEX idx_order (user_id, display_order),
|
INDEX idx_order (user_id, display_order),
|
||||||
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
|
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户个人资料显示顺序表';
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户个人资料显示顺序表';
|
||||||
|
|
||||||
-- 用户账户历史表 (替代 account_history JSON)
|
-- 用户账户历史表 (替代 account_history JSON)
|
||||||
CREATE TABLE IF NOT EXISTS lazer_user_account_history (
|
CREATE TABLE IF NOT EXISTS lazer_user_account_history (
|
||||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||||
user_id INT NOT NULL COMMENT '关联 users.id',
|
user_id INT NOT NULL COMMENT '关联 users.id',
|
||||||
event_type VARCHAR(50) NOT NULL COMMENT '事件类型',
|
event_type VARCHAR(50) NOT NULL COMMENT '事件类型',
|
||||||
description TEXT COMMENT '事件描述',
|
description TEXT COMMENT '事件描述',
|
||||||
length INT COMMENT '持续时间(秒)',
|
length INT COMMENT '持续时间(秒)',
|
||||||
permanent TINYINT(1) DEFAULT 0 COMMENT '是否永久',
|
permanent TINYINT(1) DEFAULT 0 COMMENT '是否永久',
|
||||||
event_time DATETIME NOT NULL COMMENT '事件时间',
|
event_time DATETIME NOT NULL COMMENT '事件时间',
|
||||||
|
|
||||||
INDEX idx_user_id (user_id),
|
INDEX idx_user_id (user_id),
|
||||||
INDEX idx_event_time (event_time),
|
INDEX idx_event_time (event_time),
|
||||||
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
|
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户账户历史表';
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户账户历史表';
|
||||||
|
|
||||||
-- 用户历史用户名表 (替代 previous_usernames JSON)
|
-- 用户历史用户名表 (替代 previous_usernames JSON)
|
||||||
CREATE TABLE IF NOT EXISTS lazer_user_previous_usernames (
|
CREATE TABLE IF NOT EXISTS lazer_user_previous_usernames (
|
||||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||||
user_id INT NOT NULL COMMENT '关联 users.id',
|
user_id INT NOT NULL COMMENT '关联 users.id',
|
||||||
username VARCHAR(32) NOT NULL COMMENT '历史用户名',
|
username VARCHAR(32) NOT NULL COMMENT '历史用户名',
|
||||||
changed_at DATETIME NOT NULL COMMENT '更改时间',
|
changed_at DATETIME NOT NULL COMMENT '更改时间',
|
||||||
|
|
||||||
INDEX idx_user_id (user_id),
|
INDEX idx_user_id (user_id),
|
||||||
INDEX idx_changed_at (changed_at),
|
INDEX idx_changed_at (changed_at),
|
||||||
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
|
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户历史用户名表';
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户历史用户名表';
|
||||||
|
|
||||||
-- 用户月度游戏次数表 (替代 monthly_playcounts JSON)
|
-- 用户月度游戏次数表 (替代 monthly_playcounts JSON)
|
||||||
CREATE TABLE IF NOT EXISTS lazer_user_monthly_playcounts (
|
CREATE TABLE IF NOT EXISTS lazer_user_monthly_playcounts (
|
||||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||||
user_id INT NOT NULL COMMENT '关联 users.id',
|
user_id INT NOT NULL COMMENT '关联 users.id',
|
||||||
start_date DATE NOT NULL COMMENT '月份开始日期',
|
start_date DATE NOT NULL COMMENT '月份开始日期',
|
||||||
play_count INT DEFAULT 0 COMMENT '游戏次数',
|
play_count INT DEFAULT 0 COMMENT '游戏次数',
|
||||||
|
|
||||||
INDEX idx_user_id (user_id),
|
INDEX idx_user_id (user_id),
|
||||||
INDEX idx_start_date (start_date),
|
INDEX idx_start_date (start_date),
|
||||||
UNIQUE KEY unique_user_month (user_id, start_date),
|
UNIQUE KEY unique_user_month (user_id, start_date),
|
||||||
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
|
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户月度游戏次数表';
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户月度游戏次数表';
|
||||||
|
|
||||||
-- 用户最高排名表 (rank_highest)
|
-- 用户最高排名表 (rank_highest)
|
||||||
CREATE TABLE IF NOT EXISTS lazer_user_rank_highest (
|
CREATE TABLE IF NOT EXISTS lazer_user_rank_highest (
|
||||||
user_id INT PRIMARY KEY COMMENT '关联 users.id',
|
user_id INT PRIMARY KEY COMMENT '关联 users.id',
|
||||||
rank_position INT NOT NULL COMMENT '最高排名位置',
|
rank_position INT NOT NULL COMMENT '最高排名位置',
|
||||||
updated_at DATETIME NOT NULL COMMENT '更新时间',
|
updated_at DATETIME NOT NULL COMMENT '更新时间',
|
||||||
|
|
||||||
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
|
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户最高排名表';
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户最高排名表';
|
||||||
|
|
||||||
-- ============================================
|
-- ============================================
|
||||||
-- OAuth 令牌表 (Lazer API 专用)
|
-- OAuth 令牌表 (Lazer API 专用)
|
||||||
-- ============================================
|
-- ============================================
|
||||||
CREATE TABLE IF NOT EXISTS lazer_oauth_tokens (
|
CREATE TABLE IF NOT EXISTS lazer_oauth_tokens (
|
||||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||||
user_id INT NOT NULL,
|
user_id INT NOT NULL,
|
||||||
access_token VARCHAR(255) NOT NULL,
|
access_token VARCHAR(255) NOT NULL,
|
||||||
refresh_token VARCHAR(255) NOT NULL,
|
refresh_token VARCHAR(255) NOT NULL,
|
||||||
expires_at DATETIME NOT NULL,
|
expires_at DATETIME NOT NULL,
|
||||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||||
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||||
INDEX idx_user_id (user_id),
|
INDEX idx_user_id (user_id),
|
||||||
INDEX idx_access_token (access_token),
|
INDEX idx_access_token (access_token),
|
||||||
INDEX idx_refresh_token (refresh_token),
|
INDEX idx_refresh_token (refresh_token),
|
||||||
INDEX idx_expires_at (expires_at),
|
INDEX idx_expires_at (expires_at),
|
||||||
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
|
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='Lazer API OAuth访问令牌表';
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='Lazer API OAuth访问令牌表';
|
||||||
|
|
||||||
-- ============================================
|
-- ============================================
|
||||||
-- 用户统计数据表 (基于真实 API 数据结构)
|
-- 用户统计数据表 (基于真实 API 数据结构)
|
||||||
-- ============================================
|
-- ============================================
|
||||||
|
|
||||||
-- 用户主要统计表 (statistics 字段)
|
-- 用户主要统计表 (statistics 字段)
|
||||||
CREATE TABLE IF NOT EXISTS lazer_user_statistics (
|
CREATE TABLE IF NOT EXISTS lazer_user_statistics (
|
||||||
user_id INT NOT NULL,
|
user_id INT NOT NULL,
|
||||||
mode VARCHAR(10) NOT NULL DEFAULT 'osu' COMMENT '游戏模式: osu, taiko, fruits, mania',
|
mode VARCHAR(10) NOT NULL DEFAULT 'osu' COMMENT '游戏模式: osu, taiko, fruits, mania',
|
||||||
|
|
||||||
-- 基本命中统计
|
-- 基本命中统计
|
||||||
count_100 INT DEFAULT 0 COMMENT '100分命中数',
|
count_100 INT DEFAULT 0 COMMENT '100分命中数',
|
||||||
count_300 INT DEFAULT 0 COMMENT '300分命中数',
|
count_300 INT DEFAULT 0 COMMENT '300分命中数',
|
||||||
count_50 INT DEFAULT 0 COMMENT '50分命中数',
|
count_50 INT DEFAULT 0 COMMENT '50分命中数',
|
||||||
count_miss INT DEFAULT 0 COMMENT 'Miss数',
|
count_miss INT DEFAULT 0 COMMENT 'Miss数',
|
||||||
|
|
||||||
-- 等级信息
|
-- 等级信息
|
||||||
level_current INT DEFAULT 1 COMMENT '当前等级',
|
level_current INT DEFAULT 1 COMMENT '当前等级',
|
||||||
level_progress INT DEFAULT 0 COMMENT '等级进度',
|
level_progress INT DEFAULT 0 COMMENT '等级进度',
|
||||||
|
|
||||||
-- 排名信息
|
-- 排名信息
|
||||||
global_rank INT NULL COMMENT '全球排名',
|
global_rank INT NULL COMMENT '全球排名',
|
||||||
global_rank_exp INT NULL COMMENT '全球排名(实验性)',
|
global_rank_exp INT NULL COMMENT '全球排名(实验性)',
|
||||||
country_rank INT NULL COMMENT '国家/地区排名',
|
country_rank INT NULL COMMENT '国家/地区排名',
|
||||||
|
|
||||||
-- PP 和分数
|
-- PP 和分数
|
||||||
pp DECIMAL(10,2) DEFAULT 0.00 COMMENT 'Performance Points',
|
pp DECIMAL(10,2) DEFAULT 0.00 COMMENT 'Performance Points',
|
||||||
pp_exp DECIMAL(10,2) DEFAULT 0.00 COMMENT 'PP(实验性)',
|
pp_exp DECIMAL(10,2) DEFAULT 0.00 COMMENT 'PP(实验性)',
|
||||||
ranked_score BIGINT DEFAULT 0 COMMENT 'Ranked分数',
|
ranked_score BIGINT DEFAULT 0 COMMENT 'Ranked分数',
|
||||||
hit_accuracy DECIMAL(5,2) DEFAULT 0.00 COMMENT '命中精度',
|
hit_accuracy DECIMAL(5,2) DEFAULT 0.00 COMMENT '命中精度',
|
||||||
total_score BIGINT DEFAULT 0 COMMENT '总分数',
|
total_score BIGINT DEFAULT 0 COMMENT '总分数',
|
||||||
total_hits BIGINT DEFAULT 0 COMMENT '总命中数',
|
total_hits BIGINT DEFAULT 0 COMMENT '总命中数',
|
||||||
maximum_combo INT DEFAULT 0 COMMENT '最大连击',
|
maximum_combo INT DEFAULT 0 COMMENT '最大连击',
|
||||||
|
|
||||||
-- 游戏统计
|
-- 游戏统计
|
||||||
play_count INT DEFAULT 0 COMMENT '游戏次数',
|
play_count INT DEFAULT 0 COMMENT '游戏次数',
|
||||||
play_time INT DEFAULT 0 COMMENT '游戏时间(秒)',
|
play_time INT DEFAULT 0 COMMENT '游戏时间(秒)',
|
||||||
replays_watched_by_others INT DEFAULT 0 COMMENT '被观看的Replay次数',
|
replays_watched_by_others INT DEFAULT 0 COMMENT '被观看的Replay次数',
|
||||||
is_ranked TINYINT(1) DEFAULT 0 COMMENT '是否有排名',
|
is_ranked TINYINT(1) DEFAULT 0 COMMENT '是否有排名',
|
||||||
|
|
||||||
-- 成绩等级计数 (grade_counts)
|
-- 成绩等级计数 (grade_counts)
|
||||||
grade_ss INT DEFAULT 0 COMMENT 'SS等级数',
|
grade_ss INT DEFAULT 0 COMMENT 'SS等级数',
|
||||||
grade_ssh INT DEFAULT 0 COMMENT 'SSH等级数',
|
grade_ssh INT DEFAULT 0 COMMENT 'SSH等级数',
|
||||||
grade_s INT DEFAULT 0 COMMENT 'S等级数',
|
grade_s INT DEFAULT 0 COMMENT 'S等级数',
|
||||||
grade_sh INT DEFAULT 0 COMMENT 'SH等级数',
|
grade_sh INT DEFAULT 0 COMMENT 'SH等级数',
|
||||||
grade_a INT DEFAULT 0 COMMENT 'A等级数',
|
grade_a INT DEFAULT 0 COMMENT 'A等级数',
|
||||||
|
|
||||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||||
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||||
|
|
||||||
PRIMARY KEY (user_id, mode),
|
PRIMARY KEY (user_id, mode),
|
||||||
INDEX idx_mode (mode),
|
INDEX idx_mode (mode),
|
||||||
INDEX idx_global_rank (global_rank),
|
INDEX idx_global_rank (global_rank),
|
||||||
INDEX idx_country_rank (country_rank),
|
INDEX idx_country_rank (country_rank),
|
||||||
INDEX idx_pp (pp),
|
INDEX idx_pp (pp),
|
||||||
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
|
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='Lazer API 用户游戏统计表';
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='Lazer API 用户游戏统计表';
|
||||||
|
|
||||||
-- 每日挑战用户统计表 (daily_challenge_user_stats)
|
-- 每日挑战用户统计表 (daily_challenge_user_stats)
|
||||||
CREATE TABLE IF NOT EXISTS lazer_daily_challenge_stats (
|
CREATE TABLE IF NOT EXISTS lazer_daily_challenge_stats (
|
||||||
user_id INT PRIMARY KEY COMMENT '关联 users.id',
|
user_id INT PRIMARY KEY COMMENT '关联 users.id',
|
||||||
daily_streak_best INT DEFAULT 0 COMMENT '最佳每日连击',
|
daily_streak_best INT DEFAULT 0 COMMENT '最佳每日连击',
|
||||||
daily_streak_current INT DEFAULT 0 COMMENT '当前每日连击',
|
daily_streak_current INT DEFAULT 0 COMMENT '当前每日连击',
|
||||||
last_update DATE NULL COMMENT '最后更新日期',
|
last_update DATE NULL COMMENT '最后更新日期',
|
||||||
last_weekly_streak DATE NULL COMMENT '最后周连击日期',
|
last_weekly_streak DATE NULL COMMENT '最后周连击日期',
|
||||||
playcount INT DEFAULT 0 COMMENT '游戏次数',
|
playcount INT DEFAULT 0 COMMENT '游戏次数',
|
||||||
top_10p_placements INT DEFAULT 0 COMMENT 'Top 10% 位置数',
|
top_10p_placements INT DEFAULT 0 COMMENT 'Top 10% 位置数',
|
||||||
top_50p_placements INT DEFAULT 0 COMMENT 'Top 50% 位置数',
|
top_50p_placements INT DEFAULT 0 COMMENT 'Top 50% 位置数',
|
||||||
weekly_streak_best INT DEFAULT 0 COMMENT '最佳周连击',
|
weekly_streak_best INT DEFAULT 0 COMMENT '最佳周连击',
|
||||||
weekly_streak_current INT DEFAULT 0 COMMENT '当前周连击',
|
weekly_streak_current INT DEFAULT 0 COMMENT '当前周连击',
|
||||||
|
|
||||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||||
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||||
|
|
||||||
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
|
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='每日挑战用户统计表';
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='每日挑战用户统计表';
|
||||||
|
|
||||||
-- 用户团队信息表 (team 字段)
|
-- 用户团队信息表 (team 字段)
|
||||||
CREATE TABLE IF NOT EXISTS lazer_user_teams (
|
CREATE TABLE IF NOT EXISTS lazer_user_teams (
|
||||||
user_id INT PRIMARY KEY COMMENT '关联 users.id',
|
user_id INT PRIMARY KEY COMMENT '关联 users.id',
|
||||||
team_id INT NOT NULL COMMENT '团队ID',
|
team_id INT NOT NULL COMMENT '团队ID',
|
||||||
team_name VARCHAR(100) NOT NULL COMMENT '团队名称',
|
team_name VARCHAR(100) NOT NULL COMMENT '团队名称',
|
||||||
team_short_name VARCHAR(10) NOT NULL COMMENT '团队简称',
|
team_short_name VARCHAR(10) NOT NULL COMMENT '团队简称',
|
||||||
flag_url VARCHAR(500) NULL COMMENT '团队旗帜URL',
|
flag_url VARCHAR(500) NULL COMMENT '团队旗帜URL',
|
||||||
|
|
||||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||||
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||||
|
|
||||||
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
|
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户团队信息表';
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户团队信息表';
|
||||||
|
|
||||||
-- 用户成就表 (user_achievements)
|
-- 用户成就表 (user_achievements)
|
||||||
CREATE TABLE IF NOT EXISTS lazer_user_achievements (
|
CREATE TABLE IF NOT EXISTS lazer_user_achievements (
|
||||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||||
user_id INT NOT NULL COMMENT '关联 users.id',
|
user_id INT NOT NULL COMMENT '关联 users.id',
|
||||||
achievement_id INT NOT NULL COMMENT '成就ID',
|
achievement_id INT NOT NULL COMMENT '成就ID',
|
||||||
achieved_at DATETIME NOT NULL COMMENT '获得时间',
|
achieved_at DATETIME NOT NULL COMMENT '获得时间',
|
||||||
|
|
||||||
INDEX idx_user_id (user_id),
|
INDEX idx_user_id (user_id),
|
||||||
INDEX idx_achievement_id (achievement_id),
|
INDEX idx_achievement_id (achievement_id),
|
||||||
INDEX idx_achieved_at (achieved_at),
|
INDEX idx_achieved_at (achieved_at),
|
||||||
UNIQUE KEY unique_user_achievement (user_id, achievement_id),
|
UNIQUE KEY unique_user_achievement (user_id, achievement_id),
|
||||||
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
|
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户成就表';
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户成就表';
|
||||||
|
|
||||||
-- 用户排名历史表 (rank_history)
|
-- 用户排名历史表 (rank_history)
|
||||||
CREATE TABLE IF NOT EXISTS lazer_user_rank_history (
|
CREATE TABLE IF NOT EXISTS lazer_user_rank_history (
|
||||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||||
user_id INT NOT NULL COMMENT '关联 users.id',
|
user_id INT NOT NULL COMMENT '关联 users.id',
|
||||||
mode VARCHAR(10) NOT NULL DEFAULT 'osu' COMMENT '游戏模式',
|
mode VARCHAR(10) NOT NULL DEFAULT 'osu' COMMENT '游戏模式',
|
||||||
day_offset INT NOT NULL COMMENT '天数偏移量(从某个基准日期开始)',
|
day_offset INT NOT NULL COMMENT '天数偏移量(从某个基准日期开始)',
|
||||||
rank_position INT NOT NULL COMMENT '排名位置',
|
rank_position INT NOT NULL COMMENT '排名位置',
|
||||||
|
|
||||||
INDEX idx_user_mode (user_id, mode),
|
INDEX idx_user_mode (user_id, mode),
|
||||||
INDEX idx_day_offset (day_offset),
|
INDEX idx_day_offset (day_offset),
|
||||||
UNIQUE KEY unique_user_mode_day (user_id, mode, day_offset),
|
UNIQUE KEY unique_user_mode_day (user_id, mode, day_offset),
|
||||||
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
|
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户排名历史表';
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户排名历史表';
|
||||||
|
|
||||||
-- Replay 观看次数表 (replays_watched_counts)
|
-- Replay 观看次数表 (replays_watched_counts)
|
||||||
CREATE TABLE IF NOT EXISTS lazer_user_replays_watched (
|
CREATE TABLE IF NOT EXISTS lazer_user_replays_watched (
|
||||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||||
user_id INT NOT NULL COMMENT '关联 users.id',
|
user_id INT NOT NULL COMMENT '关联 users.id',
|
||||||
start_date DATE NOT NULL COMMENT '开始日期',
|
start_date DATE NOT NULL COMMENT '开始日期',
|
||||||
count INT DEFAULT 0 COMMENT '观看次数',
|
count INT DEFAULT 0 COMMENT '观看次数',
|
||||||
|
|
||||||
INDEX idx_user_id (user_id),
|
INDEX idx_user_id (user_id),
|
||||||
INDEX idx_start_date (start_date),
|
INDEX idx_start_date (start_date),
|
||||||
UNIQUE KEY unique_user_date (user_id, start_date),
|
UNIQUE KEY unique_user_date (user_id, start_date),
|
||||||
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
|
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户Replay观看次数表';
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户Replay观看次数表';
|
||||||
|
|
||||||
-- 用户徽章表 (badges)
|
-- 用户徽章表 (badges)
|
||||||
CREATE TABLE IF NOT EXISTS lazer_user_badges (
|
CREATE TABLE IF NOT EXISTS lazer_user_badges (
|
||||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||||
user_id INT NOT NULL COMMENT '关联 users.id',
|
user_id INT NOT NULL COMMENT '关联 users.id',
|
||||||
badge_id INT NOT NULL COMMENT '徽章ID',
|
badge_id INT NOT NULL COMMENT '徽章ID',
|
||||||
awarded_at DATETIME NULL COMMENT '授予时间',
|
awarded_at DATETIME NULL COMMENT '授予时间',
|
||||||
description TEXT NULL COMMENT '徽章描述',
|
description TEXT NULL COMMENT '徽章描述',
|
||||||
image_url VARCHAR(500) NULL COMMENT '徽章图片URL',
|
image_url VARCHAR(500) NULL COMMENT '徽章图片URL',
|
||||||
url VARCHAR(500) NULL COMMENT '徽章链接',
|
url VARCHAR(500) NULL COMMENT '徽章链接',
|
||||||
|
|
||||||
INDEX idx_user_id (user_id),
|
INDEX idx_user_id (user_id),
|
||||||
INDEX idx_badge_id (badge_id),
|
INDEX idx_badge_id (badge_id),
|
||||||
UNIQUE KEY unique_user_badge (user_id, badge_id),
|
UNIQUE KEY unique_user_badge (user_id, badge_id),
|
||||||
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
|
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户徽章表';
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户徽章表';
|
||||||
|
|
||||||
-- 用户组表 (groups)
|
-- 用户组表 (groups)
|
||||||
CREATE TABLE IF NOT EXISTS lazer_user_groups (
|
CREATE TABLE IF NOT EXISTS lazer_user_groups (
|
||||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||||
user_id INT NOT NULL COMMENT '关联 users.id',
|
user_id INT NOT NULL COMMENT '关联 users.id',
|
||||||
group_id INT NOT NULL COMMENT '用户组ID',
|
group_id INT NOT NULL COMMENT '用户组ID',
|
||||||
group_name VARCHAR(100) NOT NULL COMMENT '用户组名称',
|
group_name VARCHAR(100) NOT NULL COMMENT '用户组名称',
|
||||||
group_identifier VARCHAR(50) NULL COMMENT '用户组标识符',
|
group_identifier VARCHAR(50) NULL COMMENT '用户组标识符',
|
||||||
colour VARCHAR(7) NULL COMMENT '用户组颜色',
|
colour VARCHAR(7) NULL COMMENT '用户组颜色',
|
||||||
is_probationary TINYINT(1) DEFAULT 0 COMMENT '是否为试用期',
|
is_probationary TINYINT(1) DEFAULT 0 COMMENT '是否为试用期',
|
||||||
has_listing TINYINT(1) DEFAULT 1 COMMENT '是否显示在列表中',
|
has_listing TINYINT(1) DEFAULT 1 COMMENT '是否显示在列表中',
|
||||||
has_playmodes TINYINT(1) DEFAULT 0 COMMENT '是否有游戏模式',
|
has_playmodes TINYINT(1) DEFAULT 0 COMMENT '是否有游戏模式',
|
||||||
|
|
||||||
INDEX idx_user_id (user_id),
|
INDEX idx_user_id (user_id),
|
||||||
INDEX idx_group_id (group_id),
|
INDEX idx_group_id (group_id),
|
||||||
UNIQUE KEY unique_user_group (user_id, group_id),
|
UNIQUE KEY unique_user_group (user_id, group_id),
|
||||||
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
|
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户组表';
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户组表';
|
||||||
|
|
||||||
-- 锦标赛横幅表 (active_tournament_banners)
|
-- 锦标赛横幅表 (active_tournament_banners)
|
||||||
CREATE TABLE IF NOT EXISTS lazer_user_tournament_banners (
|
CREATE TABLE IF NOT EXISTS lazer_user_tournament_banners (
|
||||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||||
user_id INT NOT NULL COMMENT '关联 users.id',
|
user_id INT NOT NULL COMMENT '关联 users.id',
|
||||||
tournament_id INT NOT NULL COMMENT '锦标赛ID',
|
tournament_id INT NOT NULL COMMENT '锦标赛ID',
|
||||||
image_url VARCHAR(500) NOT NULL COMMENT '横幅图片URL',
|
image_url VARCHAR(500) NOT NULL COMMENT '横幅图片URL',
|
||||||
is_active TINYINT(1) DEFAULT 1 COMMENT '是否为当前活跃横幅',
|
is_active TINYINT(1) DEFAULT 1 COMMENT '是否为当前活跃横幅',
|
||||||
|
|
||||||
INDEX idx_user_id (user_id),
|
INDEX idx_user_id (user_id),
|
||||||
INDEX idx_tournament_id (tournament_id),
|
INDEX idx_tournament_id (tournament_id),
|
||||||
INDEX idx_is_active (is_active),
|
INDEX idx_is_active (is_active),
|
||||||
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
|
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户锦标赛横幅表';
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户锦标赛横幅表';
|
||||||
|
|
||||||
-- ============================================
|
-- ============================================
|
||||||
-- 占位表 (未来功能扩展用)
|
-- 占位表 (未来功能扩展用)
|
||||||
-- ============================================
|
-- ============================================
|
||||||
|
|
||||||
-- 当前赛季统计占位表
|
-- 当前赛季统计占位表
|
||||||
CREATE TABLE IF NOT EXISTS lazer_current_season_stats (
|
CREATE TABLE IF NOT EXISTS lazer_current_season_stats (
|
||||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||||
user_id INT NOT NULL COMMENT '关联 users.id',
|
user_id INT NOT NULL COMMENT '关联 users.id',
|
||||||
season_id VARCHAR(50) NOT NULL COMMENT '赛季ID',
|
season_id VARCHAR(50) NOT NULL COMMENT '赛季ID',
|
||||||
data_placeholder TEXT COMMENT '赛季数据占位',
|
data_placeholder TEXT COMMENT '赛季数据占位',
|
||||||
|
|
||||||
INDEX idx_user_id (user_id),
|
INDEX idx_user_id (user_id),
|
||||||
INDEX idx_season_id (season_id),
|
INDEX idx_season_id (season_id),
|
||||||
UNIQUE KEY unique_user_season (user_id, season_id),
|
UNIQUE KEY unique_user_season (user_id, season_id),
|
||||||
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
|
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='当前赛季统计占位表';
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='当前赛季统计占位表';
|
||||||
|
|
||||||
-- 其他功能占位表
|
-- 其他功能占位表
|
||||||
CREATE TABLE IF NOT EXISTS lazer_feature_placeholder (
|
CREATE TABLE IF NOT EXISTS lazer_feature_placeholder (
|
||||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||||
feature_type VARCHAR(50) NOT NULL COMMENT '功能类型',
|
feature_type VARCHAR(50) NOT NULL COMMENT '功能类型',
|
||||||
entity_id INT NOT NULL COMMENT '实体ID',
|
entity_id INT NOT NULL COMMENT '实体ID',
|
||||||
data_placeholder TEXT COMMENT '功能数据占位',
|
data_placeholder TEXT COMMENT '功能数据占位',
|
||||||
|
|
||||||
INDEX idx_feature_type (feature_type),
|
INDEX idx_feature_type (feature_type),
|
||||||
INDEX idx_entity_id (entity_id)
|
INDEX idx_entity_id (entity_id)
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='功能扩展占位表';
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='功能扩展占位表';
|
||||||
|
|||||||
@@ -1,486 +1,486 @@
|
|||||||
create table achievements
|
create table achievements
|
||||||
(
|
(
|
||||||
id int auto_increment
|
id int auto_increment
|
||||||
primary key,
|
primary key,
|
||||||
file varchar(128) not null,
|
file varchar(128) not null,
|
||||||
name varchar(128) charset utf8 not null,
|
name varchar(128) charset utf8 not null,
|
||||||
`desc` varchar(256) charset utf8 not null,
|
`desc` varchar(256) charset utf8 not null,
|
||||||
cond varchar(64) not null,
|
cond varchar(64) not null,
|
||||||
constraint achievements_desc_uindex
|
constraint achievements_desc_uindex
|
||||||
unique (`desc`),
|
unique (`desc`),
|
||||||
constraint achievements_file_uindex
|
constraint achievements_file_uindex
|
||||||
unique (file),
|
unique (file),
|
||||||
constraint achievements_name_uindex
|
constraint achievements_name_uindex
|
||||||
unique (name)
|
unique (name)
|
||||||
);
|
);
|
||||||
|
|
||||||
create table channels
|
create table channels
|
||||||
(
|
(
|
||||||
id int auto_increment
|
id int auto_increment
|
||||||
primary key,
|
primary key,
|
||||||
name varchar(32) not null,
|
name varchar(32) not null,
|
||||||
topic varchar(256) not null,
|
topic varchar(256) not null,
|
||||||
read_priv int default 1 not null,
|
read_priv int default 1 not null,
|
||||||
write_priv int default 2 not null,
|
write_priv int default 2 not null,
|
||||||
auto_join tinyint(1) default 0 not null,
|
auto_join tinyint(1) default 0 not null,
|
||||||
constraint channels_name_uindex
|
constraint channels_name_uindex
|
||||||
unique (name)
|
unique (name)
|
||||||
);
|
);
|
||||||
create index channels_auto_join_index
|
create index channels_auto_join_index
|
||||||
on channels (auto_join);
|
on channels (auto_join);
|
||||||
|
|
||||||
create table clans
|
create table clans
|
||||||
(
|
(
|
||||||
id int auto_increment
|
id int auto_increment
|
||||||
primary key,
|
primary key,
|
||||||
name varchar(16) charset utf8 not null,
|
name varchar(16) charset utf8 not null,
|
||||||
tag varchar(6) charset utf8 not null,
|
tag varchar(6) charset utf8 not null,
|
||||||
owner int not null,
|
owner int not null,
|
||||||
created_at datetime not null,
|
created_at datetime not null,
|
||||||
constraint clans_name_uindex
|
constraint clans_name_uindex
|
||||||
unique (name),
|
unique (name),
|
||||||
constraint clans_owner_uindex
|
constraint clans_owner_uindex
|
||||||
unique (owner),
|
unique (owner),
|
||||||
constraint clans_tag_uindex
|
constraint clans_tag_uindex
|
||||||
unique (tag)
|
unique (tag)
|
||||||
);
|
);
|
||||||
|
|
||||||
create table client_hashes
|
create table client_hashes
|
||||||
(
|
(
|
||||||
userid int not null,
|
userid int not null,
|
||||||
osupath char(32) not null,
|
osupath char(32) not null,
|
||||||
adapters char(32) not null,
|
adapters char(32) not null,
|
||||||
uninstall_id char(32) not null,
|
uninstall_id char(32) not null,
|
||||||
disk_serial char(32) not null,
|
disk_serial char(32) not null,
|
||||||
latest_time datetime not null,
|
latest_time datetime not null,
|
||||||
occurrences int default 0 not null,
|
occurrences int default 0 not null,
|
||||||
primary key (userid, osupath, adapters, uninstall_id, disk_serial)
|
primary key (userid, osupath, adapters, uninstall_id, disk_serial)
|
||||||
);
|
);
|
||||||
|
|
||||||
create table comments
|
create table comments
|
||||||
(
|
(
|
||||||
id int auto_increment
|
id int auto_increment
|
||||||
primary key,
|
primary key,
|
||||||
target_id int not null comment 'replay, map, or set id',
|
target_id int not null comment 'replay, map, or set id',
|
||||||
target_type enum('replay', 'map', 'song') not null,
|
target_type enum('replay', 'map', 'song') not null,
|
||||||
userid int not null,
|
userid int not null,
|
||||||
time int not null,
|
time int not null,
|
||||||
comment varchar(80) charset utf8 not null,
|
comment varchar(80) charset utf8 not null,
|
||||||
colour char(6) null comment 'rgb hex string'
|
colour char(6) null comment 'rgb hex string'
|
||||||
);
|
);
|
||||||
|
|
||||||
create table favourites
|
create table favourites
|
||||||
(
|
(
|
||||||
userid int not null,
|
userid int not null,
|
||||||
setid int not null,
|
setid int not null,
|
||||||
created_at int default 0 not null,
|
created_at int default 0 not null,
|
||||||
primary key (userid, setid)
|
primary key (userid, setid)
|
||||||
);
|
);
|
||||||
|
|
||||||
create table ingame_logins
|
create table ingame_logins
|
||||||
(
|
(
|
||||||
id int auto_increment
|
id int auto_increment
|
||||||
primary key,
|
primary key,
|
||||||
userid int not null,
|
userid int not null,
|
||||||
ip varchar(45) not null comment 'maxlen for ipv6',
|
ip varchar(45) not null comment 'maxlen for ipv6',
|
||||||
osu_ver date not null,
|
osu_ver date not null,
|
||||||
osu_stream varchar(11) not null,
|
osu_stream varchar(11) not null,
|
||||||
datetime datetime not null
|
datetime datetime not null
|
||||||
);
|
);
|
||||||
|
|
||||||
create table relationships
|
create table relationships
|
||||||
(
|
(
|
||||||
user1 int not null,
|
user1 int not null,
|
||||||
user2 int not null,
|
user2 int not null,
|
||||||
type enum('friend', 'block') not null,
|
type enum('friend', 'block') not null,
|
||||||
primary key (user1, user2)
|
primary key (user1, user2)
|
||||||
);
|
);
|
||||||
|
|
||||||
create table logs
|
create table logs
|
||||||
(
|
(
|
||||||
id int auto_increment
|
id int auto_increment
|
||||||
primary key,
|
primary key,
|
||||||
`from` int not null comment 'both from and to are playerids',
|
`from` int not null comment 'both from and to are playerids',
|
||||||
`to` int not null,
|
`to` int not null,
|
||||||
`action` varchar(32) not null,
|
`action` varchar(32) not null,
|
||||||
msg varchar(2048) charset utf8 null,
|
msg varchar(2048) charset utf8 null,
|
||||||
time datetime not null on update CURRENT_TIMESTAMP
|
time datetime not null on update CURRENT_TIMESTAMP
|
||||||
);
|
);
|
||||||
|
|
||||||
create table mail
|
create table mail
|
||||||
(
|
(
|
||||||
id int auto_increment
|
id int auto_increment
|
||||||
primary key,
|
primary key,
|
||||||
from_id int not null,
|
from_id int not null,
|
||||||
to_id int not null,
|
to_id int not null,
|
||||||
msg varchar(2048) charset utf8 not null,
|
msg varchar(2048) charset utf8 not null,
|
||||||
time int null,
|
time int null,
|
||||||
`read` tinyint(1) default 0 not null
|
`read` tinyint(1) default 0 not null
|
||||||
);
|
);
|
||||||
|
|
||||||
create table maps
|
create table maps
|
||||||
(
|
(
|
||||||
server enum('osu!', 'private') default 'osu!' not null,
|
server enum('osu!', 'private') default 'osu!' not null,
|
||||||
id int not null,
|
id int not null,
|
||||||
set_id int not null,
|
set_id int not null,
|
||||||
status int not null,
|
status int not null,
|
||||||
md5 char(32) not null,
|
md5 char(32) not null,
|
||||||
artist varchar(128) charset utf8 not null,
|
artist varchar(128) charset utf8 not null,
|
||||||
title varchar(128) charset utf8 not null,
|
title varchar(128) charset utf8 not null,
|
||||||
version varchar(128) charset utf8 not null,
|
version varchar(128) charset utf8 not null,
|
||||||
creator varchar(19) charset utf8 not null,
|
creator varchar(19) charset utf8 not null,
|
||||||
filename varchar(256) charset utf8 not null,
|
filename varchar(256) charset utf8 not null,
|
||||||
last_update datetime not null,
|
last_update datetime not null,
|
||||||
total_length int not null,
|
total_length int not null,
|
||||||
max_combo int not null,
|
max_combo int not null,
|
||||||
frozen tinyint(1) default 0 not null,
|
frozen tinyint(1) default 0 not null,
|
||||||
plays int default 0 not null,
|
plays int default 0 not null,
|
||||||
passes int default 0 not null,
|
passes int default 0 not null,
|
||||||
mode tinyint(1) default 0 not null,
|
mode tinyint(1) default 0 not null,
|
||||||
bpm float(12,2) default 0.00 not null,
|
bpm float(12,2) default 0.00 not null,
|
||||||
cs float(4,2) default 0.00 not null,
|
cs float(4,2) default 0.00 not null,
|
||||||
ar float(4,2) default 0.00 not null,
|
ar float(4,2) default 0.00 not null,
|
||||||
od float(4,2) default 0.00 not null,
|
od float(4,2) default 0.00 not null,
|
||||||
hp float(4,2) default 0.00 not null,
|
hp float(4,2) default 0.00 not null,
|
||||||
diff float(6,3) default 0.000 not null,
|
diff float(6,3) default 0.000 not null,
|
||||||
primary key (server, id),
|
primary key (server, id),
|
||||||
constraint maps_id_uindex
|
constraint maps_id_uindex
|
||||||
unique (id),
|
unique (id),
|
||||||
constraint maps_md5_uindex
|
constraint maps_md5_uindex
|
||||||
unique (md5)
|
unique (md5)
|
||||||
);
|
);
|
||||||
create index maps_set_id_index
|
create index maps_set_id_index
|
||||||
on maps (set_id);
|
on maps (set_id);
|
||||||
create index maps_status_index
|
create index maps_status_index
|
||||||
on maps (status);
|
on maps (status);
|
||||||
create index maps_filename_index
|
create index maps_filename_index
|
||||||
on maps (filename);
|
on maps (filename);
|
||||||
create index maps_plays_index
|
create index maps_plays_index
|
||||||
on maps (plays);
|
on maps (plays);
|
||||||
create index maps_mode_index
|
create index maps_mode_index
|
||||||
on maps (mode);
|
on maps (mode);
|
||||||
create index maps_frozen_index
|
create index maps_frozen_index
|
||||||
on maps (frozen);
|
on maps (frozen);
|
||||||
|
|
||||||
create table mapsets
|
create table mapsets
|
||||||
(
|
(
|
||||||
server enum('osu!', 'private') default 'osu!' not null,
|
server enum('osu!', 'private') default 'osu!' not null,
|
||||||
id int not null,
|
id int not null,
|
||||||
last_osuapi_check datetime default CURRENT_TIMESTAMP not null,
|
last_osuapi_check datetime default CURRENT_TIMESTAMP not null,
|
||||||
primary key (server, id),
|
primary key (server, id),
|
||||||
constraint nmapsets_id_uindex
|
constraint nmapsets_id_uindex
|
||||||
unique (id)
|
unique (id)
|
||||||
);
|
);
|
||||||
|
|
||||||
create table map_requests
|
create table map_requests
|
||||||
(
|
(
|
||||||
id int auto_increment
|
id int auto_increment
|
||||||
primary key,
|
primary key,
|
||||||
map_id int not null,
|
map_id int not null,
|
||||||
player_id int not null,
|
player_id int not null,
|
||||||
datetime datetime not null,
|
datetime datetime not null,
|
||||||
active tinyint(1) not null
|
active tinyint(1) not null
|
||||||
);
|
);
|
||||||
|
|
||||||
create table performance_reports
|
create table performance_reports
|
||||||
(
|
(
|
||||||
scoreid bigint(20) unsigned not null,
|
scoreid bigint(20) unsigned not null,
|
||||||
mod_mode enum('vanilla', 'relax', 'autopilot') default 'vanilla' not null,
|
mod_mode enum('vanilla', 'relax', 'autopilot') default 'vanilla' not null,
|
||||||
os varchar(64) not null,
|
os varchar(64) not null,
|
||||||
fullscreen tinyint(1) not null,
|
fullscreen tinyint(1) not null,
|
||||||
fps_cap varchar(16) not null,
|
fps_cap varchar(16) not null,
|
||||||
compatibility tinyint(1) not null,
|
compatibility tinyint(1) not null,
|
||||||
version varchar(16) not null,
|
version varchar(16) not null,
|
||||||
start_time int not null,
|
start_time int not null,
|
||||||
end_time int not null,
|
end_time int not null,
|
||||||
frame_count int not null,
|
frame_count int not null,
|
||||||
spike_frames int not null,
|
spike_frames int not null,
|
||||||
aim_rate int not null,
|
aim_rate int not null,
|
||||||
completion tinyint(1) not null,
|
completion tinyint(1) not null,
|
||||||
identifier varchar(128) null comment 'really don''t know much about this yet',
|
identifier varchar(128) null comment 'really don''t know much about this yet',
|
||||||
average_frametime int not null,
|
average_frametime int not null,
|
||||||
primary key (scoreid, mod_mode)
|
primary key (scoreid, mod_mode)
|
||||||
);
|
);
|
||||||
|
|
||||||
create table ratings
|
create table ratings
|
||||||
(
|
(
|
||||||
userid int not null,
|
userid int not null,
|
||||||
map_md5 char(32) not null,
|
map_md5 char(32) not null,
|
||||||
rating tinyint(2) not null,
|
rating tinyint(2) not null,
|
||||||
primary key (userid, map_md5)
|
primary key (userid, map_md5)
|
||||||
);
|
);
|
||||||
|
|
||||||
create table scores
|
create table scores
|
||||||
(
|
(
|
||||||
id bigint unsigned auto_increment
|
id bigint unsigned auto_increment
|
||||||
primary key,
|
primary key,
|
||||||
map_md5 char(32) not null,
|
map_md5 char(32) not null,
|
||||||
score int not null,
|
score int not null,
|
||||||
pp float(7,3) not null,
|
pp float(7,3) not null,
|
||||||
acc float(6,3) not null,
|
acc float(6,3) not null,
|
||||||
max_combo int not null,
|
max_combo int not null,
|
||||||
mods int not null,
|
mods int not null,
|
||||||
n300 int not null,
|
n300 int not null,
|
||||||
n100 int not null,
|
n100 int not null,
|
||||||
n50 int not null,
|
n50 int not null,
|
||||||
nmiss int not null,
|
nmiss int not null,
|
||||||
ngeki int not null,
|
ngeki int not null,
|
||||||
nkatu int not null,
|
nkatu int not null,
|
||||||
grade varchar(2) default 'N' not null,
|
grade varchar(2) default 'N' not null,
|
||||||
status tinyint not null,
|
status tinyint not null,
|
||||||
mode tinyint not null,
|
mode tinyint not null,
|
||||||
play_time datetime not null,
|
play_time datetime not null,
|
||||||
time_elapsed int not null,
|
time_elapsed int not null,
|
||||||
client_flags int not null,
|
client_flags int not null,
|
||||||
userid int not null,
|
userid int not null,
|
||||||
perfect tinyint(1) not null,
|
perfect tinyint(1) not null,
|
||||||
online_checksum char(32) not null
|
online_checksum char(32) not null
|
||||||
);
|
);
|
||||||
create index scores_map_md5_index
|
create index scores_map_md5_index
|
||||||
on scores (map_md5);
|
on scores (map_md5);
|
||||||
create index scores_score_index
|
create index scores_score_index
|
||||||
on scores (score);
|
on scores (score);
|
||||||
create index scores_pp_index
|
create index scores_pp_index
|
||||||
on scores (pp);
|
on scores (pp);
|
||||||
create index scores_mods_index
|
create index scores_mods_index
|
||||||
on scores (mods);
|
on scores (mods);
|
||||||
create index scores_status_index
|
create index scores_status_index
|
||||||
on scores (status);
|
on scores (status);
|
||||||
create index scores_mode_index
|
create index scores_mode_index
|
||||||
on scores (mode);
|
on scores (mode);
|
||||||
create index scores_play_time_index
|
create index scores_play_time_index
|
||||||
on scores (play_time);
|
on scores (play_time);
|
||||||
create index scores_userid_index
|
create index scores_userid_index
|
||||||
on scores (userid);
|
on scores (userid);
|
||||||
create index scores_online_checksum_index
|
create index scores_online_checksum_index
|
||||||
on scores (online_checksum);
|
on scores (online_checksum);
|
||||||
create index scores_fetch_leaderboard_generic_index
|
create index scores_fetch_leaderboard_generic_index
|
||||||
on scores (map_md5, status, mode);
|
on scores (map_md5, status, mode);
|
||||||
|
|
||||||
create table startups
|
create table startups
|
||||||
(
|
(
|
||||||
id int auto_increment
|
id int auto_increment
|
||||||
primary key,
|
primary key,
|
||||||
ver_major tinyint not null,
|
ver_major tinyint not null,
|
||||||
ver_minor tinyint not null,
|
ver_minor tinyint not null,
|
||||||
ver_micro tinyint not null,
|
ver_micro tinyint not null,
|
||||||
datetime datetime not null
|
datetime datetime not null
|
||||||
);
|
);
|
||||||
|
|
||||||
create table stats
|
create table stats
|
||||||
(
|
(
|
||||||
id int auto_increment,
|
id int auto_increment,
|
||||||
mode tinyint(1) not null,
|
mode tinyint(1) not null,
|
||||||
tscore bigint unsigned default 0 not null,
|
tscore bigint unsigned default 0 not null,
|
||||||
rscore bigint unsigned default 0 not null,
|
rscore bigint unsigned default 0 not null,
|
||||||
pp int unsigned default 0 not null,
|
pp int unsigned default 0 not null,
|
||||||
plays int unsigned default 0 not null,
|
plays int unsigned default 0 not null,
|
||||||
playtime int unsigned default 0 not null,
|
playtime int unsigned default 0 not null,
|
||||||
acc float(6,3) default 0.000 not null,
|
acc float(6,3) default 0.000 not null,
|
||||||
max_combo int unsigned default 0 not null,
|
max_combo int unsigned default 0 not null,
|
||||||
total_hits int unsigned default 0 not null,
|
total_hits int unsigned default 0 not null,
|
||||||
replay_views int unsigned default 0 not null,
|
replay_views int unsigned default 0 not null,
|
||||||
xh_count int unsigned default 0 not null,
|
xh_count int unsigned default 0 not null,
|
||||||
x_count int unsigned default 0 not null,
|
x_count int unsigned default 0 not null,
|
||||||
sh_count int unsigned default 0 not null,
|
sh_count int unsigned default 0 not null,
|
||||||
s_count int unsigned default 0 not null,
|
s_count int unsigned default 0 not null,
|
||||||
a_count int unsigned default 0 not null,
|
a_count int unsigned default 0 not null,
|
||||||
primary key (id, mode)
|
primary key (id, mode)
|
||||||
);
|
);
|
||||||
create index stats_mode_index
|
create index stats_mode_index
|
||||||
on stats (mode);
|
on stats (mode);
|
||||||
create index stats_pp_index
|
create index stats_pp_index
|
||||||
on stats (pp);
|
on stats (pp);
|
||||||
create index stats_tscore_index
|
create index stats_tscore_index
|
||||||
on stats (tscore);
|
on stats (tscore);
|
||||||
create index stats_rscore_index
|
create index stats_rscore_index
|
||||||
on stats (rscore);
|
on stats (rscore);
|
||||||
|
|
||||||
create table tourney_pool_maps
|
create table tourney_pool_maps
|
||||||
(
|
(
|
||||||
map_id int not null,
|
map_id int not null,
|
||||||
pool_id int not null,
|
pool_id int not null,
|
||||||
mods int not null,
|
mods int not null,
|
||||||
slot tinyint not null,
|
slot tinyint not null,
|
||||||
primary key (map_id, pool_id)
|
primary key (map_id, pool_id)
|
||||||
);
|
);
|
||||||
create index tourney_pool_maps_mods_slot_index
|
create index tourney_pool_maps_mods_slot_index
|
||||||
on tourney_pool_maps (mods, slot);
|
on tourney_pool_maps (mods, slot);
|
||||||
create index tourney_pool_maps_tourney_pools_id_fk
|
create index tourney_pool_maps_tourney_pools_id_fk
|
||||||
on tourney_pool_maps (pool_id);
|
on tourney_pool_maps (pool_id);
|
||||||
|
|
||||||
create table tourney_pools
|
create table tourney_pools
|
||||||
(
|
(
|
||||||
id int auto_increment
|
id int auto_increment
|
||||||
primary key,
|
primary key,
|
||||||
name varchar(16) not null,
|
name varchar(16) not null,
|
||||||
created_at datetime not null,
|
created_at datetime not null,
|
||||||
created_by int not null
|
created_by int not null
|
||||||
);
|
);
|
||||||
|
|
||||||
create index tourney_pools_users_id_fk
|
create index tourney_pools_users_id_fk
|
||||||
on tourney_pools (created_by);
|
on tourney_pools (created_by);
|
||||||
|
|
||||||
create table user_achievements
|
create table user_achievements
|
||||||
(
|
(
|
||||||
userid int not null,
|
userid int not null,
|
||||||
achid int not null,
|
achid int not null,
|
||||||
primary key (userid, achid)
|
primary key (userid, achid)
|
||||||
);
|
);
|
||||||
create index user_achievements_achid_index
|
create index user_achievements_achid_index
|
||||||
on user_achievements (achid);
|
on user_achievements (achid);
|
||||||
create index user_achievements_userid_index
|
create index user_achievements_userid_index
|
||||||
on user_achievements (userid);
|
on user_achievements (userid);
|
||||||
|
|
||||||
create table users
|
create table users
|
||||||
(
|
(
|
||||||
id int auto_increment
|
id int auto_increment
|
||||||
primary key,
|
primary key,
|
||||||
name varchar(32) charset utf8 not null,
|
name varchar(32) charset utf8 not null,
|
||||||
safe_name varchar(32) charset utf8 not null,
|
safe_name varchar(32) charset utf8 not null,
|
||||||
email varchar(254) not null,
|
email varchar(254) not null,
|
||||||
priv int default 1 not null,
|
priv int default 1 not null,
|
||||||
pw_bcrypt char(60) not null,
|
pw_bcrypt char(60) not null,
|
||||||
country char(2) default 'xx' not null,
|
country char(2) default 'xx' not null,
|
||||||
silence_end int default 0 not null,
|
silence_end int default 0 not null,
|
||||||
donor_end int default 0 not null,
|
donor_end int default 0 not null,
|
||||||
creation_time int default 0 not null,
|
creation_time int default 0 not null,
|
||||||
latest_activity int default 0 not null,
|
latest_activity int default 0 not null,
|
||||||
clan_id int default 0 not null,
|
clan_id int default 0 not null,
|
||||||
clan_priv tinyint(1) default 0 not null,
|
clan_priv tinyint(1) default 0 not null,
|
||||||
preferred_mode int default 0 not null,
|
preferred_mode int default 0 not null,
|
||||||
play_style int default 0 not null,
|
play_style int default 0 not null,
|
||||||
custom_badge_name varchar(16) charset utf8 null,
|
custom_badge_name varchar(16) charset utf8 null,
|
||||||
custom_badge_icon varchar(64) null,
|
custom_badge_icon varchar(64) null,
|
||||||
userpage_content varchar(2048) charset utf8 null,
|
userpage_content varchar(2048) charset utf8 null,
|
||||||
api_key char(36) null,
|
api_key char(36) null,
|
||||||
constraint users_api_key_uindex
|
constraint users_api_key_uindex
|
||||||
unique (api_key),
|
unique (api_key),
|
||||||
constraint users_email_uindex
|
constraint users_email_uindex
|
||||||
unique (email),
|
unique (email),
|
||||||
constraint users_name_uindex
|
constraint users_name_uindex
|
||||||
unique (name),
|
unique (name),
|
||||||
constraint users_safe_name_uindex
|
constraint users_safe_name_uindex
|
||||||
unique (safe_name)
|
unique (safe_name)
|
||||||
);
|
);
|
||||||
create index users_priv_index
|
create index users_priv_index
|
||||||
on users (priv);
|
on users (priv);
|
||||||
create index users_clan_id_index
|
create index users_clan_id_index
|
||||||
on users (clan_id);
|
on users (clan_id);
|
||||||
create index users_clan_priv_index
|
create index users_clan_priv_index
|
||||||
on users (clan_priv);
|
on users (clan_priv);
|
||||||
create index users_country_index
|
create index users_country_index
|
||||||
on users (country);
|
on users (country);
|
||||||
|
|
||||||
insert into users (id, name, safe_name, priv, country, silence_end, email, pw_bcrypt, creation_time, latest_activity)
|
insert into users (id, name, safe_name, priv, country, silence_end, email, pw_bcrypt, creation_time, latest_activity)
|
||||||
values (1, 'BanchoBot', 'banchobot', 1, 'ca', 0, 'bot@akatsuki.pw',
|
values (1, 'BanchoBot', 'banchobot', 1, 'ca', 0, 'bot@akatsuki.pw',
|
||||||
'_______________________my_cool_bcrypt_______________________', UNIX_TIMESTAMP(), UNIX_TIMESTAMP());
|
'_______________________my_cool_bcrypt_______________________', UNIX_TIMESTAMP(), UNIX_TIMESTAMP());
|
||||||
|
|
||||||
INSERT INTO stats (id, mode) VALUES (1, 0); # vn!std
|
INSERT INTO stats (id, mode) VALUES (1, 0); # vn!std
|
||||||
INSERT INTO stats (id, mode) VALUES (1, 1); # vn!taiko
|
INSERT INTO stats (id, mode) VALUES (1, 1); # vn!taiko
|
||||||
INSERT INTO stats (id, mode) VALUES (1, 2); # vn!catch
|
INSERT INTO stats (id, mode) VALUES (1, 2); # vn!catch
|
||||||
INSERT INTO stats (id, mode) VALUES (1, 3); # vn!mania
|
INSERT INTO stats (id, mode) VALUES (1, 3); # vn!mania
|
||||||
INSERT INTO stats (id, mode) VALUES (1, 4); # rx!std
|
INSERT INTO stats (id, mode) VALUES (1, 4); # rx!std
|
||||||
INSERT INTO stats (id, mode) VALUES (1, 5); # rx!taiko
|
INSERT INTO stats (id, mode) VALUES (1, 5); # rx!taiko
|
||||||
INSERT INTO stats (id, mode) VALUES (1, 6); # rx!catch
|
INSERT INTO stats (id, mode) VALUES (1, 6); # rx!catch
|
||||||
INSERT INTO stats (id, mode) VALUES (1, 8); # ap!std
|
INSERT INTO stats (id, mode) VALUES (1, 8); # ap!std
|
||||||
|
|
||||||
|
|
||||||
# userid 2 is reserved for ppy in osu!, and the
|
# userid 2 is reserved for ppy in osu!, and the
|
||||||
# client will not allow users to pm this id.
|
# client will not allow users to pm this id.
|
||||||
# If you want this, simply remove these two lines.
|
# If you want this, simply remove these two lines.
|
||||||
alter table users auto_increment = 3;
|
alter table users auto_increment = 3;
|
||||||
alter table stats auto_increment = 3;
|
alter table stats auto_increment = 3;
|
||||||
|
|
||||||
insert into channels (name, topic, read_priv, write_priv, auto_join)
|
insert into channels (name, topic, read_priv, write_priv, auto_join)
|
||||||
values ('#osu', 'General discussion.', 1, 2, true),
|
values ('#osu', 'General discussion.', 1, 2, true),
|
||||||
('#announce', 'Exemplary performance and public announcements.', 1, 24576, true),
|
('#announce', 'Exemplary performance and public announcements.', 1, 24576, true),
|
||||||
('#lobby', 'Multiplayer lobby discussion room.', 1, 2, false),
|
('#lobby', 'Multiplayer lobby discussion room.', 1, 2, false),
|
||||||
('#supporter', 'General discussion for supporters.', 48, 48, false),
|
('#supporter', 'General discussion for supporters.', 48, 48, false),
|
||||||
('#staff', 'General discussion for staff members.', 28672, 28672, true),
|
('#staff', 'General discussion for staff members.', 28672, 28672, true),
|
||||||
('#admin', 'General discussion for administrators.', 24576, 24576, true),
|
('#admin', 'General discussion for administrators.', 24576, 24576, true),
|
||||||
('#dev', 'General discussion for developers.', 16384, 16384, true);
|
('#dev', 'General discussion for developers.', 16384, 16384, true);
|
||||||
|
|
||||||
insert into achievements (id, file, name, `desc`, cond) values (1, 'osu-skill-pass-1', 'Rising Star', 'Can''t go forward without the first steps.', '(score.mods & 1 == 0) and 1 <= score.sr < 2 and mode_vn == 0');
|
insert into achievements (id, file, name, `desc`, cond) values (1, 'osu-skill-pass-1', 'Rising Star', 'Can''t go forward without the first steps.', '(score.mods & 1 == 0) and 1 <= score.sr < 2 and mode_vn == 0');
|
||||||
insert into achievements (id, file, name, `desc`, cond) values (2, 'osu-skill-pass-2', 'Constellation Prize', 'Definitely not a consolation prize. Now things start getting hard!', '(score.mods & 1 == 0) and 2 <= score.sr < 3 and mode_vn == 0');
|
insert into achievements (id, file, name, `desc`, cond) values (2, 'osu-skill-pass-2', 'Constellation Prize', 'Definitely not a consolation prize. Now things start getting hard!', '(score.mods & 1 == 0) and 2 <= score.sr < 3 and mode_vn == 0');
|
||||||
insert into achievements (id, file, name, `desc`, cond) values (3, 'osu-skill-pass-3', 'Building Confidence', 'Oh, you''ve SO got this.', '(score.mods & 1 == 0) and 3 <= score.sr < 4 and mode_vn == 0');
|
insert into achievements (id, file, name, `desc`, cond) values (3, 'osu-skill-pass-3', 'Building Confidence', 'Oh, you''ve SO got this.', '(score.mods & 1 == 0) and 3 <= score.sr < 4 and mode_vn == 0');
|
||||||
insert into achievements (id, file, name, `desc`, cond) values (4, 'osu-skill-pass-4', 'Insanity Approaches', 'You''re not twitching, you''re just ready.', '(score.mods & 1 == 0) and 4 <= score.sr < 5 and mode_vn == 0');
|
insert into achievements (id, file, name, `desc`, cond) values (4, 'osu-skill-pass-4', 'Insanity Approaches', 'You''re not twitching, you''re just ready.', '(score.mods & 1 == 0) and 4 <= score.sr < 5 and mode_vn == 0');
|
||||||
insert into achievements (id, file, name, `desc`, cond) values (5, 'osu-skill-pass-5', 'These Clarion Skies', 'Everything seems so clear now.', '(score.mods & 1 == 0) and 5 <= score.sr < 6 and mode_vn == 0');
|
insert into achievements (id, file, name, `desc`, cond) values (5, 'osu-skill-pass-5', 'These Clarion Skies', 'Everything seems so clear now.', '(score.mods & 1 == 0) and 5 <= score.sr < 6 and mode_vn == 0');
|
||||||
insert into achievements (id, file, name, `desc`, cond) values (6, 'osu-skill-pass-6', 'Above and Beyond', 'A cut above the rest.', '(score.mods & 1 == 0) and 6 <= score.sr < 7 and mode_vn == 0');
|
insert into achievements (id, file, name, `desc`, cond) values (6, 'osu-skill-pass-6', 'Above and Beyond', 'A cut above the rest.', '(score.mods & 1 == 0) and 6 <= score.sr < 7 and mode_vn == 0');
|
||||||
insert into achievements (id, file, name, `desc`, cond) values (7, 'osu-skill-pass-7', 'Supremacy', 'All marvel before your prowess.', '(score.mods & 1 == 0) and 7 <= score.sr < 8 and mode_vn == 0');
|
insert into achievements (id, file, name, `desc`, cond) values (7, 'osu-skill-pass-7', 'Supremacy', 'All marvel before your prowess.', '(score.mods & 1 == 0) and 7 <= score.sr < 8 and mode_vn == 0');
|
||||||
insert into achievements (id, file, name, `desc`, cond) values (8, 'osu-skill-pass-8', 'Absolution', 'My god, you''re full of stars!', '(score.mods & 1 == 0) and 8 <= score.sr < 9 and mode_vn == 0');
|
insert into achievements (id, file, name, `desc`, cond) values (8, 'osu-skill-pass-8', 'Absolution', 'My god, you''re full of stars!', '(score.mods & 1 == 0) and 8 <= score.sr < 9 and mode_vn == 0');
|
||||||
insert into achievements (id, file, name, `desc`, cond) values (9, 'osu-skill-pass-9', 'Event Horizon', 'No force dares to pull you under.', '(score.mods & 1 == 0) and 9 <= score.sr < 10 and mode_vn == 0');
|
insert into achievements (id, file, name, `desc`, cond) values (9, 'osu-skill-pass-9', 'Event Horizon', 'No force dares to pull you under.', '(score.mods & 1 == 0) and 9 <= score.sr < 10 and mode_vn == 0');
|
||||||
insert into achievements (id, file, name, `desc`, cond) values (10, 'osu-skill-pass-10', 'Phantasm', 'Fevered is your passion, extraordinary is your skill.', '(score.mods & 1 == 0) and 10 <= score.sr < 11 and mode_vn == 0');
|
insert into achievements (id, file, name, `desc`, cond) values (10, 'osu-skill-pass-10', 'Phantasm', 'Fevered is your passion, extraordinary is your skill.', '(score.mods & 1 == 0) and 10 <= score.sr < 11 and mode_vn == 0');
|
||||||
insert into achievements (id, file, name, `desc`, cond) values (11, 'osu-skill-fc-1', 'Totality', 'All the notes. Every single one.', 'score.perfect and 1 <= score.sr < 2 and mode_vn == 0');
|
insert into achievements (id, file, name, `desc`, cond) values (11, 'osu-skill-fc-1', 'Totality', 'All the notes. Every single one.', 'score.perfect and 1 <= score.sr < 2 and mode_vn == 0');
|
||||||
insert into achievements (id, file, name, `desc`, cond) values (12, 'osu-skill-fc-2', 'Business As Usual', 'Two to go, please.', 'score.perfect and 2 <= score.sr < 3 and mode_vn == 0');
|
insert into achievements (id, file, name, `desc`, cond) values (12, 'osu-skill-fc-2', 'Business As Usual', 'Two to go, please.', 'score.perfect and 2 <= score.sr < 3 and mode_vn == 0');
|
||||||
insert into achievements (id, file, name, `desc`, cond) values (13, 'osu-skill-fc-3', 'Building Steam', 'Hey, this isn''t so bad.', 'score.perfect and 3 <= score.sr < 4 and mode_vn == 0');
|
insert into achievements (id, file, name, `desc`, cond) values (13, 'osu-skill-fc-3', 'Building Steam', 'Hey, this isn''t so bad.', 'score.perfect and 3 <= score.sr < 4 and mode_vn == 0');
|
||||||
insert into achievements (id, file, name, `desc`, cond) values (14, 'osu-skill-fc-4', 'Moving Forward', 'Bet you feel good about that.', 'score.perfect and 4 <= score.sr < 5 and mode_vn == 0');
|
insert into achievements (id, file, name, `desc`, cond) values (14, 'osu-skill-fc-4', 'Moving Forward', 'Bet you feel good about that.', 'score.perfect and 4 <= score.sr < 5 and mode_vn == 0');
|
||||||
insert into achievements (id, file, name, `desc`, cond) values (15, 'osu-skill-fc-5', 'Paradigm Shift', 'Surprisingly difficult.', 'score.perfect and 5 <= score.sr < 6 and mode_vn == 0');
|
insert into achievements (id, file, name, `desc`, cond) values (15, 'osu-skill-fc-5', 'Paradigm Shift', 'Surprisingly difficult.', 'score.perfect and 5 <= score.sr < 6 and mode_vn == 0');
|
||||||
insert into achievements (id, file, name, `desc`, cond) values (16, 'osu-skill-fc-6', 'Anguish Quelled', 'Don''t choke.', 'score.perfect and 6 <= score.sr < 7 and mode_vn == 0');
|
insert into achievements (id, file, name, `desc`, cond) values (16, 'osu-skill-fc-6', 'Anguish Quelled', 'Don''t choke.', 'score.perfect and 6 <= score.sr < 7 and mode_vn == 0');
|
||||||
insert into achievements (id, file, name, `desc`, cond) values (17, 'osu-skill-fc-7', 'Never Give Up', 'Excellence is its own reward.', 'score.perfect and 7 <= score.sr < 8 and mode_vn == 0');
|
insert into achievements (id, file, name, `desc`, cond) values (17, 'osu-skill-fc-7', 'Never Give Up', 'Excellence is its own reward.', 'score.perfect and 7 <= score.sr < 8 and mode_vn == 0');
|
||||||
insert into achievements (id, file, name, `desc`, cond) values (18, 'osu-skill-fc-8', 'Aberration', 'They said it couldn''t be done. They were wrong.', 'score.perfect and 8 <= score.sr < 9 and mode_vn == 0');
|
insert into achievements (id, file, name, `desc`, cond) values (18, 'osu-skill-fc-8', 'Aberration', 'They said it couldn''t be done. They were wrong.', 'score.perfect and 8 <= score.sr < 9 and mode_vn == 0');
|
||||||
insert into achievements (id, file, name, `desc`, cond) values (19, 'osu-skill-fc-9', 'Chosen', 'Reign among the Prometheans, where you belong.', 'score.perfect and 9 <= score.sr < 10 and mode_vn == 0');
|
insert into achievements (id, file, name, `desc`, cond) values (19, 'osu-skill-fc-9', 'Chosen', 'Reign among the Prometheans, where you belong.', 'score.perfect and 9 <= score.sr < 10 and mode_vn == 0');
|
||||||
insert into achievements (id, file, name, `desc`, cond) values (20, 'osu-skill-fc-10', 'Unfathomable', 'You have no equal.', 'score.perfect and 10 <= score.sr < 11 and mode_vn == 0');
|
insert into achievements (id, file, name, `desc`, cond) values (20, 'osu-skill-fc-10', 'Unfathomable', 'You have no equal.', 'score.perfect and 10 <= score.sr < 11 and mode_vn == 0');
|
||||||
insert into achievements (id, file, name, `desc`, cond) values (21, 'osu-combo-500', '500 Combo', '500 big ones! You''re moving up in the world!', '500 <= score.max_combo < 750 and mode_vn == 0');
|
insert into achievements (id, file, name, `desc`, cond) values (21, 'osu-combo-500', '500 Combo', '500 big ones! You''re moving up in the world!', '500 <= score.max_combo < 750 and mode_vn == 0');
|
||||||
insert into achievements (id, file, name, `desc`, cond) values (22, 'osu-combo-750', '750 Combo', '750 notes back to back? Woah.', '750 <= score.max_combo < 1000 and mode_vn == 0');
|
insert into achievements (id, file, name, `desc`, cond) values (22, 'osu-combo-750', '750 Combo', '750 notes back to back? Woah.', '750 <= score.max_combo < 1000 and mode_vn == 0');
|
||||||
insert into achievements (id, file, name, `desc`, cond) values (23, 'osu-combo-1000', '1000 Combo', 'A thousand reasons why you rock at this game.', '1000 <= score.max_combo < 2000 and mode_vn == 0');
|
insert into achievements (id, file, name, `desc`, cond) values (23, 'osu-combo-1000', '1000 Combo', 'A thousand reasons why you rock at this game.', '1000 <= score.max_combo < 2000 and mode_vn == 0');
|
||||||
insert into achievements (id, file, name, `desc`, cond) values (24, 'osu-combo-2000', '2000 Combo', 'Nothing can stop you now.', '2000 <= score.max_combo and mode_vn == 0');
|
insert into achievements (id, file, name, `desc`, cond) values (24, 'osu-combo-2000', '2000 Combo', 'Nothing can stop you now.', '2000 <= score.max_combo and mode_vn == 0');
|
||||||
insert into achievements (id, file, name, `desc`, cond) values (25, 'taiko-skill-pass-1', 'My First Don', 'Marching to the beat of your own drum. Literally.', '(score.mods & 1 == 0) and 1 <= score.sr < 2 and mode_vn == 1');
|
insert into achievements (id, file, name, `desc`, cond) values (25, 'taiko-skill-pass-1', 'My First Don', 'Marching to the beat of your own drum. Literally.', '(score.mods & 1 == 0) and 1 <= score.sr < 2 and mode_vn == 1');
|
||||||
insert into achievements (id, file, name, `desc`, cond) values (26, 'taiko-skill-pass-2', 'Katsu Katsu Katsu', 'Hora! Izuko!', '(score.mods & 1 == 0) and 2 <= score.sr < 3 and mode_vn == 1');
|
insert into achievements (id, file, name, `desc`, cond) values (26, 'taiko-skill-pass-2', 'Katsu Katsu Katsu', 'Hora! Izuko!', '(score.mods & 1 == 0) and 2 <= score.sr < 3 and mode_vn == 1');
|
||||||
insert into achievements (id, file, name, `desc`, cond) values (27, 'taiko-skill-pass-3', 'Not Even Trying', 'Muzukashii? Not even.', '(score.mods & 1 == 0) and 3 <= score.sr < 4 and mode_vn == 1');
|
insert into achievements (id, file, name, `desc`, cond) values (27, 'taiko-skill-pass-3', 'Not Even Trying', 'Muzukashii? Not even.', '(score.mods & 1 == 0) and 3 <= score.sr < 4 and mode_vn == 1');
|
||||||
insert into achievements (id, file, name, `desc`, cond) values (28, 'taiko-skill-pass-4', 'Face Your Demons', 'The first trials are now behind you, but are you a match for the Oni?', '(score.mods & 1 == 0) and 4 <= score.sr < 5 and mode_vn == 1');
|
insert into achievements (id, file, name, `desc`, cond) values (28, 'taiko-skill-pass-4', 'Face Your Demons', 'The first trials are now behind you, but are you a match for the Oni?', '(score.mods & 1 == 0) and 4 <= score.sr < 5 and mode_vn == 1');
|
||||||
insert into achievements (id, file, name, `desc`, cond) values (29, 'taiko-skill-pass-5', 'The Demon Within', 'No rest for the wicked.', '(score.mods & 1 == 0) and 5 <= score.sr < 6 and mode_vn == 1');
|
insert into achievements (id, file, name, `desc`, cond) values (29, 'taiko-skill-pass-5', 'The Demon Within', 'No rest for the wicked.', '(score.mods & 1 == 0) and 5 <= score.sr < 6 and mode_vn == 1');
|
||||||
insert into achievements (id, file, name, `desc`, cond) values (30, 'taiko-skill-pass-6', 'Drumbreaker', 'Too strong.', '(score.mods & 1 == 0) and 6 <= score.sr < 7 and mode_vn == 1');
|
insert into achievements (id, file, name, `desc`, cond) values (30, 'taiko-skill-pass-6', 'Drumbreaker', 'Too strong.', '(score.mods & 1 == 0) and 6 <= score.sr < 7 and mode_vn == 1');
|
||||||
insert into achievements (id, file, name, `desc`, cond) values (31, 'taiko-skill-pass-7', 'The Godfather', 'You are the Don of Dons.', '(score.mods & 1 == 0) and 7 <= score.sr < 8 and mode_vn == 1');
|
insert into achievements (id, file, name, `desc`, cond) values (31, 'taiko-skill-pass-7', 'The Godfather', 'You are the Don of Dons.', '(score.mods & 1 == 0) and 7 <= score.sr < 8 and mode_vn == 1');
|
||||||
insert into achievements (id, file, name, `desc`, cond) values (32, 'taiko-skill-pass-8', 'Rhythm Incarnate', 'Feel the beat. Become the beat.', '(score.mods & 1 == 0) and 8 <= score.sr < 9 and mode_vn == 1');
|
insert into achievements (id, file, name, `desc`, cond) values (32, 'taiko-skill-pass-8', 'Rhythm Incarnate', 'Feel the beat. Become the beat.', '(score.mods & 1 == 0) and 8 <= score.sr < 9 and mode_vn == 1');
|
||||||
insert into achievements (id, file, name, `desc`, cond) values (33, 'taiko-skill-fc-1', 'Keeping Time', 'Don, then katsu. Don, then katsu..', 'score.perfect and 1 <= score.sr < 2 and mode_vn == 1');
|
insert into achievements (id, file, name, `desc`, cond) values (33, 'taiko-skill-fc-1', 'Keeping Time', 'Don, then katsu. Don, then katsu..', 'score.perfect and 1 <= score.sr < 2 and mode_vn == 1');
|
||||||
insert into achievements (id, file, name, `desc`, cond) values (34, 'taiko-skill-fc-2', 'To Your Own Beat', 'Straight and steady.', 'score.perfect and 2 <= score.sr < 3 and mode_vn == 1');
|
insert into achievements (id, file, name, `desc`, cond) values (34, 'taiko-skill-fc-2', 'To Your Own Beat', 'Straight and steady.', 'score.perfect and 2 <= score.sr < 3 and mode_vn == 1');
|
||||||
insert into achievements (id, file, name, `desc`, cond) values (35, 'taiko-skill-fc-3', 'Big Drums', 'Bigger scores to match.', 'score.perfect and 3 <= score.sr < 4 and mode_vn == 1');
|
insert into achievements (id, file, name, `desc`, cond) values (35, 'taiko-skill-fc-3', 'Big Drums', 'Bigger scores to match.', 'score.perfect and 3 <= score.sr < 4 and mode_vn == 1');
|
||||||
insert into achievements (id, file, name, `desc`, cond) values (36, 'taiko-skill-fc-4', 'Adversity Overcome', 'Difficult? Not for you.', 'score.perfect and 4 <= score.sr < 5 and mode_vn == 1');
|
insert into achievements (id, file, name, `desc`, cond) values (36, 'taiko-skill-fc-4', 'Adversity Overcome', 'Difficult? Not for you.', 'score.perfect and 4 <= score.sr < 5 and mode_vn == 1');
|
||||||
insert into achievements (id, file, name, `desc`, cond) values (37, 'taiko-skill-fc-5', 'Demonslayer', 'An Oni felled forevermore.', 'score.perfect and 5 <= score.sr < 6 and mode_vn == 1');
|
insert into achievements (id, file, name, `desc`, cond) values (37, 'taiko-skill-fc-5', 'Demonslayer', 'An Oni felled forevermore.', 'score.perfect and 5 <= score.sr < 6 and mode_vn == 1');
|
||||||
insert into achievements (id, file, name, `desc`, cond) values (38, 'taiko-skill-fc-6', 'Rhythm''s Call', 'Heralding true skill.', 'score.perfect and 6 <= score.sr < 7 and mode_vn == 1');
|
insert into achievements (id, file, name, `desc`, cond) values (38, 'taiko-skill-fc-6', 'Rhythm''s Call', 'Heralding true skill.', 'score.perfect and 6 <= score.sr < 7 and mode_vn == 1');
|
||||||
insert into achievements (id, file, name, `desc`, cond) values (39, 'taiko-skill-fc-7', 'Time Everlasting', 'Not a single beat escapes you.', 'score.perfect and 7 <= score.sr < 8 and mode_vn == 1');
|
insert into achievements (id, file, name, `desc`, cond) values (39, 'taiko-skill-fc-7', 'Time Everlasting', 'Not a single beat escapes you.', 'score.perfect and 7 <= score.sr < 8 and mode_vn == 1');
|
||||||
insert into achievements (id, file, name, `desc`, cond) values (40, 'taiko-skill-fc-8', 'The Drummer''s Throne', 'Percussive brilliance befitting royalty alone.', 'score.perfect and 8 <= score.sr < 9 and mode_vn == 1');
|
insert into achievements (id, file, name, `desc`, cond) values (40, 'taiko-skill-fc-8', 'The Drummer''s Throne', 'Percussive brilliance befitting royalty alone.', 'score.perfect and 8 <= score.sr < 9 and mode_vn == 1');
|
||||||
insert into achievements (id, file, name, `desc`, cond) values (41, 'fruits-skill-pass-1', 'A Slice Of Life', 'Hey, this fruit catching business isn''t bad.', '(score.mods & 1 == 0) and 1 <= score.sr < 2 and mode_vn == 2');
|
insert into achievements (id, file, name, `desc`, cond) values (41, 'fruits-skill-pass-1', 'A Slice Of Life', 'Hey, this fruit catching business isn''t bad.', '(score.mods & 1 == 0) and 1 <= score.sr < 2 and mode_vn == 2');
|
||||||
insert into achievements (id, file, name, `desc`, cond) values (42, 'fruits-skill-pass-2', 'Dashing Ever Forward', 'Fast is how you do it.', '(score.mods & 1 == 0) and 2 <= score.sr < 3 and mode_vn == 2');
|
insert into achievements (id, file, name, `desc`, cond) values (42, 'fruits-skill-pass-2', 'Dashing Ever Forward', 'Fast is how you do it.', '(score.mods & 1 == 0) and 2 <= score.sr < 3 and mode_vn == 2');
|
||||||
insert into achievements (id, file, name, `desc`, cond) values (43, 'fruits-skill-pass-3', 'Zesty Disposition', 'No scurvy for you, not with that much fruit.', '(score.mods & 1 == 0) and 3 <= score.sr < 4 and mode_vn == 2');
|
insert into achievements (id, file, name, `desc`, cond) values (43, 'fruits-skill-pass-3', 'Zesty Disposition', 'No scurvy for you, not with that much fruit.', '(score.mods & 1 == 0) and 3 <= score.sr < 4 and mode_vn == 2');
|
||||||
insert into achievements (id, file, name, `desc`, cond) values (44, 'fruits-skill-pass-4', 'Hyperdash ON!', 'Time and distance is no obstacle to you.', '(score.mods & 1 == 0) and 4 <= score.sr < 5 and mode_vn == 2');
|
insert into achievements (id, file, name, `desc`, cond) values (44, 'fruits-skill-pass-4', 'Hyperdash ON!', 'Time and distance is no obstacle to you.', '(score.mods & 1 == 0) and 4 <= score.sr < 5 and mode_vn == 2');
|
||||||
insert into achievements (id, file, name, `desc`, cond) values (45, 'fruits-skill-pass-5', 'It''s Raining Fruit', 'And you can catch them all.', '(score.mods & 1 == 0) and 5 <= score.sr < 6 and mode_vn == 2');
|
insert into achievements (id, file, name, `desc`, cond) values (45, 'fruits-skill-pass-5', 'It''s Raining Fruit', 'And you can catch them all.', '(score.mods & 1 == 0) and 5 <= score.sr < 6 and mode_vn == 2');
|
||||||
insert into achievements (id, file, name, `desc`, cond) values (46, 'fruits-skill-pass-6', 'Fruit Ninja', 'Legendary techniques.', '(score.mods & 1 == 0) and 6 <= score.sr < 7 and mode_vn == 2');
|
insert into achievements (id, file, name, `desc`, cond) values (46, 'fruits-skill-pass-6', 'Fruit Ninja', 'Legendary techniques.', '(score.mods & 1 == 0) and 6 <= score.sr < 7 and mode_vn == 2');
|
||||||
insert into achievements (id, file, name, `desc`, cond) values (47, 'fruits-skill-pass-7', 'Dreamcatcher', 'No fruit, only dreams now.', '(score.mods & 1 == 0) and 7 <= score.sr < 8 and mode_vn == 2');
|
insert into achievements (id, file, name, `desc`, cond) values (47, 'fruits-skill-pass-7', 'Dreamcatcher', 'No fruit, only dreams now.', '(score.mods & 1 == 0) and 7 <= score.sr < 8 and mode_vn == 2');
|
||||||
insert into achievements (id, file, name, `desc`, cond) values (48, 'fruits-skill-pass-8', 'Lord of the Catch', 'Your kingdom kneels before you.', '(score.mods & 1 == 0) and 8 <= score.sr < 9 and mode_vn == 2');
|
insert into achievements (id, file, name, `desc`, cond) values (48, 'fruits-skill-pass-8', 'Lord of the Catch', 'Your kingdom kneels before you.', '(score.mods & 1 == 0) and 8 <= score.sr < 9 and mode_vn == 2');
|
||||||
insert into achievements (id, file, name, `desc`, cond) values (49, 'fruits-skill-fc-1', 'Sweet And Sour', 'Apples and oranges, literally.', 'score.perfect and 1 <= score.sr < 2 and mode_vn == 2');
|
insert into achievements (id, file, name, `desc`, cond) values (49, 'fruits-skill-fc-1', 'Sweet And Sour', 'Apples and oranges, literally.', 'score.perfect and 1 <= score.sr < 2 and mode_vn == 2');
|
||||||
insert into achievements (id, file, name, `desc`, cond) values (50, 'fruits-skill-fc-2', 'Reaching The Core', 'The seeds of future success.', 'score.perfect and 2 <= score.sr < 3 and mode_vn == 2');
|
insert into achievements (id, file, name, `desc`, cond) values (50, 'fruits-skill-fc-2', 'Reaching The Core', 'The seeds of future success.', 'score.perfect and 2 <= score.sr < 3 and mode_vn == 2');
|
||||||
insert into achievements (id, file, name, `desc`, cond) values (51, 'fruits-skill-fc-3', 'Clean Platter', 'Clean only of failure. It is completely full, otherwise.', 'score.perfect and 3 <= score.sr < 4 and mode_vn == 2');
|
insert into achievements (id, file, name, `desc`, cond) values (51, 'fruits-skill-fc-3', 'Clean Platter', 'Clean only of failure. It is completely full, otherwise.', 'score.perfect and 3 <= score.sr < 4 and mode_vn == 2');
|
||||||
insert into achievements (id, file, name, `desc`, cond) values (52, 'fruits-skill-fc-4', 'Between The Rain', 'No umbrella needed.', 'score.perfect and 4 <= score.sr < 5 and mode_vn == 2');
|
insert into achievements (id, file, name, `desc`, cond) values (52, 'fruits-skill-fc-4', 'Between The Rain', 'No umbrella needed.', 'score.perfect and 4 <= score.sr < 5 and mode_vn == 2');
|
||||||
insert into achievements (id, file, name, `desc`, cond) values (53, 'fruits-skill-fc-5', 'Addicted', 'That was an overdose?', 'score.perfect and 5 <= score.sr < 6 and mode_vn == 2');
|
insert into achievements (id, file, name, `desc`, cond) values (53, 'fruits-skill-fc-5', 'Addicted', 'That was an overdose?', 'score.perfect and 5 <= score.sr < 6 and mode_vn == 2');
|
||||||
insert into achievements (id, file, name, `desc`, cond) values (54, 'fruits-skill-fc-6', 'Quickening', 'A dash above normal limits.', 'score.perfect and 6 <= score.sr < 7 and mode_vn == 2');
|
insert into achievements (id, file, name, `desc`, cond) values (54, 'fruits-skill-fc-6', 'Quickening', 'A dash above normal limits.', 'score.perfect and 6 <= score.sr < 7 and mode_vn == 2');
|
||||||
insert into achievements (id, file, name, `desc`, cond) values (55, 'fruits-skill-fc-7', 'Supersonic', 'Faster than is reasonably necessary.', 'score.perfect and 7 <= score.sr < 8 and mode_vn == 2');
|
insert into achievements (id, file, name, `desc`, cond) values (55, 'fruits-skill-fc-7', 'Supersonic', 'Faster than is reasonably necessary.', 'score.perfect and 7 <= score.sr < 8 and mode_vn == 2');
|
||||||
insert into achievements (id, file, name, `desc`, cond) values (56, 'fruits-skill-fc-8', 'Dashing Scarlet', 'Speed beyond mortal reckoning.', 'score.perfect and 8 <= score.sr < 9 and mode_vn == 2');
|
insert into achievements (id, file, name, `desc`, cond) values (56, 'fruits-skill-fc-8', 'Dashing Scarlet', 'Speed beyond mortal reckoning.', 'score.perfect and 8 <= score.sr < 9 and mode_vn == 2');
|
||||||
insert into achievements (id, file, name, `desc`, cond) values (57, 'mania-skill-pass-1', 'First Steps', 'It isn''t 9-to-5, but 1-to-9. Keys, that is.', '(score.mods & 1 == 0) and 1 <= score.sr < 2 and mode_vn == 3');
|
insert into achievements (id, file, name, `desc`, cond) values (57, 'mania-skill-pass-1', 'First Steps', 'It isn''t 9-to-5, but 1-to-9. Keys, that is.', '(score.mods & 1 == 0) and 1 <= score.sr < 2 and mode_vn == 3');
|
||||||
insert into achievements (id, file, name, `desc`, cond) values (58, 'mania-skill-pass-2', 'No Normal Player', 'Not anymore, at least.', '(score.mods & 1 == 0) and 2 <= score.sr < 3 and mode_vn == 3');
|
insert into achievements (id, file, name, `desc`, cond) values (58, 'mania-skill-pass-2', 'No Normal Player', 'Not anymore, at least.', '(score.mods & 1 == 0) and 2 <= score.sr < 3 and mode_vn == 3');
|
||||||
insert into achievements (id, file, name, `desc`, cond) values (59, 'mania-skill-pass-3', 'Impulse Drive', 'Not quite hyperspeed, but getting close.', '(score.mods & 1 == 0) and 3 <= score.sr < 4 and mode_vn == 3');
|
insert into achievements (id, file, name, `desc`, cond) values (59, 'mania-skill-pass-3', 'Impulse Drive', 'Not quite hyperspeed, but getting close.', '(score.mods & 1 == 0) and 3 <= score.sr < 4 and mode_vn == 3');
|
||||||
insert into achievements (id, file, name, `desc`, cond) values (60, 'mania-skill-pass-4', 'Hyperspeed', 'Woah.', '(score.mods & 1 == 0) and 4 <= score.sr < 5 and mode_vn == 3');
|
insert into achievements (id, file, name, `desc`, cond) values (60, 'mania-skill-pass-4', 'Hyperspeed', 'Woah.', '(score.mods & 1 == 0) and 4 <= score.sr < 5 and mode_vn == 3');
|
||||||
insert into achievements (id, file, name, `desc`, cond) values (61, 'mania-skill-pass-5', 'Ever Onwards', 'Another challenge is just around the corner.', '(score.mods & 1 == 0) and 5 <= score.sr < 6 and mode_vn == 3');
|
insert into achievements (id, file, name, `desc`, cond) values (61, 'mania-skill-pass-5', 'Ever Onwards', 'Another challenge is just around the corner.', '(score.mods & 1 == 0) and 5 <= score.sr < 6 and mode_vn == 3');
|
||||||
insert into achievements (id, file, name, `desc`, cond) values (62, 'mania-skill-pass-6', 'Another Surpassed', 'Is there no limit to your skills?', '(score.mods & 1 == 0) and 6 <= score.sr < 7 and mode_vn == 3');
|
insert into achievements (id, file, name, `desc`, cond) values (62, 'mania-skill-pass-6', 'Another Surpassed', 'Is there no limit to your skills?', '(score.mods & 1 == 0) and 6 <= score.sr < 7 and mode_vn == 3');
|
||||||
insert into achievements (id, file, name, `desc`, cond) values (63, 'mania-skill-pass-7', 'Extra Credit', 'See me after class.', '(score.mods & 1 == 0) and 7 <= score.sr < 8 and mode_vn == 3');
|
insert into achievements (id, file, name, `desc`, cond) values (63, 'mania-skill-pass-7', 'Extra Credit', 'See me after class.', '(score.mods & 1 == 0) and 7 <= score.sr < 8 and mode_vn == 3');
|
||||||
insert into achievements (id, file, name, `desc`, cond) values (64, 'mania-skill-pass-8', 'Maniac', 'There''s just no stopping you.', '(score.mods & 1 == 0) and 8 <= score.sr < 9 and mode_vn == 3');
|
insert into achievements (id, file, name, `desc`, cond) values (64, 'mania-skill-pass-8', 'Maniac', 'There''s just no stopping you.', '(score.mods & 1 == 0) and 8 <= score.sr < 9 and mode_vn == 3');
|
||||||
insert into achievements (id, file, name, `desc`, cond) values (65, 'mania-skill-fc-1', 'Keystruck', 'The beginning of a new story', 'score.perfect and 1 <= score.sr < 2 and mode_vn == 3');
|
insert into achievements (id, file, name, `desc`, cond) values (65, 'mania-skill-fc-1', 'Keystruck', 'The beginning of a new story', 'score.perfect and 1 <= score.sr < 2 and mode_vn == 3');
|
||||||
insert into achievements (id, file, name, `desc`, cond) values (66, 'mania-skill-fc-2', 'Keying In', 'Finding your groove.', 'score.perfect and 2 <= score.sr < 3 and mode_vn == 3');
|
insert into achievements (id, file, name, `desc`, cond) values (66, 'mania-skill-fc-2', 'Keying In', 'Finding your groove.', 'score.perfect and 2 <= score.sr < 3 and mode_vn == 3');
|
||||||
insert into achievements (id, file, name, `desc`, cond) values (67, 'mania-skill-fc-3', 'Hyperflow', 'You can *feel* the rhythm.', 'score.perfect and 3 <= score.sr < 4 and mode_vn == 3');
|
insert into achievements (id, file, name, `desc`, cond) values (67, 'mania-skill-fc-3', 'Hyperflow', 'You can *feel* the rhythm.', 'score.perfect and 3 <= score.sr < 4 and mode_vn == 3');
|
||||||
insert into achievements (id, file, name, `desc`, cond) values (68, 'mania-skill-fc-4', 'Breakthrough', 'Many skills mastered, rolled into one.', 'score.perfect and 4 <= score.sr < 5 and mode_vn == 3');
|
insert into achievements (id, file, name, `desc`, cond) values (68, 'mania-skill-fc-4', 'Breakthrough', 'Many skills mastered, rolled into one.', 'score.perfect and 4 <= score.sr < 5 and mode_vn == 3');
|
||||||
insert into achievements (id, file, name, `desc`, cond) values (69, 'mania-skill-fc-5', 'Everything Extra', 'Giving your all is giving everything you have.', 'score.perfect and 5 <= score.sr < 6 and mode_vn == 3');
|
insert into achievements (id, file, name, `desc`, cond) values (69, 'mania-skill-fc-5', 'Everything Extra', 'Giving your all is giving everything you have.', 'score.perfect and 5 <= score.sr < 6 and mode_vn == 3');
|
||||||
insert into achievements (id, file, name, `desc`, cond) values (70, 'mania-skill-fc-6', 'Level Breaker', 'Finesse beyond reason', 'score.perfect and 6 <= score.sr < 7 and mode_vn == 3');
|
insert into achievements (id, file, name, `desc`, cond) values (70, 'mania-skill-fc-6', 'Level Breaker', 'Finesse beyond reason', 'score.perfect and 6 <= score.sr < 7 and mode_vn == 3');
|
||||||
insert into achievements (id, file, name, `desc`, cond) values (71, 'mania-skill-fc-7', 'Step Up', 'A precipice rarely seen.', 'score.perfect and 7 <= score.sr < 8 and mode_vn == 3');
|
insert into achievements (id, file, name, `desc`, cond) values (71, 'mania-skill-fc-7', 'Step Up', 'A precipice rarely seen.', 'score.perfect and 7 <= score.sr < 8 and mode_vn == 3');
|
||||||
insert into achievements (id, file, name, `desc`, cond) values (72, 'mania-skill-fc-8', 'Behind The Veil', 'Supernatural!', 'score.perfect and 8 <= score.sr < 9 and mode_vn == 3');
|
insert into achievements (id, file, name, `desc`, cond) values (72, 'mania-skill-fc-8', 'Behind The Veil', 'Supernatural!', 'score.perfect and 8 <= score.sr < 9 and mode_vn == 3');
|
||||||
insert into achievements (id, file, name, `desc`, cond) values (73, 'all-intro-suddendeath', 'Finality', 'High stakes, no regrets.', 'score.mods == 32');
|
insert into achievements (id, file, name, `desc`, cond) values (73, 'all-intro-suddendeath', 'Finality', 'High stakes, no regrets.', 'score.mods == 32');
|
||||||
insert into achievements (id, file, name, `desc`, cond) values (74, 'all-intro-hidden', 'Blindsight', 'I can see just perfectly', 'score.mods & 8');
|
insert into achievements (id, file, name, `desc`, cond) values (74, 'all-intro-hidden', 'Blindsight', 'I can see just perfectly', 'score.mods & 8');
|
||||||
insert into achievements (id, file, name, `desc`, cond) values (75, 'all-intro-perfect', 'Perfectionist', 'Accept nothing but the best.', 'score.mods & 16384');
|
insert into achievements (id, file, name, `desc`, cond) values (75, 'all-intro-perfect', 'Perfectionist', 'Accept nothing but the best.', 'score.mods & 16384');
|
||||||
insert into achievements (id, file, name, `desc`, cond) values (76, 'all-intro-hardrock', 'Rock Around The Clock', "You can\'t stop the rock.", 'score.mods & 16');
|
insert into achievements (id, file, name, `desc`, cond) values (76, 'all-intro-hardrock', 'Rock Around The Clock', "You can\'t stop the rock.", 'score.mods & 16');
|
||||||
insert into achievements (id, file, name, `desc`, cond) values (77, 'all-intro-doubletime', 'Time And A Half', "Having a right ol\' time. One and a half of them, almost.", 'score.mods & 64');
|
insert into achievements (id, file, name, `desc`, cond) values (77, 'all-intro-doubletime', 'Time And A Half', "Having a right ol\' time. One and a half of them, almost.", 'score.mods & 64');
|
||||||
insert into achievements (id, file, name, `desc`, cond) values (78, 'all-intro-flashlight', 'Are You Afraid Of The Dark?', "Harder than it looks, probably because it\'s hard to look.", 'score.mods & 1024');
|
insert into achievements (id, file, name, `desc`, cond) values (78, 'all-intro-flashlight', 'Are You Afraid Of The Dark?', "Harder than it looks, probably because it\'s hard to look.", 'score.mods & 1024');
|
||||||
insert into achievements (id, file, name, `desc`, cond) values (79, 'all-intro-easy', 'Dial It Right Back', 'Sometimes you just want to take it easy.', 'score.mods & 2');
|
insert into achievements (id, file, name, `desc`, cond) values (79, 'all-intro-easy', 'Dial It Right Back', 'Sometimes you just want to take it easy.', 'score.mods & 2');
|
||||||
insert into achievements (id, file, name, `desc`, cond) values (80, 'all-intro-nofail', 'Risk Averse', 'Safety nets are fun!', 'score.mods & 1');
|
insert into achievements (id, file, name, `desc`, cond) values (80, 'all-intro-nofail', 'Risk Averse', 'Safety nets are fun!', 'score.mods & 1');
|
||||||
insert into achievements (id, file, name, `desc`, cond) values (81, 'all-intro-nightcore', 'Sweet Rave Party', 'Founded in the fine tradition of changing things that were just fine as they were.', 'score.mods & 512');
|
insert into achievements (id, file, name, `desc`, cond) values (81, 'all-intro-nightcore', 'Sweet Rave Party', 'Founded in the fine tradition of changing things that were just fine as they were.', 'score.mods & 512');
|
||||||
insert into achievements (id, file, name, `desc`, cond) values (82, 'all-intro-halftime', 'Slowboat', 'You got there. Eventually.', 'score.mods & 256');
|
insert into achievements (id, file, name, `desc`, cond) values (82, 'all-intro-halftime', 'Slowboat', 'You got there. Eventually.', 'score.mods & 256');
|
||||||
insert into achievements (id, file, name, `desc`, cond) values (83, 'all-intro-spunout', 'Burned Out', 'One cannot always spin to win.', 'score.mods & 4096');
|
insert into achievements (id, file, name, `desc`, cond) values (83, 'all-intro-spunout', 'Burned Out', 'One cannot always spin to win.', 'score.mods & 4096');
|
||||||
|
|||||||
@@ -1,209 +1,209 @@
|
|||||||
-- 自定义谱面系统迁移
|
-- 自定义谱面系统迁移
|
||||||
-- 创建自定义谱面表,与官方谱面不冲突
|
-- 创建自定义谱面表,与官方谱面不冲突
|
||||||
|
|
||||||
-- 自定义谱面集表
|
-- 自定义谱面集表
|
||||||
CREATE TABLE custom_mapsets (
|
CREATE TABLE custom_mapsets (
|
||||||
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||||
creator_id INT NOT NULL,
|
creator_id INT NOT NULL,
|
||||||
title VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
|
title VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||||
artist VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
|
artist VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||||
source VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT '',
|
source VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT '',
|
||||||
tags TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci,
|
tags TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci,
|
||||||
description TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci,
|
description TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci,
|
||||||
status ENUM('pending', 'approved', 'rejected', 'loved') DEFAULT 'pending',
|
status ENUM('pending', 'approved', 'rejected', 'loved') DEFAULT 'pending',
|
||||||
upload_date DATETIME DEFAULT CURRENT_TIMESTAMP,
|
upload_date DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||||
last_update DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
last_update DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||||
osz_filename VARCHAR(255) NOT NULL,
|
osz_filename VARCHAR(255) NOT NULL,
|
||||||
osz_hash CHAR(32) NOT NULL,
|
osz_hash CHAR(32) NOT NULL,
|
||||||
download_count INT DEFAULT 0,
|
download_count INT DEFAULT 0,
|
||||||
favourite_count INT DEFAULT 0,
|
favourite_count INT DEFAULT 0,
|
||||||
UNIQUE KEY idx_custom_mapsets_id (id),
|
UNIQUE KEY idx_custom_mapsets_id (id),
|
||||||
KEY idx_custom_mapsets_creator (creator_id),
|
KEY idx_custom_mapsets_creator (creator_id),
|
||||||
KEY idx_custom_mapsets_status (status),
|
KEY idx_custom_mapsets_status (status),
|
||||||
KEY idx_custom_mapsets_upload_date (upload_date),
|
KEY idx_custom_mapsets_upload_date (upload_date),
|
||||||
UNIQUE KEY idx_custom_mapsets_osz_hash (osz_hash)
|
UNIQUE KEY idx_custom_mapsets_osz_hash (osz_hash)
|
||||||
);
|
);
|
||||||
|
|
||||||
-- 自定义谱面难度表
|
-- 自定义谱面难度表
|
||||||
CREATE TABLE custom_maps (
|
CREATE TABLE custom_maps (
|
||||||
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||||
mapset_id BIGINT NOT NULL,
|
mapset_id BIGINT NOT NULL,
|
||||||
md5 CHAR(32) NOT NULL,
|
md5 CHAR(32) NOT NULL,
|
||||||
difficulty_name VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
|
difficulty_name VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||||
filename VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
|
filename VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||||
mode TINYINT DEFAULT 0 NOT NULL COMMENT '0=osu!, 1=taiko, 2=catch, 3=mania',
|
mode TINYINT DEFAULT 0 NOT NULL COMMENT '0=osu!, 1=taiko, 2=catch, 3=mania',
|
||||||
status ENUM('pending', 'approved', 'rejected', 'loved') DEFAULT 'pending',
|
status ENUM('pending', 'approved', 'rejected', 'loved') DEFAULT 'pending',
|
||||||
|
|
||||||
-- osu!文件基本信息
|
-- osu!文件基本信息
|
||||||
audio_filename VARCHAR(255) DEFAULT '',
|
audio_filename VARCHAR(255) DEFAULT '',
|
||||||
audio_lead_in INT DEFAULT 0,
|
audio_lead_in INT DEFAULT 0,
|
||||||
preview_time INT DEFAULT -1,
|
preview_time INT DEFAULT -1,
|
||||||
countdown TINYINT DEFAULT 1,
|
countdown TINYINT DEFAULT 1,
|
||||||
sample_set VARCHAR(16) DEFAULT 'Normal',
|
sample_set VARCHAR(16) DEFAULT 'Normal',
|
||||||
stack_leniency DECIMAL(3,2) DEFAULT 0.70,
|
stack_leniency DECIMAL(3,2) DEFAULT 0.70,
|
||||||
letterbox_in_breaks BOOLEAN DEFAULT FALSE,
|
letterbox_in_breaks BOOLEAN DEFAULT FALSE,
|
||||||
story_fire_in_front BOOLEAN DEFAULT TRUE,
|
story_fire_in_front BOOLEAN DEFAULT TRUE,
|
||||||
use_skin_sprites BOOLEAN DEFAULT FALSE,
|
use_skin_sprites BOOLEAN DEFAULT FALSE,
|
||||||
always_show_playfield BOOLEAN DEFAULT FALSE,
|
always_show_playfield BOOLEAN DEFAULT FALSE,
|
||||||
overlay_position VARCHAR(16) DEFAULT 'NoChange',
|
overlay_position VARCHAR(16) DEFAULT 'NoChange',
|
||||||
skin_preference VARCHAR(255) DEFAULT '',
|
skin_preference VARCHAR(255) DEFAULT '',
|
||||||
epilepsy_warning BOOLEAN DEFAULT FALSE,
|
epilepsy_warning BOOLEAN DEFAULT FALSE,
|
||||||
countdown_offset INT DEFAULT 0,
|
countdown_offset INT DEFAULT 0,
|
||||||
special_style BOOLEAN DEFAULT FALSE,
|
special_style BOOLEAN DEFAULT FALSE,
|
||||||
widescreen_storyboard BOOLEAN DEFAULT FALSE,
|
widescreen_storyboard BOOLEAN DEFAULT FALSE,
|
||||||
samples_match_playback_rate BOOLEAN DEFAULT FALSE,
|
samples_match_playback_rate BOOLEAN DEFAULT FALSE,
|
||||||
|
|
||||||
-- 编辑器信息
|
-- 编辑器信息
|
||||||
distance_spacing DECIMAL(6,3) DEFAULT 1.000,
|
distance_spacing DECIMAL(6,3) DEFAULT 1.000,
|
||||||
beat_divisor TINYINT DEFAULT 4,
|
beat_divisor TINYINT DEFAULT 4,
|
||||||
grid_size TINYINT DEFAULT 4,
|
grid_size TINYINT DEFAULT 4,
|
||||||
timeline_zoom DECIMAL(6,3) DEFAULT 1.000,
|
timeline_zoom DECIMAL(6,3) DEFAULT 1.000,
|
||||||
|
|
||||||
-- 谱面元数据
|
-- 谱面元数据
|
||||||
title_unicode VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT '',
|
title_unicode VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT '',
|
||||||
artist_unicode VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT '',
|
artist_unicode VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT '',
|
||||||
creator VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
|
creator VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||||
version VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
|
version VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
|
||||||
source VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT '',
|
source VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT '',
|
||||||
tags TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci,
|
tags TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci,
|
||||||
beatmap_id BIGINT DEFAULT 0,
|
beatmap_id BIGINT DEFAULT 0,
|
||||||
beatmapset_id BIGINT DEFAULT 0,
|
beatmapset_id BIGINT DEFAULT 0,
|
||||||
|
|
||||||
-- 难度设定
|
-- 难度设定
|
||||||
hp_drain_rate DECIMAL(3,1) DEFAULT 5.0,
|
hp_drain_rate DECIMAL(3,1) DEFAULT 5.0,
|
||||||
circle_size DECIMAL(3,1) DEFAULT 5.0,
|
circle_size DECIMAL(3,1) DEFAULT 5.0,
|
||||||
overall_difficulty DECIMAL(3,1) DEFAULT 5.0,
|
overall_difficulty DECIMAL(3,1) DEFAULT 5.0,
|
||||||
approach_rate DECIMAL(3,1) DEFAULT 5.0,
|
approach_rate DECIMAL(3,1) DEFAULT 5.0,
|
||||||
slider_multiplier DECIMAL(6,3) DEFAULT 1.400,
|
slider_multiplier DECIMAL(6,3) DEFAULT 1.400,
|
||||||
slider_tick_rate DECIMAL(3,1) DEFAULT 1.0,
|
slider_tick_rate DECIMAL(3,1) DEFAULT 1.0,
|
||||||
|
|
||||||
-- 计算得出的信息
|
-- 计算得出的信息
|
||||||
total_length INT DEFAULT 0 COMMENT '总长度(秒)',
|
total_length INT DEFAULT 0 COMMENT '总长度(秒)',
|
||||||
hit_length INT DEFAULT 0 COMMENT '击打长度(秒)',
|
hit_length INT DEFAULT 0 COMMENT '击打长度(秒)',
|
||||||
max_combo INT DEFAULT 0,
|
max_combo INT DEFAULT 0,
|
||||||
bpm DECIMAL(8,3) DEFAULT 0.000,
|
bpm DECIMAL(8,3) DEFAULT 0.000,
|
||||||
star_rating DECIMAL(6,3) DEFAULT 0.000,
|
star_rating DECIMAL(6,3) DEFAULT 0.000,
|
||||||
aim_difficulty DECIMAL(6,3) DEFAULT 0.000,
|
aim_difficulty DECIMAL(6,3) DEFAULT 0.000,
|
||||||
speed_difficulty DECIMAL(6,3) DEFAULT 0.000,
|
speed_difficulty DECIMAL(6,3) DEFAULT 0.000,
|
||||||
|
|
||||||
-- 统计信息
|
-- 统计信息
|
||||||
plays INT DEFAULT 0,
|
plays INT DEFAULT 0,
|
||||||
passes INT DEFAULT 0,
|
passes INT DEFAULT 0,
|
||||||
|
|
||||||
-- 时间戳
|
-- 时间戳
|
||||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||||
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||||
|
|
||||||
UNIQUE KEY idx_custom_maps_id (id),
|
UNIQUE KEY idx_custom_maps_id (id),
|
||||||
UNIQUE KEY idx_custom_maps_md5 (md5),
|
UNIQUE KEY idx_custom_maps_md5 (md5),
|
||||||
KEY idx_custom_maps_mapset (mapset_id),
|
KEY idx_custom_maps_mapset (mapset_id),
|
||||||
KEY idx_custom_maps_mode (mode),
|
KEY idx_custom_maps_mode (mode),
|
||||||
KEY idx_custom_maps_status (status),
|
KEY idx_custom_maps_status (status),
|
||||||
KEY idx_custom_maps_creator (creator),
|
KEY idx_custom_maps_creator (creator),
|
||||||
KEY idx_custom_maps_star_rating (star_rating),
|
KEY idx_custom_maps_star_rating (star_rating),
|
||||||
KEY idx_custom_maps_plays (plays),
|
KEY idx_custom_maps_plays (plays),
|
||||||
|
|
||||||
FOREIGN KEY (mapset_id) REFERENCES custom_mapsets(id) ON DELETE CASCADE
|
FOREIGN KEY (mapset_id) REFERENCES custom_mapsets(id) ON DELETE CASCADE
|
||||||
);
|
);
|
||||||
|
|
||||||
-- 自定义谱面书签表
|
-- 自定义谱面书签表
|
||||||
CREATE TABLE custom_map_bookmarks (
|
CREATE TABLE custom_map_bookmarks (
|
||||||
user_id INT NOT NULL,
|
user_id INT NOT NULL,
|
||||||
mapset_id BIGINT NOT NULL,
|
mapset_id BIGINT NOT NULL,
|
||||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||||
PRIMARY KEY (user_id, mapset_id),
|
PRIMARY KEY (user_id, mapset_id),
|
||||||
FOREIGN KEY (mapset_id) REFERENCES custom_mapsets(id) ON DELETE CASCADE
|
FOREIGN KEY (mapset_id) REFERENCES custom_mapsets(id) ON DELETE CASCADE
|
||||||
);
|
);
|
||||||
|
|
||||||
-- 自定义谱面评分表
|
-- 自定义谱面评分表
|
||||||
CREATE TABLE custom_map_ratings (
|
CREATE TABLE custom_map_ratings (
|
||||||
user_id INT NOT NULL,
|
user_id INT NOT NULL,
|
||||||
map_id BIGINT NOT NULL,
|
map_id BIGINT NOT NULL,
|
||||||
rating TINYINT NOT NULL CHECK (rating >= 1 AND rating <= 10),
|
rating TINYINT NOT NULL CHECK (rating >= 1 AND rating <= 10),
|
||||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||||
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||||
PRIMARY KEY (user_id, map_id),
|
PRIMARY KEY (user_id, map_id),
|
||||||
FOREIGN KEY (map_id) REFERENCES custom_maps(id) ON DELETE CASCADE
|
FOREIGN KEY (map_id) REFERENCES custom_maps(id) ON DELETE CASCADE
|
||||||
);
|
);
|
||||||
|
|
||||||
-- 自定义谱面成绩表 (继承原scores表结构)
|
-- 自定义谱面成绩表 (继承原scores表结构)
|
||||||
CREATE TABLE custom_scores (
|
CREATE TABLE custom_scores (
|
||||||
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
|
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
|
||||||
map_id BIGINT NOT NULL,
|
map_id BIGINT NOT NULL,
|
||||||
map_md5 CHAR(32) NOT NULL,
|
map_md5 CHAR(32) NOT NULL,
|
||||||
user_id INT NOT NULL,
|
user_id INT NOT NULL,
|
||||||
score INT NOT NULL,
|
score INT NOT NULL,
|
||||||
pp FLOAT(7,3) NOT NULL,
|
pp FLOAT(7,3) NOT NULL,
|
||||||
acc FLOAT(6,3) NOT NULL,
|
acc FLOAT(6,3) NOT NULL,
|
||||||
max_combo INT NOT NULL,
|
max_combo INT NOT NULL,
|
||||||
mods INT NOT NULL,
|
mods INT NOT NULL,
|
||||||
n300 INT NOT NULL,
|
n300 INT NOT NULL,
|
||||||
n100 INT NOT NULL,
|
n100 INT NOT NULL,
|
||||||
n50 INT NOT NULL,
|
n50 INT NOT NULL,
|
||||||
nmiss INT NOT NULL,
|
nmiss INT NOT NULL,
|
||||||
ngeki INT NOT NULL,
|
ngeki INT NOT NULL,
|
||||||
nkatu INT NOT NULL,
|
nkatu INT NOT NULL,
|
||||||
grade VARCHAR(2) DEFAULT 'N' NOT NULL,
|
grade VARCHAR(2) DEFAULT 'N' NOT NULL,
|
||||||
status TINYINT NOT NULL COMMENT '0=failed, 1=submitted, 2=best',
|
status TINYINT NOT NULL COMMENT '0=failed, 1=submitted, 2=best',
|
||||||
mode TINYINT NOT NULL,
|
mode TINYINT NOT NULL,
|
||||||
play_time DATETIME NOT NULL,
|
play_time DATETIME NOT NULL,
|
||||||
time_elapsed INT NOT NULL,
|
time_elapsed INT NOT NULL,
|
||||||
client_flags INT NOT NULL,
|
client_flags INT NOT NULL,
|
||||||
perfect BOOLEAN NOT NULL,
|
perfect BOOLEAN NOT NULL,
|
||||||
online_checksum CHAR(32) NOT NULL,
|
online_checksum CHAR(32) NOT NULL,
|
||||||
|
|
||||||
KEY idx_custom_scores_map_id (map_id),
|
KEY idx_custom_scores_map_id (map_id),
|
||||||
KEY idx_custom_scores_map_md5 (map_md5),
|
KEY idx_custom_scores_map_md5 (map_md5),
|
||||||
KEY idx_custom_scores_user_id (user_id),
|
KEY idx_custom_scores_user_id (user_id),
|
||||||
KEY idx_custom_scores_score (score),
|
KEY idx_custom_scores_score (score),
|
||||||
KEY idx_custom_scores_pp (pp),
|
KEY idx_custom_scores_pp (pp),
|
||||||
KEY idx_custom_scores_mods (mods),
|
KEY idx_custom_scores_mods (mods),
|
||||||
KEY idx_custom_scores_status (status),
|
KEY idx_custom_scores_status (status),
|
||||||
KEY idx_custom_scores_mode (mode),
|
KEY idx_custom_scores_mode (mode),
|
||||||
KEY idx_custom_scores_play_time (play_time),
|
KEY idx_custom_scores_play_time (play_time),
|
||||||
KEY idx_custom_scores_online_checksum (online_checksum),
|
KEY idx_custom_scores_online_checksum (online_checksum),
|
||||||
KEY idx_custom_scores_leaderboard (map_md5, status, mode),
|
KEY idx_custom_scores_leaderboard (map_md5, status, mode),
|
||||||
|
|
||||||
FOREIGN KEY (map_id) REFERENCES custom_maps(id) ON DELETE CASCADE
|
FOREIGN KEY (map_id) REFERENCES custom_maps(id) ON DELETE CASCADE
|
||||||
);
|
);
|
||||||
|
|
||||||
-- 自定义谱面文件存储表 (用于存储.osu文件内容等)
|
-- 自定义谱面文件存储表 (用于存储.osu文件内容等)
|
||||||
CREATE TABLE custom_map_files (
|
CREATE TABLE custom_map_files (
|
||||||
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||||
map_id BIGINT NOT NULL,
|
map_id BIGINT NOT NULL,
|
||||||
file_type ENUM('osu', 'audio', 'image', 'video', 'storyboard') NOT NULL,
|
file_type ENUM('osu', 'audio', 'image', 'video', 'storyboard') NOT NULL,
|
||||||
filename VARCHAR(255) NOT NULL,
|
filename VARCHAR(255) NOT NULL,
|
||||||
file_hash CHAR(32) NOT NULL,
|
file_hash CHAR(32) NOT NULL,
|
||||||
file_size INT NOT NULL,
|
file_size INT NOT NULL,
|
||||||
mime_type VARCHAR(100) DEFAULT '',
|
mime_type VARCHAR(100) DEFAULT '',
|
||||||
storage_path VARCHAR(500) NOT NULL,
|
storage_path VARCHAR(500) NOT NULL,
|
||||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
|
||||||
UNIQUE KEY idx_custom_map_files_id (id),
|
UNIQUE KEY idx_custom_map_files_id (id),
|
||||||
KEY idx_custom_map_files_map_id (map_id),
|
KEY idx_custom_map_files_map_id (map_id),
|
||||||
KEY idx_custom_map_files_type (file_type),
|
KEY idx_custom_map_files_type (file_type),
|
||||||
KEY idx_custom_map_files_hash (file_hash),
|
KEY idx_custom_map_files_hash (file_hash),
|
||||||
|
|
||||||
FOREIGN KEY (map_id) REFERENCES custom_maps(id) ON DELETE CASCADE
|
FOREIGN KEY (map_id) REFERENCES custom_maps(id) ON DELETE CASCADE
|
||||||
);
|
);
|
||||||
|
|
||||||
-- 为自定义谱面创建专门的ID生成器,避免与官方ID冲突
|
-- 为自定义谱面创建专门的ID生成器,避免与官方ID冲突
|
||||||
-- 自定义谱面ID从1000000开始
|
-- 自定义谱面ID从1000000开始
|
||||||
ALTER TABLE custom_mapsets AUTO_INCREMENT = 3000000;
|
ALTER TABLE custom_mapsets AUTO_INCREMENT = 3000000;
|
||||||
ALTER TABLE custom_maps AUTO_INCREMENT = 3000000;
|
ALTER TABLE custom_maps AUTO_INCREMENT = 3000000;
|
||||||
|
|
||||||
-- 创建触发器来同步mapset信息到maps表
|
-- 创建触发器来同步mapset信息到maps表
|
||||||
DELIMITER $$
|
DELIMITER $$
|
||||||
|
|
||||||
CREATE TRIGGER update_custom_mapset_on_map_change
|
CREATE TRIGGER update_custom_mapset_on_map_change
|
||||||
AFTER UPDATE ON custom_maps
|
AFTER UPDATE ON custom_maps
|
||||||
FOR EACH ROW
|
FOR EACH ROW
|
||||||
BEGIN
|
BEGIN
|
||||||
IF NEW.status != OLD.status THEN
|
IF NEW.status != OLD.status THEN
|
||||||
UPDATE custom_mapsets
|
UPDATE custom_mapsets
|
||||||
SET last_update = CURRENT_TIMESTAMP
|
SET last_update = CURRENT_TIMESTAMP
|
||||||
WHERE id = NEW.mapset_id;
|
WHERE id = NEW.mapset_id;
|
||||||
END IF;
|
END IF;
|
||||||
END$$
|
END$$
|
||||||
|
|
||||||
DELIMITER ;
|
DELIMITER ;
|
||||||
|
|||||||
@@ -1,477 +1,477 @@
|
|||||||
# This file contains any sql updates, along with the
|
# This file contains any sql updates, along with the
|
||||||
# version they are required from. Touching this without
|
# version they are required from. Touching this without
|
||||||
# at least reading utils/updater.py is certainly a bad idea :)
|
# at least reading utils/updater.py is certainly a bad idea :)
|
||||||
|
|
||||||
# v3.0.6
|
# v3.0.6
|
||||||
alter table users change name_safe safe_name varchar(32) not null;
|
alter table users change name_safe safe_name varchar(32) not null;
|
||||||
alter table users drop key users_name_safe_uindex;
|
alter table users drop key users_name_safe_uindex;
|
||||||
alter table users add constraint users_safe_name_uindex unique (safe_name);
|
alter table users add constraint users_safe_name_uindex unique (safe_name);
|
||||||
alter table users change pw_hash pw_bcrypt char(60) not null;
|
alter table users change pw_hash pw_bcrypt char(60) not null;
|
||||||
insert into channels (name, topic, read_priv, write_priv, auto_join) values
|
insert into channels (name, topic, read_priv, write_priv, auto_join) values
|
||||||
('#supporter', 'General discussion for p2w gamers.', 48, 48, false),
|
('#supporter', 'General discussion for p2w gamers.', 48, 48, false),
|
||||||
('#staff', 'General discussion for the cool kids.', 28672, 28672, true),
|
('#staff', 'General discussion for the cool kids.', 28672, 28672, true),
|
||||||
('#admin', 'General discussion for the cool.', 24576, 24576, true),
|
('#admin', 'General discussion for the cool.', 24576, 24576, true),
|
||||||
('#dev', 'General discussion for the.', 16384, 16384, true);
|
('#dev', 'General discussion for the.', 16384, 16384, true);
|
||||||
|
|
||||||
# v3.0.8
|
# v3.0.8
|
||||||
alter table users modify safe_name varchar(32) charset utf8 not null;
|
alter table users modify safe_name varchar(32) charset utf8 not null;
|
||||||
alter table users modify name varchar(32) charset utf8 not null;
|
alter table users modify name varchar(32) charset utf8 not null;
|
||||||
alter table mail modify msg varchar(2048) charset utf8 not null;
|
alter table mail modify msg varchar(2048) charset utf8 not null;
|
||||||
alter table logs modify msg varchar(2048) charset utf8 not null;
|
alter table logs modify msg varchar(2048) charset utf8 not null;
|
||||||
drop table if exists comments;
|
drop table if exists comments;
|
||||||
create table comments
|
create table comments
|
||||||
(
|
(
|
||||||
id int auto_increment
|
id int auto_increment
|
||||||
primary key,
|
primary key,
|
||||||
target_id int not null comment 'replay, map, or set id',
|
target_id int not null comment 'replay, map, or set id',
|
||||||
target_type enum('replay', 'map', 'song') not null,
|
target_type enum('replay', 'map', 'song') not null,
|
||||||
userid int not null,
|
userid int not null,
|
||||||
time int not null,
|
time int not null,
|
||||||
comment varchar(80) charset utf8 not null,
|
comment varchar(80) charset utf8 not null,
|
||||||
colour char(6) null comment 'rgb hex string'
|
colour char(6) null comment 'rgb hex string'
|
||||||
);
|
);
|
||||||
|
|
||||||
# v3.0.9
|
# v3.0.9
|
||||||
alter table stats modify tscore_vn_std int unsigned default 0 not null;
|
alter table stats modify tscore_vn_std int unsigned default 0 not null;
|
||||||
alter table stats modify tscore_vn_taiko int unsigned default 0 not null;
|
alter table stats modify tscore_vn_taiko int unsigned default 0 not null;
|
||||||
alter table stats modify tscore_vn_catch int unsigned default 0 not null;
|
alter table stats modify tscore_vn_catch int unsigned default 0 not null;
|
||||||
alter table stats modify tscore_vn_mania int unsigned default 0 not null;
|
alter table stats modify tscore_vn_mania int unsigned default 0 not null;
|
||||||
alter table stats modify tscore_rx_std int unsigned default 0 not null;
|
alter table stats modify tscore_rx_std int unsigned default 0 not null;
|
||||||
alter table stats modify tscore_rx_taiko int unsigned default 0 not null;
|
alter table stats modify tscore_rx_taiko int unsigned default 0 not null;
|
||||||
alter table stats modify tscore_rx_catch int unsigned default 0 not null;
|
alter table stats modify tscore_rx_catch int unsigned default 0 not null;
|
||||||
alter table stats modify tscore_ap_std int unsigned default 0 not null;
|
alter table stats modify tscore_ap_std int unsigned default 0 not null;
|
||||||
alter table stats modify rscore_vn_std int unsigned default 0 not null;
|
alter table stats modify rscore_vn_std int unsigned default 0 not null;
|
||||||
alter table stats modify rscore_vn_taiko int unsigned default 0 not null;
|
alter table stats modify rscore_vn_taiko int unsigned default 0 not null;
|
||||||
alter table stats modify rscore_vn_catch int unsigned default 0 not null;
|
alter table stats modify rscore_vn_catch int unsigned default 0 not null;
|
||||||
alter table stats modify rscore_vn_mania int unsigned default 0 not null;
|
alter table stats modify rscore_vn_mania int unsigned default 0 not null;
|
||||||
alter table stats modify rscore_rx_std int unsigned default 0 not null;
|
alter table stats modify rscore_rx_std int unsigned default 0 not null;
|
||||||
alter table stats modify rscore_rx_taiko int unsigned default 0 not null;
|
alter table stats modify rscore_rx_taiko int unsigned default 0 not null;
|
||||||
alter table stats modify rscore_rx_catch int unsigned default 0 not null;
|
alter table stats modify rscore_rx_catch int unsigned default 0 not null;
|
||||||
alter table stats modify rscore_ap_std int unsigned default 0 not null;
|
alter table stats modify rscore_ap_std int unsigned default 0 not null;
|
||||||
alter table stats modify pp_vn_std smallint unsigned default 0 not null;
|
alter table stats modify pp_vn_std smallint unsigned default 0 not null;
|
||||||
alter table stats modify pp_vn_taiko smallint unsigned default 0 not null;
|
alter table stats modify pp_vn_taiko smallint unsigned default 0 not null;
|
||||||
alter table stats modify pp_vn_catch smallint unsigned default 0 not null;
|
alter table stats modify pp_vn_catch smallint unsigned default 0 not null;
|
||||||
alter table stats modify pp_vn_mania smallint unsigned default 0 not null;
|
alter table stats modify pp_vn_mania smallint unsigned default 0 not null;
|
||||||
alter table stats modify pp_rx_std smallint unsigned default 0 not null;
|
alter table stats modify pp_rx_std smallint unsigned default 0 not null;
|
||||||
alter table stats modify pp_rx_taiko smallint unsigned default 0 not null;
|
alter table stats modify pp_rx_taiko smallint unsigned default 0 not null;
|
||||||
alter table stats modify pp_rx_catch smallint unsigned default 0 not null;
|
alter table stats modify pp_rx_catch smallint unsigned default 0 not null;
|
||||||
alter table stats modify pp_ap_std smallint unsigned default 0 not null;
|
alter table stats modify pp_ap_std smallint unsigned default 0 not null;
|
||||||
alter table stats modify plays_vn_std int unsigned default 0 not null;
|
alter table stats modify plays_vn_std int unsigned default 0 not null;
|
||||||
alter table stats modify plays_vn_taiko int unsigned default 0 not null;
|
alter table stats modify plays_vn_taiko int unsigned default 0 not null;
|
||||||
alter table stats modify plays_vn_catch int unsigned default 0 not null;
|
alter table stats modify plays_vn_catch int unsigned default 0 not null;
|
||||||
alter table stats modify plays_vn_mania int unsigned default 0 not null;
|
alter table stats modify plays_vn_mania int unsigned default 0 not null;
|
||||||
alter table stats modify plays_rx_std int unsigned default 0 not null;
|
alter table stats modify plays_rx_std int unsigned default 0 not null;
|
||||||
alter table stats modify plays_rx_taiko int unsigned default 0 not null;
|
alter table stats modify plays_rx_taiko int unsigned default 0 not null;
|
||||||
alter table stats modify plays_rx_catch int unsigned default 0 not null;
|
alter table stats modify plays_rx_catch int unsigned default 0 not null;
|
||||||
alter table stats modify plays_ap_std int unsigned default 0 not null;
|
alter table stats modify plays_ap_std int unsigned default 0 not null;
|
||||||
alter table stats modify playtime_vn_std int unsigned default 0 not null;
|
alter table stats modify playtime_vn_std int unsigned default 0 not null;
|
||||||
alter table stats modify playtime_vn_taiko int unsigned default 0 not null;
|
alter table stats modify playtime_vn_taiko int unsigned default 0 not null;
|
||||||
alter table stats modify playtime_vn_catch int unsigned default 0 not null;
|
alter table stats modify playtime_vn_catch int unsigned default 0 not null;
|
||||||
alter table stats modify playtime_vn_mania int unsigned default 0 not null;
|
alter table stats modify playtime_vn_mania int unsigned default 0 not null;
|
||||||
alter table stats modify playtime_rx_std int unsigned default 0 not null;
|
alter table stats modify playtime_rx_std int unsigned default 0 not null;
|
||||||
alter table stats modify playtime_rx_taiko int unsigned default 0 not null;
|
alter table stats modify playtime_rx_taiko int unsigned default 0 not null;
|
||||||
alter table stats modify playtime_rx_catch int unsigned default 0 not null;
|
alter table stats modify playtime_rx_catch int unsigned default 0 not null;
|
||||||
alter table stats modify playtime_ap_std int unsigned default 0 not null;
|
alter table stats modify playtime_ap_std int unsigned default 0 not null;
|
||||||
alter table stats modify maxcombo_vn_std int unsigned default 0 not null;
|
alter table stats modify maxcombo_vn_std int unsigned default 0 not null;
|
||||||
alter table stats modify maxcombo_vn_taiko int unsigned default 0 not null;
|
alter table stats modify maxcombo_vn_taiko int unsigned default 0 not null;
|
||||||
alter table stats modify maxcombo_vn_catch int unsigned default 0 not null;
|
alter table stats modify maxcombo_vn_catch int unsigned default 0 not null;
|
||||||
alter table stats modify maxcombo_vn_mania int unsigned default 0 not null;
|
alter table stats modify maxcombo_vn_mania int unsigned default 0 not null;
|
||||||
alter table stats modify maxcombo_rx_std int unsigned default 0 not null;
|
alter table stats modify maxcombo_rx_std int unsigned default 0 not null;
|
||||||
alter table stats modify maxcombo_rx_taiko int unsigned default 0 not null;
|
alter table stats modify maxcombo_rx_taiko int unsigned default 0 not null;
|
||||||
alter table stats modify maxcombo_rx_catch int unsigned default 0 not null;
|
alter table stats modify maxcombo_rx_catch int unsigned default 0 not null;
|
||||||
alter table stats modify maxcombo_ap_std int unsigned default 0 not null;
|
alter table stats modify maxcombo_ap_std int unsigned default 0 not null;
|
||||||
|
|
||||||
# v3.0.10
|
# v3.0.10
|
||||||
update channels set write_priv = 24576 where name = '#announce';
|
update channels set write_priv = 24576 where name = '#announce';
|
||||||
|
|
||||||
# v3.1.0
|
# v3.1.0
|
||||||
alter table maps modify bpm float(12,2) default 0.00 not null;
|
alter table maps modify bpm float(12,2) default 0.00 not null;
|
||||||
alter table stats modify tscore_vn_std bigint unsigned default 0 not null;
|
alter table stats modify tscore_vn_std bigint unsigned default 0 not null;
|
||||||
alter table stats modify tscore_vn_taiko bigint unsigned default 0 not null;
|
alter table stats modify tscore_vn_taiko bigint unsigned default 0 not null;
|
||||||
alter table stats modify tscore_vn_catch bigint unsigned default 0 not null;
|
alter table stats modify tscore_vn_catch bigint unsigned default 0 not null;
|
||||||
alter table stats modify tscore_vn_mania bigint unsigned default 0 not null;
|
alter table stats modify tscore_vn_mania bigint unsigned default 0 not null;
|
||||||
alter table stats modify tscore_rx_std bigint unsigned default 0 not null;
|
alter table stats modify tscore_rx_std bigint unsigned default 0 not null;
|
||||||
alter table stats modify tscore_rx_taiko bigint unsigned default 0 not null;
|
alter table stats modify tscore_rx_taiko bigint unsigned default 0 not null;
|
||||||
alter table stats modify tscore_rx_catch bigint unsigned default 0 not null;
|
alter table stats modify tscore_rx_catch bigint unsigned default 0 not null;
|
||||||
alter table stats modify tscore_ap_std bigint unsigned default 0 not null;
|
alter table stats modify tscore_ap_std bigint unsigned default 0 not null;
|
||||||
alter table stats modify rscore_vn_std bigint unsigned default 0 not null;
|
alter table stats modify rscore_vn_std bigint unsigned default 0 not null;
|
||||||
alter table stats modify rscore_vn_taiko bigint unsigned default 0 not null;
|
alter table stats modify rscore_vn_taiko bigint unsigned default 0 not null;
|
||||||
alter table stats modify rscore_vn_catch bigint unsigned default 0 not null;
|
alter table stats modify rscore_vn_catch bigint unsigned default 0 not null;
|
||||||
alter table stats modify rscore_vn_mania bigint unsigned default 0 not null;
|
alter table stats modify rscore_vn_mania bigint unsigned default 0 not null;
|
||||||
alter table stats modify rscore_rx_std bigint unsigned default 0 not null;
|
alter table stats modify rscore_rx_std bigint unsigned default 0 not null;
|
||||||
alter table stats modify rscore_rx_taiko bigint unsigned default 0 not null;
|
alter table stats modify rscore_rx_taiko bigint unsigned default 0 not null;
|
||||||
alter table stats modify rscore_rx_catch bigint unsigned default 0 not null;
|
alter table stats modify rscore_rx_catch bigint unsigned default 0 not null;
|
||||||
alter table stats modify rscore_ap_std bigint unsigned default 0 not null;
|
alter table stats modify rscore_ap_std bigint unsigned default 0 not null;
|
||||||
alter table stats modify pp_vn_std int unsigned default 0 not null;
|
alter table stats modify pp_vn_std int unsigned default 0 not null;
|
||||||
alter table stats modify pp_vn_taiko int unsigned default 0 not null;
|
alter table stats modify pp_vn_taiko int unsigned default 0 not null;
|
||||||
alter table stats modify pp_vn_catch int unsigned default 0 not null;
|
alter table stats modify pp_vn_catch int unsigned default 0 not null;
|
||||||
alter table stats modify pp_vn_mania int unsigned default 0 not null;
|
alter table stats modify pp_vn_mania int unsigned default 0 not null;
|
||||||
alter table stats modify pp_rx_std int unsigned default 0 not null;
|
alter table stats modify pp_rx_std int unsigned default 0 not null;
|
||||||
alter table stats modify pp_rx_taiko int unsigned default 0 not null;
|
alter table stats modify pp_rx_taiko int unsigned default 0 not null;
|
||||||
alter table stats modify pp_rx_catch int unsigned default 0 not null;
|
alter table stats modify pp_rx_catch int unsigned default 0 not null;
|
||||||
alter table stats modify pp_ap_std int unsigned default 0 not null;
|
alter table stats modify pp_ap_std int unsigned default 0 not null;
|
||||||
|
|
||||||
# v3.1.2
|
# v3.1.2
|
||||||
create table clans
|
create table clans
|
||||||
(
|
(
|
||||||
id int auto_increment
|
id int auto_increment
|
||||||
primary key,
|
primary key,
|
||||||
name varchar(16) not null,
|
name varchar(16) not null,
|
||||||
tag varchar(6) not null,
|
tag varchar(6) not null,
|
||||||
owner int not null,
|
owner int not null,
|
||||||
created_at datetime not null,
|
created_at datetime not null,
|
||||||
constraint clans_name_uindex
|
constraint clans_name_uindex
|
||||||
unique (name),
|
unique (name),
|
||||||
constraint clans_owner_uindex
|
constraint clans_owner_uindex
|
||||||
unique (owner),
|
unique (owner),
|
||||||
constraint clans_tag_uindex
|
constraint clans_tag_uindex
|
||||||
unique (tag)
|
unique (tag)
|
||||||
);
|
);
|
||||||
alter table users add clan_id int default 0 not null;
|
alter table users add clan_id int default 0 not null;
|
||||||
alter table users add clan_rank tinyint(1) default 0 not null;
|
alter table users add clan_rank tinyint(1) default 0 not null;
|
||||||
create table achievements
|
create table achievements
|
||||||
(
|
(
|
||||||
id int auto_increment
|
id int auto_increment
|
||||||
primary key,
|
primary key,
|
||||||
file varchar(128) not null,
|
file varchar(128) not null,
|
||||||
name varchar(128) not null,
|
name varchar(128) not null,
|
||||||
`desc` varchar(256) not null,
|
`desc` varchar(256) not null,
|
||||||
cond varchar(64) not null,
|
cond varchar(64) not null,
|
||||||
mode tinyint(1) not null,
|
mode tinyint(1) not null,
|
||||||
constraint achievements_desc_uindex
|
constraint achievements_desc_uindex
|
||||||
unique (`desc`),
|
unique (`desc`),
|
||||||
constraint achievements_file_uindex
|
constraint achievements_file_uindex
|
||||||
unique (file),
|
unique (file),
|
||||||
constraint achievements_name_uindex
|
constraint achievements_name_uindex
|
||||||
unique (name)
|
unique (name)
|
||||||
);
|
);
|
||||||
create table user_achievements
|
create table user_achievements
|
||||||
(
|
(
|
||||||
userid int not null,
|
userid int not null,
|
||||||
achid int not null,
|
achid int not null,
|
||||||
primary key (userid, achid)
|
primary key (userid, achid)
|
||||||
);
|
);
|
||||||
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (1, 'osu-skill-pass-1', 'Rising Star', 'Can''t go forward without the first steps.', '(score.mods & 259 == 0) and 2 >= score.sr > 1', 0);
|
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (1, 'osu-skill-pass-1', 'Rising Star', 'Can''t go forward without the first steps.', '(score.mods & 259 == 0) and 2 >= score.sr > 1', 0);
|
||||||
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (2, 'osu-skill-pass-2', 'Constellation Prize', 'Definitely not a consolation prize. Now things start getting hard!', '(score.mods & 259 == 0) and 3 >= score.sr > 2', 0);
|
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (2, 'osu-skill-pass-2', 'Constellation Prize', 'Definitely not a consolation prize. Now things start getting hard!', '(score.mods & 259 == 0) and 3 >= score.sr > 2', 0);
|
||||||
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (3, 'osu-skill-pass-3', 'Building Confidence', 'Oh, you''ve SO got this.', '(score.mods & 259 == 0) and 4 >= score.sr > 3', 0);
|
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (3, 'osu-skill-pass-3', 'Building Confidence', 'Oh, you''ve SO got this.', '(score.mods & 259 == 0) and 4 >= score.sr > 3', 0);
|
||||||
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (4, 'osu-skill-pass-4', 'Insanity Approaches', 'You''re not twitching, you''re just ready.', '(score.mods & 259 == 0) and 5 >= score.sr > 4', 0);
|
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (4, 'osu-skill-pass-4', 'Insanity Approaches', 'You''re not twitching, you''re just ready.', '(score.mods & 259 == 0) and 5 >= score.sr > 4', 0);
|
||||||
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (5, 'osu-skill-pass-5', 'These Clarion Skies', 'Everything seems so clear now.', '(score.mods & 259 == 0) and 6 >= score.sr > 5', 0);
|
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (5, 'osu-skill-pass-5', 'These Clarion Skies', 'Everything seems so clear now.', '(score.mods & 259 == 0) and 6 >= score.sr > 5', 0);
|
||||||
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (6, 'osu-skill-pass-6', 'Above and Beyond', 'A cut above the rest.', '(score.mods & 259 == 0) and 7 >= score.sr > 6', 0);
|
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (6, 'osu-skill-pass-6', 'Above and Beyond', 'A cut above the rest.', '(score.mods & 259 == 0) and 7 >= score.sr > 6', 0);
|
||||||
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (7, 'osu-skill-pass-7', 'Supremacy', 'All marvel before your prowess.', '(score.mods & 259 == 0) and 8 >= score.sr > 7', 0);
|
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (7, 'osu-skill-pass-7', 'Supremacy', 'All marvel before your prowess.', '(score.mods & 259 == 0) and 8 >= score.sr > 7', 0);
|
||||||
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (8, 'osu-skill-pass-8', 'Absolution', 'My god, you''re full of stars!', '(score.mods & 259 == 0) and 9 >= score.sr > 8', 0);
|
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (8, 'osu-skill-pass-8', 'Absolution', 'My god, you''re full of stars!', '(score.mods & 259 == 0) and 9 >= score.sr > 8', 0);
|
||||||
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (9, 'osu-skill-pass-9', 'Event Horizon', 'No force dares to pull you under.', '(score.mods & 259 == 0) and 10 >= score.sr > 9', 0);
|
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (9, 'osu-skill-pass-9', 'Event Horizon', 'No force dares to pull you under.', '(score.mods & 259 == 0) and 10 >= score.sr > 9', 0);
|
||||||
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (10, 'osu-skill-pass-10', 'Phantasm', 'Fevered is your passion, extraordinary is your skill.', '(score.mods & 259 == 0) and 11 >= score.sr > 10', 0);
|
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (10, 'osu-skill-pass-10', 'Phantasm', 'Fevered is your passion, extraordinary is your skill.', '(score.mods & 259 == 0) and 11 >= score.sr > 10', 0);
|
||||||
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (11, 'osu-skill-fc-1', 'Totality', 'All the notes. Every single one.', 'score.perfect and 2 >= score.sr > 1', 0);
|
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (11, 'osu-skill-fc-1', 'Totality', 'All the notes. Every single one.', 'score.perfect and 2 >= score.sr > 1', 0);
|
||||||
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (12, 'osu-skill-fc-2', 'Business As Usual', 'Two to go, please.', 'score.perfect and 3 >= score.sr > 2', 0);
|
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (12, 'osu-skill-fc-2', 'Business As Usual', 'Two to go, please.', 'score.perfect and 3 >= score.sr > 2', 0);
|
||||||
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (13, 'osu-skill-fc-3', 'Building Steam', 'Hey, this isn''t so bad.', 'score.perfect and 4 >= score.sr > 3', 0);
|
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (13, 'osu-skill-fc-3', 'Building Steam', 'Hey, this isn''t so bad.', 'score.perfect and 4 >= score.sr > 3', 0);
|
||||||
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (14, 'osu-skill-fc-4', 'Moving Forward', 'Bet you feel good about that.', 'score.perfect and 5 >= score.sr > 4', 0);
|
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (14, 'osu-skill-fc-4', 'Moving Forward', 'Bet you feel good about that.', 'score.perfect and 5 >= score.sr > 4', 0);
|
||||||
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (15, 'osu-skill-fc-5', 'Paradigm Shift', 'Surprisingly difficult.', 'score.perfect and 6 >= score.sr > 5', 0);
|
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (15, 'osu-skill-fc-5', 'Paradigm Shift', 'Surprisingly difficult.', 'score.perfect and 6 >= score.sr > 5', 0);
|
||||||
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (16, 'osu-skill-fc-6', 'Anguish Quelled', 'Don''t choke.', 'score.perfect and 7 >= score.sr > 6', 0);
|
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (16, 'osu-skill-fc-6', 'Anguish Quelled', 'Don''t choke.', 'score.perfect and 7 >= score.sr > 6', 0);
|
||||||
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (17, 'osu-skill-fc-7', 'Never Give Up', 'Excellence is its own reward.', 'score.perfect and 8 >= score.sr > 7', 0);
|
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (17, 'osu-skill-fc-7', 'Never Give Up', 'Excellence is its own reward.', 'score.perfect and 8 >= score.sr > 7', 0);
|
||||||
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (18, 'osu-skill-fc-8', 'Aberration', 'They said it couldn''t be done. They were wrong.', 'score.perfect and 9 >= score.sr > 8', 0);
|
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (18, 'osu-skill-fc-8', 'Aberration', 'They said it couldn''t be done. They were wrong.', 'score.perfect and 9 >= score.sr > 8', 0);
|
||||||
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (19, 'osu-skill-fc-9', 'Chosen', 'Reign among the Prometheans, where you belong.', 'score.perfect and 10 >= score.sr > 9', 0);
|
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (19, 'osu-skill-fc-9', 'Chosen', 'Reign among the Prometheans, where you belong.', 'score.perfect and 10 >= score.sr > 9', 0);
|
||||||
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (20, 'osu-skill-fc-10', 'Unfathomable', 'You have no equal.', 'score.perfect and 11 >= score.sr > 10', 0);
|
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (20, 'osu-skill-fc-10', 'Unfathomable', 'You have no equal.', 'score.perfect and 11 >= score.sr > 10', 0);
|
||||||
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (21, 'osu-combo-500', '500 Combo', '500 big ones! You''re moving up in the world!', '750 >= score.max_combo > 500', 0);
|
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (21, 'osu-combo-500', '500 Combo', '500 big ones! You''re moving up in the world!', '750 >= score.max_combo > 500', 0);
|
||||||
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (22, 'osu-combo-750', '750 Combo', '750 notes back to back? Woah.', '1000 >= score.max_combo > 750', 0);
|
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (22, 'osu-combo-750', '750 Combo', '750 notes back to back? Woah.', '1000 >= score.max_combo > 750', 0);
|
||||||
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (23, 'osu-combo-1000', '1000 Combo', 'A thousand reasons why you rock at this game.', '2000 >= score.max_combo > 1000', 0);
|
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (23, 'osu-combo-1000', '1000 Combo', 'A thousand reasons why you rock at this game.', '2000 >= score.max_combo > 1000', 0);
|
||||||
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (24, 'osu-combo-2000', '2000 Combo', 'Nothing can stop you now.', 'score.max_combo >= 2000', 0);
|
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (24, 'osu-combo-2000', '2000 Combo', 'Nothing can stop you now.', 'score.max_combo >= 2000', 0);
|
||||||
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (25, 'taiko-skill-pass-1', 'My First Don', 'Marching to the beat of your own drum. Literally.', '(score.mods & 259 == 0) and 2 >= score.sr > 1', 1);
|
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (25, 'taiko-skill-pass-1', 'My First Don', 'Marching to the beat of your own drum. Literally.', '(score.mods & 259 == 0) and 2 >= score.sr > 1', 1);
|
||||||
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (26, 'taiko-skill-pass-2', 'Katsu Katsu Katsu', 'Hora! Izuko!', '(score.mods & 259 == 0) and 3 >= score.sr > 2', 1);
|
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (26, 'taiko-skill-pass-2', 'Katsu Katsu Katsu', 'Hora! Izuko!', '(score.mods & 259 == 0) and 3 >= score.sr > 2', 1);
|
||||||
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (27, 'taiko-skill-pass-3', 'Not Even Trying', 'Muzukashii? Not even.', '(score.mods & 259 == 0) and 4 >= score.sr > 3', 1);
|
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (27, 'taiko-skill-pass-3', 'Not Even Trying', 'Muzukashii? Not even.', '(score.mods & 259 == 0) and 4 >= score.sr > 3', 1);
|
||||||
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (28, 'taiko-skill-pass-4', 'Face Your Demons', 'The first trials are now behind you, but are you a match for the Oni?', '(score.mods & 259 == 0) and 5 >= score.sr > 4', 1);
|
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (28, 'taiko-skill-pass-4', 'Face Your Demons', 'The first trials are now behind you, but are you a match for the Oni?', '(score.mods & 259 == 0) and 5 >= score.sr > 4', 1);
|
||||||
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (29, 'taiko-skill-pass-5', 'The Demon Within', 'No rest for the wicked.', '(score.mods & 259 == 0) and 6 >= score.sr > 5', 1);
|
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (29, 'taiko-skill-pass-5', 'The Demon Within', 'No rest for the wicked.', '(score.mods & 259 == 0) and 6 >= score.sr > 5', 1);
|
||||||
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (30, 'taiko-skill-pass-6', 'Drumbreaker', 'Too strong.', '(score.mods & 259 == 0) and 7 >= score.sr > 6', 1);
|
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (30, 'taiko-skill-pass-6', 'Drumbreaker', 'Too strong.', '(score.mods & 259 == 0) and 7 >= score.sr > 6', 1);
|
||||||
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (31, 'taiko-skill-pass-7', 'The Godfather', 'You are the Don of Dons.', '(score.mods & 259 == 0) and 8 >= score.sr > 7', 1);
|
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (31, 'taiko-skill-pass-7', 'The Godfather', 'You are the Don of Dons.', '(score.mods & 259 == 0) and 8 >= score.sr > 7', 1);
|
||||||
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (32, 'taiko-skill-pass-8', 'Rhythm Incarnate', 'Feel the beat. Become the beat.', '(score.mods & 259 == 0) and 9 >= score.sr > 8', 1);
|
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (32, 'taiko-skill-pass-8', 'Rhythm Incarnate', 'Feel the beat. Become the beat.', '(score.mods & 259 == 0) and 9 >= score.sr > 8', 1);
|
||||||
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (33, 'taiko-skill-fc-1', 'Keeping Time', 'Don, then katsu. Don, then katsu..', 'score.perfect and 2 >= score.sr > 1', 1);
|
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (33, 'taiko-skill-fc-1', 'Keeping Time', 'Don, then katsu. Don, then katsu..', 'score.perfect and 2 >= score.sr > 1', 1);
|
||||||
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (34, 'taiko-skill-fc-2', 'To Your Own Beat', 'Straight and steady.', 'score.perfect and 3 >= score.sr > 2', 1);
|
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (34, 'taiko-skill-fc-2', 'To Your Own Beat', 'Straight and steady.', 'score.perfect and 3 >= score.sr > 2', 1);
|
||||||
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (35, 'taiko-skill-fc-3', 'Big Drums', 'Bigger scores to match.', 'score.perfect and 4 >= score.sr > 3', 1);
|
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (35, 'taiko-skill-fc-3', 'Big Drums', 'Bigger scores to match.', 'score.perfect and 4 >= score.sr > 3', 1);
|
||||||
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (36, 'taiko-skill-fc-4', 'Adversity Overcome', 'Difficult? Not for you.', 'score.perfect and 5 >= score.sr > 4', 1);
|
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (36, 'taiko-skill-fc-4', 'Adversity Overcome', 'Difficult? Not for you.', 'score.perfect and 5 >= score.sr > 4', 1);
|
||||||
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (37, 'taiko-skill-fc-5', 'Demonslayer', 'An Oni felled forevermore.', 'score.perfect and 6 >= score.sr > 5', 1);
|
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (37, 'taiko-skill-fc-5', 'Demonslayer', 'An Oni felled forevermore.', 'score.perfect and 6 >= score.sr > 5', 1);
|
||||||
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (38, 'taiko-skill-fc-6', 'Rhythm''s Call', 'Heralding true skill.', 'score.perfect and 7 >= score.sr > 6', 1);
|
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (38, 'taiko-skill-fc-6', 'Rhythm''s Call', 'Heralding true skill.', 'score.perfect and 7 >= score.sr > 6', 1);
|
||||||
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (39, 'taiko-skill-fc-7', 'Time Everlasting', 'Not a single beat escapes you.', 'score.perfect and 8 >= score.sr > 7', 1);
|
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (39, 'taiko-skill-fc-7', 'Time Everlasting', 'Not a single beat escapes you.', 'score.perfect and 8 >= score.sr > 7', 1);
|
||||||
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (40, 'taiko-skill-fc-8', 'The Drummer''s Throne', 'Percussive brilliance befitting royalty alone.', 'score.perfect and 9 >= score.sr > 8', 1);
|
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (40, 'taiko-skill-fc-8', 'The Drummer''s Throne', 'Percussive brilliance befitting royalty alone.', 'score.perfect and 9 >= score.sr > 8', 1);
|
||||||
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (41, 'fruits-skill-pass-1', 'A Slice Of Life', 'Hey, this fruit catching business isn''t bad.', '(score.mods & 259 == 0) and 2 >= score.sr > 1', 2);
|
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (41, 'fruits-skill-pass-1', 'A Slice Of Life', 'Hey, this fruit catching business isn''t bad.', '(score.mods & 259 == 0) and 2 >= score.sr > 1', 2);
|
||||||
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (42, 'fruits-skill-pass-2', 'Dashing Ever Forward', 'Fast is how you do it.', '(score.mods & 259 == 0) and 3 >= score.sr > 2', 2);
|
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (42, 'fruits-skill-pass-2', 'Dashing Ever Forward', 'Fast is how you do it.', '(score.mods & 259 == 0) and 3 >= score.sr > 2', 2);
|
||||||
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (43, 'fruits-skill-pass-3', 'Zesty Disposition', 'No scurvy for you, not with that much fruit.', '(score.mods & 259 == 0) and 4 >= score.sr > 3', 2);
|
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (43, 'fruits-skill-pass-3', 'Zesty Disposition', 'No scurvy for you, not with that much fruit.', '(score.mods & 259 == 0) and 4 >= score.sr > 3', 2);
|
||||||
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (44, 'fruits-skill-pass-4', 'Hyperdash ON!', 'Time and distance is no obstacle to you.', '(score.mods & 259 == 0) and 5 >= score.sr > 4', 2);
|
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (44, 'fruits-skill-pass-4', 'Hyperdash ON!', 'Time and distance is no obstacle to you.', '(score.mods & 259 == 0) and 5 >= score.sr > 4', 2);
|
||||||
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (45, 'fruits-skill-pass-5', 'It''s Raining Fruit', 'And you can catch them all.', '(score.mods & 259 == 0) and 6 >= score.sr > 5', 2);
|
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (45, 'fruits-skill-pass-5', 'It''s Raining Fruit', 'And you can catch them all.', '(score.mods & 259 == 0) and 6 >= score.sr > 5', 2);
|
||||||
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (46, 'fruits-skill-pass-6', 'Fruit Ninja', 'Legendary techniques.', '(score.mods & 259 == 0) and 7 >= score.sr > 6', 2);
|
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (46, 'fruits-skill-pass-6', 'Fruit Ninja', 'Legendary techniques.', '(score.mods & 259 == 0) and 7 >= score.sr > 6', 2);
|
||||||
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (47, 'fruits-skill-pass-7', 'Dreamcatcher', 'No fruit, only dreams now.', '(score.mods & 259 == 0) and 8 >= score.sr > 7', 2);
|
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (47, 'fruits-skill-pass-7', 'Dreamcatcher', 'No fruit, only dreams now.', '(score.mods & 259 == 0) and 8 >= score.sr > 7', 2);
|
||||||
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (48, 'fruits-skill-pass-8', 'Lord of the Catch', 'Your kingdom kneels before you.', '(score.mods & 259 == 0) and 9 >= score.sr > 8', 2);
|
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (48, 'fruits-skill-pass-8', 'Lord of the Catch', 'Your kingdom kneels before you.', '(score.mods & 259 == 0) and 9 >= score.sr > 8', 2);
|
||||||
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (49, 'fruits-skill-fc-1', 'Sweet And Sour', 'Apples and oranges, literally.', 'score.perfect and 2 >= score.sr > 1', 2);
|
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (49, 'fruits-skill-fc-1', 'Sweet And Sour', 'Apples and oranges, literally.', 'score.perfect and 2 >= score.sr > 1', 2);
|
||||||
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (50, 'fruits-skill-fc-2', 'Reaching The Core', 'The seeds of future success.', 'score.perfect and 3 >= score.sr > 2', 2);
|
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (50, 'fruits-skill-fc-2', 'Reaching The Core', 'The seeds of future success.', 'score.perfect and 3 >= score.sr > 2', 2);
|
||||||
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (51, 'fruits-skill-fc-3', 'Clean Platter', 'Clean only of failure. It is completely full, otherwise.', 'score.perfect and 4 >= score.sr > 3', 2);
|
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (51, 'fruits-skill-fc-3', 'Clean Platter', 'Clean only of failure. It is completely full, otherwise.', 'score.perfect and 4 >= score.sr > 3', 2);
|
||||||
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (52, 'fruits-skill-fc-4', 'Between The Rain', 'No umbrella needed.', 'score.perfect and 5 >= score.sr > 4', 2);
|
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (52, 'fruits-skill-fc-4', 'Between The Rain', 'No umbrella needed.', 'score.perfect and 5 >= score.sr > 4', 2);
|
||||||
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (53, 'fruits-skill-fc-5', 'Addicted', 'That was an overdose?', 'score.perfect and 6 >= score.sr > 5', 2);
|
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (53, 'fruits-skill-fc-5', 'Addicted', 'That was an overdose?', 'score.perfect and 6 >= score.sr > 5', 2);
|
||||||
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (54, 'fruits-skill-fc-6', 'Quickening', 'A dash above normal limits.', 'score.perfect and 7 >= score.sr > 6', 2);
|
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (54, 'fruits-skill-fc-6', 'Quickening', 'A dash above normal limits.', 'score.perfect and 7 >= score.sr > 6', 2);
|
||||||
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (55, 'fruits-skill-fc-7', 'Supersonic', 'Faster than is reasonably necessary.', 'score.perfect and 8 >= score.sr > 7', 2);
|
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (55, 'fruits-skill-fc-7', 'Supersonic', 'Faster than is reasonably necessary.', 'score.perfect and 8 >= score.sr > 7', 2);
|
||||||
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (56, 'fruits-skill-fc-8', 'Dashing Scarlet', 'Speed beyond mortal reckoning.', 'score.perfect and 9 >= score.sr > 8', 2);
|
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (56, 'fruits-skill-fc-8', 'Dashing Scarlet', 'Speed beyond mortal reckoning.', 'score.perfect and 9 >= score.sr > 8', 2);
|
||||||
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (57, 'mania-skill-pass-1', 'First Steps', 'It isn''t 9-to-5, but 1-to-9. Keys, that is.', '(score.mods & 259 == 0) and 2 >= score.sr > 1', 3);
|
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (57, 'mania-skill-pass-1', 'First Steps', 'It isn''t 9-to-5, but 1-to-9. Keys, that is.', '(score.mods & 259 == 0) and 2 >= score.sr > 1', 3);
|
||||||
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (58, 'mania-skill-pass-2', 'No Normal Player', 'Not anymore, at least.', '(score.mods & 259 == 0) and 3 >= score.sr > 2', 3);
|
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (58, 'mania-skill-pass-2', 'No Normal Player', 'Not anymore, at least.', '(score.mods & 259 == 0) and 3 >= score.sr > 2', 3);
|
||||||
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (59, 'mania-skill-pass-3', 'Impulse Drive', 'Not quite hyperspeed, but getting close.', '(score.mods & 259 == 0) and 4 >= score.sr > 3', 3);
|
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (59, 'mania-skill-pass-3', 'Impulse Drive', 'Not quite hyperspeed, but getting close.', '(score.mods & 259 == 0) and 4 >= score.sr > 3', 3);
|
||||||
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (60, 'mania-skill-pass-4', 'Hyperspeed', 'Woah.', '(score.mods & 259 == 0) and 5 >= score.sr > 4', 3);
|
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (60, 'mania-skill-pass-4', 'Hyperspeed', 'Woah.', '(score.mods & 259 == 0) and 5 >= score.sr > 4', 3);
|
||||||
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (61, 'mania-skill-pass-5', 'Ever Onwards', 'Another challenge is just around the corner.', '(score.mods & 259 == 0) and 6 >= score.sr > 5', 3);
|
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (61, 'mania-skill-pass-5', 'Ever Onwards', 'Another challenge is just around the corner.', '(score.mods & 259 == 0) and 6 >= score.sr > 5', 3);
|
||||||
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (62, 'mania-skill-pass-6', 'Another Surpassed', 'Is there no limit to your skills?', '(score.mods & 259 == 0) and 7 >= score.sr > 6', 3);
|
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (62, 'mania-skill-pass-6', 'Another Surpassed', 'Is there no limit to your skills?', '(score.mods & 259 == 0) and 7 >= score.sr > 6', 3);
|
||||||
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (63, 'mania-skill-pass-7', 'Extra Credit', 'See me after class.', '(score.mods & 259 == 0) and 8 >= score.sr > 7', 3);
|
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (63, 'mania-skill-pass-7', 'Extra Credit', 'See me after class.', '(score.mods & 259 == 0) and 8 >= score.sr > 7', 3);
|
||||||
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (64, 'mania-skill-pass-8', 'Maniac', 'There''s just no stopping you.', '(score.mods & 259 == 0) and 9 >= score.sr > 8', 3);
|
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (64, 'mania-skill-pass-8', 'Maniac', 'There''s just no stopping you.', '(score.mods & 259 == 0) and 9 >= score.sr > 8', 3);
|
||||||
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (65, 'mania-skill-fc-1', 'Keystruck', 'The beginning of a new story', 'score.perfect and (score.mods & 259 == 0) and 2 >= score.sr > 1', 3);
|
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (65, 'mania-skill-fc-1', 'Keystruck', 'The beginning of a new story', 'score.perfect and (score.mods & 259 == 0) and 2 >= score.sr > 1', 3);
|
||||||
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (66, 'mania-skill-fc-2', 'Keying In', 'Finding your groove.', 'score.perfect and 3 >= score.sr > 2', 3);
|
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (66, 'mania-skill-fc-2', 'Keying In', 'Finding your groove.', 'score.perfect and 3 >= score.sr > 2', 3);
|
||||||
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (67, 'mania-skill-fc-3', 'Hyperflow', 'You can *feel* the rhythm.', 'score.perfect and 4 >= score.sr > 3', 3);
|
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (67, 'mania-skill-fc-3', 'Hyperflow', 'You can *feel* the rhythm.', 'score.perfect and 4 >= score.sr > 3', 3);
|
||||||
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (68, 'mania-skill-fc-4', 'Breakthrough', 'Many skills mastered, rolled into one.', 'score.perfect and 5 >= score.sr > 4', 3);
|
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (68, 'mania-skill-fc-4', 'Breakthrough', 'Many skills mastered, rolled into one.', 'score.perfect and 5 >= score.sr > 4', 3);
|
||||||
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (69, 'mania-skill-fc-5', 'Everything Extra', 'Giving your all is giving everything you have.', 'score.perfect and 6 >= score.sr > 5', 3);
|
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (69, 'mania-skill-fc-5', 'Everything Extra', 'Giving your all is giving everything you have.', 'score.perfect and 6 >= score.sr > 5', 3);
|
||||||
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (70, 'mania-skill-fc-6', 'Level Breaker', 'Finesse beyond reason', 'score.perfect and 7 >= score.sr > 6', 3);
|
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (70, 'mania-skill-fc-6', 'Level Breaker', 'Finesse beyond reason', 'score.perfect and 7 >= score.sr > 6', 3);
|
||||||
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (71, 'mania-skill-fc-7', 'Step Up', 'A precipice rarely seen.', 'score.perfect and 8 >= score.sr > 7', 3);
|
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (71, 'mania-skill-fc-7', 'Step Up', 'A precipice rarely seen.', 'score.perfect and 8 >= score.sr > 7', 3);
|
||||||
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (72, 'mania-skill-fc-8', 'Behind The Veil', 'Supernatural!', 'score.perfect and 9 >= score.sr > 8', 3);
|
insert into achievements (`id`, `file`, `name`, `desc`, `cond`, `mode`) values (72, 'mania-skill-fc-8', 'Behind The Veil', 'Supernatural!', 'score.perfect and 9 >= score.sr > 8', 3);
|
||||||
|
|
||||||
# v3.1.3
|
# v3.1.3
|
||||||
alter table clans modify name varchar(16) charset utf8 not null;
|
alter table clans modify name varchar(16) charset utf8 not null;
|
||||||
alter table clans modify tag varchar(6) charset utf8 not null;
|
alter table clans modify tag varchar(6) charset utf8 not null;
|
||||||
alter table achievements modify name varchar(128) charset utf8 not null;
|
alter table achievements modify name varchar(128) charset utf8 not null;
|
||||||
alter table achievements modify `desc` varchar(256) charset utf8 not null;
|
alter table achievements modify `desc` varchar(256) charset utf8 not null;
|
||||||
alter table maps modify artist varchar(128) charset utf8 not null;
|
alter table maps modify artist varchar(128) charset utf8 not null;
|
||||||
alter table maps modify title varchar(128) charset utf8 not null;
|
alter table maps modify title varchar(128) charset utf8 not null;
|
||||||
alter table maps modify version varchar(128) charset utf8 not null;
|
alter table maps modify version varchar(128) charset utf8 not null;
|
||||||
alter table maps modify creator varchar(19) charset utf8 not null comment 'not 100%% certain on len';
|
alter table maps modify creator varchar(19) charset utf8 not null comment 'not 100%% certain on len';
|
||||||
alter table tourney_pools drop foreign key tourney_pools_users_id_fk;
|
alter table tourney_pools drop foreign key tourney_pools_users_id_fk;
|
||||||
alter table tourney_pool_maps drop foreign key tourney_pool_maps_tourney_pools_id_fk;
|
alter table tourney_pool_maps drop foreign key tourney_pool_maps_tourney_pools_id_fk;
|
||||||
alter table stats drop foreign key stats_users_id_fk;
|
alter table stats drop foreign key stats_users_id_fk;
|
||||||
alter table ratings drop foreign key ratings_maps_md5_fk;
|
alter table ratings drop foreign key ratings_maps_md5_fk;
|
||||||
alter table ratings drop foreign key ratings_users_id_fk;
|
alter table ratings drop foreign key ratings_users_id_fk;
|
||||||
alter table logs modify `from` int not null comment 'both from and to are playerids';
|
alter table logs modify `from` int not null comment 'both from and to are playerids';
|
||||||
|
|
||||||
# v3.1.9
|
# v3.1.9
|
||||||
alter table scores_rx modify id bigint(20) unsigned auto_increment;
|
alter table scores_rx modify id bigint(20) unsigned auto_increment;
|
||||||
update scores_rx set id = id + (6148914691236517205 - 1);
|
update scores_rx set id = id + (6148914691236517205 - 1);
|
||||||
select @max_rx := MAX(id) + 1 from scores_rx;
|
select @max_rx := MAX(id) + 1 from scores_rx;
|
||||||
set @s = CONCAT('alter table scores_rx auto_increment = ', @max_rx);
|
set @s = CONCAT('alter table scores_rx auto_increment = ', @max_rx);
|
||||||
prepare stmt from @s;
|
prepare stmt from @s;
|
||||||
execute stmt;
|
execute stmt;
|
||||||
deallocate PREPARE stmt;
|
deallocate PREPARE stmt;
|
||||||
alter table scores_ap modify id bigint(20) unsigned auto_increment;
|
alter table scores_ap modify id bigint(20) unsigned auto_increment;
|
||||||
update scores_ap set id = id + (12297829382473034410 - 1);
|
update scores_ap set id = id + (12297829382473034410 - 1);
|
||||||
select @max_ap := MAX(id) + 1 from scores_ap;
|
select @max_ap := MAX(id) + 1 from scores_ap;
|
||||||
set @s = CONCAT('alter table scores_ap auto_increment = ', @max_ap);
|
set @s = CONCAT('alter table scores_ap auto_increment = ', @max_ap);
|
||||||
prepare stmt from @s;
|
prepare stmt from @s;
|
||||||
execute stmt;
|
execute stmt;
|
||||||
deallocate PREPARE stmt;
|
deallocate PREPARE stmt;
|
||||||
alter table performance_reports modify scoreid bigint(20) unsigned auto_increment;
|
alter table performance_reports modify scoreid bigint(20) unsigned auto_increment;
|
||||||
|
|
||||||
# v3.2.0
|
# v3.2.0
|
||||||
create table map_requests
|
create table map_requests
|
||||||
(
|
(
|
||||||
id int auto_increment
|
id int auto_increment
|
||||||
primary key,
|
primary key,
|
||||||
map_id int not null,
|
map_id int not null,
|
||||||
player_id int not null,
|
player_id int not null,
|
||||||
datetime datetime not null,
|
datetime datetime not null,
|
||||||
active tinyint(1) not null
|
active tinyint(1) not null
|
||||||
);
|
);
|
||||||
|
|
||||||
# v3.2.1
|
# v3.2.1
|
||||||
update scores_rx set id = id - 3074457345618258603;
|
update scores_rx set id = id - 3074457345618258603;
|
||||||
update scores_ap set id = id - 6148914691236517206;
|
update scores_ap set id = id - 6148914691236517206;
|
||||||
|
|
||||||
# v3.2.2
|
# v3.2.2
|
||||||
alter table maps add max_combo int not null after total_length;
|
alter table maps add max_combo int not null after total_length;
|
||||||
alter table users change clan_rank clan_priv tinyint(1) default 0 not null;
|
alter table users change clan_rank clan_priv tinyint(1) default 0 not null;
|
||||||
|
|
||||||
# v3.2.3
|
# v3.2.3
|
||||||
alter table users add api_key char(36) default NULL null;
|
alter table users add api_key char(36) default NULL null;
|
||||||
create unique index users_api_key_uindex on users (api_key);
|
create unique index users_api_key_uindex on users (api_key);
|
||||||
|
|
||||||
# v3.2.4
|
# v3.2.4
|
||||||
update achievements set file = replace(file, 'ctb', 'fruits') where mode = 2;
|
update achievements set file = replace(file, 'ctb', 'fruits') where mode = 2;
|
||||||
|
|
||||||
# v3.2.5
|
# v3.2.5
|
||||||
update achievements set cond = '(score.mods & 1 == 0) and 1 <= score.sr < 2' where file in ('osu-skill-pass-1', 'taiko-skill-pass-1', 'fruits-skill-pass-1', 'mania-skill-pass-1');
|
update achievements set cond = '(score.mods & 1 == 0) and 1 <= score.sr < 2' where file in ('osu-skill-pass-1', 'taiko-skill-pass-1', 'fruits-skill-pass-1', 'mania-skill-pass-1');
|
||||||
update achievements set cond = '(score.mods & 1 == 0) and 2 <= score.sr < 3' where file in ('osu-skill-pass-2', 'taiko-skill-pass-2', 'fruits-skill-pass-2', 'mania-skill-pass-2');
|
update achievements set cond = '(score.mods & 1 == 0) and 2 <= score.sr < 3' where file in ('osu-skill-pass-2', 'taiko-skill-pass-2', 'fruits-skill-pass-2', 'mania-skill-pass-2');
|
||||||
update achievements set cond = '(score.mods & 1 == 0) and 3 <= score.sr < 4' where file in ('osu-skill-pass-3', 'taiko-skill-pass-3', 'fruits-skill-pass-3', 'mania-skill-pass-3');
|
update achievements set cond = '(score.mods & 1 == 0) and 3 <= score.sr < 4' where file in ('osu-skill-pass-3', 'taiko-skill-pass-3', 'fruits-skill-pass-3', 'mania-skill-pass-3');
|
||||||
update achievements set cond = '(score.mods & 1 == 0) and 4 <= score.sr < 5' where file in ('osu-skill-pass-4', 'taiko-skill-pass-4', 'fruits-skill-pass-4', 'mania-skill-pass-4');
|
update achievements set cond = '(score.mods & 1 == 0) and 4 <= score.sr < 5' where file in ('osu-skill-pass-4', 'taiko-skill-pass-4', 'fruits-skill-pass-4', 'mania-skill-pass-4');
|
||||||
update achievements set cond = '(score.mods & 1 == 0) and 5 <= score.sr < 6' where file in ('osu-skill-pass-5', 'taiko-skill-pass-5', 'fruits-skill-pass-5', 'mania-skill-pass-5');
|
update achievements set cond = '(score.mods & 1 == 0) and 5 <= score.sr < 6' where file in ('osu-skill-pass-5', 'taiko-skill-pass-5', 'fruits-skill-pass-5', 'mania-skill-pass-5');
|
||||||
update achievements set cond = '(score.mods & 1 == 0) and 6 <= score.sr < 7' where file in ('osu-skill-pass-6', 'taiko-skill-pass-6', 'fruits-skill-pass-6', 'mania-skill-pass-6');
|
update achievements set cond = '(score.mods & 1 == 0) and 6 <= score.sr < 7' where file in ('osu-skill-pass-6', 'taiko-skill-pass-6', 'fruits-skill-pass-6', 'mania-skill-pass-6');
|
||||||
update achievements set cond = '(score.mods & 1 == 0) and 7 <= score.sr < 8' where file in ('osu-skill-pass-7', 'taiko-skill-pass-7', 'fruits-skill-pass-7', 'mania-skill-pass-7');
|
update achievements set cond = '(score.mods & 1 == 0) and 7 <= score.sr < 8' where file in ('osu-skill-pass-7', 'taiko-skill-pass-7', 'fruits-skill-pass-7', 'mania-skill-pass-7');
|
||||||
update achievements set cond = '(score.mods & 1 == 0) and 8 <= score.sr < 9' where file in ('osu-skill-pass-8', 'taiko-skill-pass-8', 'fruits-skill-pass-8', 'mania-skill-pass-8');
|
update achievements set cond = '(score.mods & 1 == 0) and 8 <= score.sr < 9' where file in ('osu-skill-pass-8', 'taiko-skill-pass-8', 'fruits-skill-pass-8', 'mania-skill-pass-8');
|
||||||
update achievements set cond = '(score.mods & 1 == 0) and 9 <= score.sr < 10' where file = 'osu-skill-pass-9';
|
update achievements set cond = '(score.mods & 1 == 0) and 9 <= score.sr < 10' where file = 'osu-skill-pass-9';
|
||||||
update achievements set cond = '(score.mods & 1 == 0) and 10 <= score.sr < 11' where file = 'osu-skill-pass-10';
|
update achievements set cond = '(score.mods & 1 == 0) and 10 <= score.sr < 11' where file = 'osu-skill-pass-10';
|
||||||
|
|
||||||
update achievements set cond = 'score.perfect and 1 <= score.sr < 2' where file in ('osu-skill-fc-1', 'taiko-skill-fc-1', 'fruits-skill-fc-1', 'mania-skill-fc-1');
|
update achievements set cond = 'score.perfect and 1 <= score.sr < 2' where file in ('osu-skill-fc-1', 'taiko-skill-fc-1', 'fruits-skill-fc-1', 'mania-skill-fc-1');
|
||||||
update achievements set cond = 'score.perfect and 2 <= score.sr < 3' where file in ('osu-skill-fc-2', 'taiko-skill-fc-2', 'fruits-skill-fc-2', 'mania-skill-fc-2');
|
update achievements set cond = 'score.perfect and 2 <= score.sr < 3' where file in ('osu-skill-fc-2', 'taiko-skill-fc-2', 'fruits-skill-fc-2', 'mania-skill-fc-2');
|
||||||
update achievements set cond = 'score.perfect and 3 <= score.sr < 4' where file in ('osu-skill-fc-3', 'taiko-skill-fc-3', 'fruits-skill-fc-3', 'mania-skill-fc-3');
|
update achievements set cond = 'score.perfect and 3 <= score.sr < 4' where file in ('osu-skill-fc-3', 'taiko-skill-fc-3', 'fruits-skill-fc-3', 'mania-skill-fc-3');
|
||||||
update achievements set cond = 'score.perfect and 4 <= score.sr < 5' where file in ('osu-skill-fc-4', 'taiko-skill-fc-4', 'fruits-skill-fc-4', 'mania-skill-fc-4');
|
update achievements set cond = 'score.perfect and 4 <= score.sr < 5' where file in ('osu-skill-fc-4', 'taiko-skill-fc-4', 'fruits-skill-fc-4', 'mania-skill-fc-4');
|
||||||
update achievements set cond = 'score.perfect and 5 <= score.sr < 6' where file in ('osu-skill-fc-5', 'taiko-skill-fc-5', 'fruits-skill-fc-5', 'mania-skill-fc-5');
|
update achievements set cond = 'score.perfect and 5 <= score.sr < 6' where file in ('osu-skill-fc-5', 'taiko-skill-fc-5', 'fruits-skill-fc-5', 'mania-skill-fc-5');
|
||||||
update achievements set cond = 'score.perfect and 6 <= score.sr < 7' where file in ('osu-skill-fc-6', 'taiko-skill-fc-6', 'fruits-skill-fc-6', 'mania-skill-fc-6');
|
update achievements set cond = 'score.perfect and 6 <= score.sr < 7' where file in ('osu-skill-fc-6', 'taiko-skill-fc-6', 'fruits-skill-fc-6', 'mania-skill-fc-6');
|
||||||
update achievements set cond = 'score.perfect and 7 <= score.sr < 8' where file in ('osu-skill-fc-7', 'taiko-skill-fc-7', 'fruits-skill-fc-7', 'mania-skill-fc-7');
|
update achievements set cond = 'score.perfect and 7 <= score.sr < 8' where file in ('osu-skill-fc-7', 'taiko-skill-fc-7', 'fruits-skill-fc-7', 'mania-skill-fc-7');
|
||||||
update achievements set cond = 'score.perfect and 8 <= score.sr < 9' where file in ('osu-skill-fc-8', 'taiko-skill-fc-8', 'fruits-skill-fc-8', 'mania-skill-fc-8');
|
update achievements set cond = 'score.perfect and 8 <= score.sr < 9' where file in ('osu-skill-fc-8', 'taiko-skill-fc-8', 'fruits-skill-fc-8', 'mania-skill-fc-8');
|
||||||
update achievements set cond = 'score.perfect and 9 <= score.sr < 10' where file = 'osu-skill-fc-9';
|
update achievements set cond = 'score.perfect and 9 <= score.sr < 10' where file = 'osu-skill-fc-9';
|
||||||
update achievements set cond = 'score.perfect and 10 <= score.sr < 11' where file = 'osu-skill-fc-10';
|
update achievements set cond = 'score.perfect and 10 <= score.sr < 11' where file = 'osu-skill-fc-10';
|
||||||
|
|
||||||
update achievements set cond = '500 <= score.max_combo < 750' where file = 'osu-combo-500';
|
update achievements set cond = '500 <= score.max_combo < 750' where file = 'osu-combo-500';
|
||||||
update achievements set cond = '750 <= score.max_combo < 1000' where file = 'osu-combo-750';
|
update achievements set cond = '750 <= score.max_combo < 1000' where file = 'osu-combo-750';
|
||||||
update achievements set cond = '1000 <= score.max_combo < 2000' where file = 'osu-combo-1000';
|
update achievements set cond = '1000 <= score.max_combo < 2000' where file = 'osu-combo-1000';
|
||||||
update achievements set cond = '2000 <= score.max_combo' where file = 'osu-combo-2000';
|
update achievements set cond = '2000 <= score.max_combo' where file = 'osu-combo-2000';
|
||||||
|
|
||||||
# v3.2.6
|
# v3.2.6
|
||||||
alter table stats change maxcombo_vn_std max_combo_vn_std int unsigned default 0 not null;
|
alter table stats change maxcombo_vn_std max_combo_vn_std int unsigned default 0 not null;
|
||||||
alter table stats change maxcombo_vn_taiko max_combo_vn_taiko int unsigned default 0 not null;
|
alter table stats change maxcombo_vn_taiko max_combo_vn_taiko int unsigned default 0 not null;
|
||||||
alter table stats change maxcombo_vn_catch max_combo_vn_catch int unsigned default 0 not null;
|
alter table stats change maxcombo_vn_catch max_combo_vn_catch int unsigned default 0 not null;
|
||||||
alter table stats change maxcombo_vn_mania max_combo_vn_mania int unsigned default 0 not null;
|
alter table stats change maxcombo_vn_mania max_combo_vn_mania int unsigned default 0 not null;
|
||||||
alter table stats change maxcombo_rx_std max_combo_rx_std int unsigned default 0 not null;
|
alter table stats change maxcombo_rx_std max_combo_rx_std int unsigned default 0 not null;
|
||||||
alter table stats change maxcombo_rx_taiko max_combo_rx_taiko int unsigned default 0 not null;
|
alter table stats change maxcombo_rx_taiko max_combo_rx_taiko int unsigned default 0 not null;
|
||||||
alter table stats change maxcombo_rx_catch max_combo_rx_catch int unsigned default 0 not null;
|
alter table stats change maxcombo_rx_catch max_combo_rx_catch int unsigned default 0 not null;
|
||||||
alter table stats change maxcombo_ap_std max_combo_ap_std int unsigned default 0 not null;
|
alter table stats change maxcombo_ap_std max_combo_ap_std int unsigned default 0 not null;
|
||||||
|
|
||||||
# v3.2.7
|
# v3.2.7
|
||||||
drop table if exists user_hashes;
|
drop table if exists user_hashes;
|
||||||
|
|
||||||
# v3.3.0
|
# v3.3.0
|
||||||
rename table friendships to relationships;
|
rename table friendships to relationships;
|
||||||
alter table relationships add type enum('friend', 'block') not null;
|
alter table relationships add type enum('friend', 'block') not null;
|
||||||
|
|
||||||
# v3.3.1
|
# v3.3.1
|
||||||
create table ingame_logins
|
create table ingame_logins
|
||||||
(
|
(
|
||||||
id int auto_increment
|
id int auto_increment
|
||||||
primary key,
|
primary key,
|
||||||
userid int not null,
|
userid int not null,
|
||||||
ip varchar(45) not null comment 'maxlen for ipv6',
|
ip varchar(45) not null comment 'maxlen for ipv6',
|
||||||
osu_ver date not null,
|
osu_ver date not null,
|
||||||
osu_stream varchar(11) not null,
|
osu_stream varchar(11) not null,
|
||||||
datetime datetime not null
|
datetime datetime not null
|
||||||
);
|
);
|
||||||
|
|
||||||
# v3.3.7
|
# v3.3.7
|
||||||
update achievements set cond = CONCAT(cond, ' and mode_vn == 0') where mode = 0;
|
update achievements set cond = CONCAT(cond, ' and mode_vn == 0') where mode = 0;
|
||||||
update achievements set cond = CONCAT(cond, ' and mode_vn == 1') where mode = 1;
|
update achievements set cond = CONCAT(cond, ' and mode_vn == 1') where mode = 1;
|
||||||
update achievements set cond = CONCAT(cond, ' and mode_vn == 2') where mode = 2;
|
update achievements set cond = CONCAT(cond, ' and mode_vn == 2') where mode = 2;
|
||||||
update achievements set cond = CONCAT(cond, ' and mode_vn == 3') where mode = 3;
|
update achievements set cond = CONCAT(cond, ' and mode_vn == 3') where mode = 3;
|
||||||
alter table achievements drop column mode;
|
alter table achievements drop column mode;
|
||||||
|
|
||||||
# v3.3.8
|
# v3.3.8
|
||||||
create table mapsets
|
create table mapsets
|
||||||
(
|
(
|
||||||
server enum('osu!', 'gulag') default 'osu!' not null,
|
server enum('osu!', 'gulag') default 'osu!' not null,
|
||||||
id int not null,
|
id int not null,
|
||||||
last_osuapi_check datetime default CURRENT_TIMESTAMP not null,
|
last_osuapi_check datetime default CURRENT_TIMESTAMP not null,
|
||||||
primary key (server, id),
|
primary key (server, id),
|
||||||
constraint nmapsets_id_uindex
|
constraint nmapsets_id_uindex
|
||||||
unique (id)
|
unique (id)
|
||||||
);
|
);
|
||||||
|
|
||||||
# v3.4.1
|
# v3.4.1
|
||||||
alter table maps add filename varchar(256) charset utf8 not null after creator;
|
alter table maps add filename varchar(256) charset utf8 not null after creator;
|
||||||
|
|
||||||
# v3.5.2
|
# v3.5.2
|
||||||
alter table scores_vn add online_checksum char(32) not null;
|
alter table scores_vn add online_checksum char(32) not null;
|
||||||
alter table scores_rx add online_checksum char(32) not null;
|
alter table scores_rx add online_checksum char(32) not null;
|
||||||
alter table scores_ap add online_checksum char(32) not null;
|
alter table scores_ap add online_checksum char(32) not null;
|
||||||
|
|
||||||
# v4.1.1
|
# v4.1.1
|
||||||
alter table stats add total_hits int unsigned default 0 not null after max_combo;
|
alter table stats add total_hits int unsigned default 0 not null after max_combo;
|
||||||
|
|
||||||
# v4.1.2
|
# v4.1.2
|
||||||
alter table stats add replay_views int unsigned default 0 not null after total_hits;
|
alter table stats add replay_views int unsigned default 0 not null after total_hits;
|
||||||
|
|
||||||
# v4.1.3
|
# v4.1.3
|
||||||
alter table users add preferred_mode int default 0 not null after latest_activity;
|
alter table users add preferred_mode int default 0 not null after latest_activity;
|
||||||
alter table users add play_style int default 0 not null after preferred_mode;
|
alter table users add play_style int default 0 not null after preferred_mode;
|
||||||
alter table users add custom_badge_name varchar(16) charset utf8 null after play_style;
|
alter table users add custom_badge_name varchar(16) charset utf8 null after play_style;
|
||||||
alter table users add custom_badge_icon varchar(64) null after custom_badge_name;
|
alter table users add custom_badge_icon varchar(64) null after custom_badge_name;
|
||||||
alter table users add userpage_content varchar(2048) charset utf8 null after custom_badge_icon;
|
alter table users add userpage_content varchar(2048) charset utf8 null after custom_badge_icon;
|
||||||
|
|
||||||
# v4.2.0
|
# v4.2.0
|
||||||
# please refer to tools/migrate_v420 for further v4.2.0 migrations
|
# please refer to tools/migrate_v420 for further v4.2.0 migrations
|
||||||
update stats set mode = 8 where mode = 7;
|
update stats set mode = 8 where mode = 7;
|
||||||
|
|
||||||
# v4.3.1
|
# v4.3.1
|
||||||
alter table maps change server server enum('osu!', 'private') default 'osu!' not null;
|
alter table maps change server server enum('osu!', 'private') default 'osu!' not null;
|
||||||
alter table mapsets change server server enum('osu!', 'private') default 'osu!' not null;
|
alter table mapsets change server server enum('osu!', 'private') default 'osu!' not null;
|
||||||
|
|
||||||
# v4.4.2
|
# v4.4.2
|
||||||
insert into achievements (id, file, name, `desc`, cond) values (73, 'all-intro-suddendeath', 'Finality', 'High stakes, no regrets.', 'score.mods == 32');
|
insert into achievements (id, file, name, `desc`, cond) values (73, 'all-intro-suddendeath', 'Finality', 'High stakes, no regrets.', 'score.mods == 32');
|
||||||
insert into achievements (id, file, name, `desc`, cond) values (74, 'all-intro-hidden', 'Blindsight', 'I can see just perfectly', 'score.mods & 8');
|
insert into achievements (id, file, name, `desc`, cond) values (74, 'all-intro-hidden', 'Blindsight', 'I can see just perfectly', 'score.mods & 8');
|
||||||
insert into achievements (id, file, name, `desc`, cond) values (75, 'all-intro-perfect', 'Perfectionist', 'Accept nothing but the best.', 'score.mods & 16384');
|
insert into achievements (id, file, name, `desc`, cond) values (75, 'all-intro-perfect', 'Perfectionist', 'Accept nothing but the best.', 'score.mods & 16384');
|
||||||
insert into achievements (id, file, name, `desc`, cond) values (76, 'all-intro-hardrock', 'Rock Around The Clock', "You can\'t stop the rock.", 'score.mods & 16');
|
insert into achievements (id, file, name, `desc`, cond) values (76, 'all-intro-hardrock', 'Rock Around The Clock', "You can\'t stop the rock.", 'score.mods & 16');
|
||||||
insert into achievements (id, file, name, `desc`, cond) values (77, 'all-intro-doubletime', 'Time And A Half', "Having a right ol\' time. One and a half of them, almost.", 'score.mods & 64');
|
insert into achievements (id, file, name, `desc`, cond) values (77, 'all-intro-doubletime', 'Time And A Half', "Having a right ol\' time. One and a half of them, almost.", 'score.mods & 64');
|
||||||
insert into achievements (id, file, name, `desc`, cond) values (78, 'all-intro-flashlight', 'Are You Afraid Of The Dark?', "Harder than it looks, probably because it\'s hard to look.", 'score.mods & 1024');
|
insert into achievements (id, file, name, `desc`, cond) values (78, 'all-intro-flashlight', 'Are You Afraid Of The Dark?', "Harder than it looks, probably because it\'s hard to look.", 'score.mods & 1024');
|
||||||
insert into achievements (id, file, name, `desc`, cond) values (79, 'all-intro-easy', 'Dial It Right Back', 'Sometimes you just want to take it easy.', 'score.mods & 2');
|
insert into achievements (id, file, name, `desc`, cond) values (79, 'all-intro-easy', 'Dial It Right Back', 'Sometimes you just want to take it easy.', 'score.mods & 2');
|
||||||
insert into achievements (id, file, name, `desc`, cond) values (80, 'all-intro-nofail', 'Risk Averse', 'Safety nets are fun!', 'score.mods & 1');
|
insert into achievements (id, file, name, `desc`, cond) values (80, 'all-intro-nofail', 'Risk Averse', 'Safety nets are fun!', 'score.mods & 1');
|
||||||
insert into achievements (id, file, name, `desc`, cond) values (81, 'all-intro-nightcore', 'Sweet Rave Party', 'Founded in the fine tradition of changing things that were just fine as they were.', 'score.mods & 512');
|
insert into achievements (id, file, name, `desc`, cond) values (81, 'all-intro-nightcore', 'Sweet Rave Party', 'Founded in the fine tradition of changing things that were just fine as they were.', 'score.mods & 512');
|
||||||
insert into achievements (id, file, name, `desc`, cond) values (82, 'all-intro-halftime', 'Slowboat', 'You got there. Eventually.', 'score.mods & 256');
|
insert into achievements (id, file, name, `desc`, cond) values (82, 'all-intro-halftime', 'Slowboat', 'You got there. Eventually.', 'score.mods & 256');
|
||||||
insert into achievements (id, file, name, `desc`, cond) values (83, 'all-intro-spunout', 'Burned Out', 'One cannot always spin to win.', 'score.mods & 4096');
|
insert into achievements (id, file, name, `desc`, cond) values (83, 'all-intro-spunout', 'Burned Out', 'One cannot always spin to win.', 'score.mods & 4096');
|
||||||
|
|
||||||
# v4.4.3
|
# v4.4.3
|
||||||
alter table favourites add created_at int default 0 not null;
|
alter table favourites add created_at int default 0 not null;
|
||||||
|
|
||||||
# v4.7.1
|
# v4.7.1
|
||||||
lock tables maps write;
|
lock tables maps write;
|
||||||
alter table maps drop primary key;
|
alter table maps drop primary key;
|
||||||
alter table maps add primary key (id);
|
alter table maps add primary key (id);
|
||||||
alter table maps modify column server enum('osu!', 'private') not null default 'osu!' after id;
|
alter table maps modify column server enum('osu!', 'private') not null default 'osu!' after id;
|
||||||
unlock tables;
|
unlock tables;
|
||||||
|
|
||||||
# v5.0.1
|
# v5.0.1
|
||||||
create index channels_auto_join_index
|
create index channels_auto_join_index
|
||||||
on channels (auto_join);
|
on channels (auto_join);
|
||||||
|
|
||||||
create index maps_set_id_index
|
create index maps_set_id_index
|
||||||
on maps (set_id);
|
on maps (set_id);
|
||||||
create index maps_status_index
|
create index maps_status_index
|
||||||
on maps (status);
|
on maps (status);
|
||||||
create index maps_filename_index
|
create index maps_filename_index
|
||||||
on maps (filename);
|
on maps (filename);
|
||||||
create index maps_plays_index
|
create index maps_plays_index
|
||||||
on maps (plays);
|
on maps (plays);
|
||||||
create index maps_mode_index
|
create index maps_mode_index
|
||||||
on maps (mode);
|
on maps (mode);
|
||||||
create index maps_frozen_index
|
create index maps_frozen_index
|
||||||
on maps (frozen);
|
on maps (frozen);
|
||||||
|
|
||||||
create index scores_map_md5_index
|
create index scores_map_md5_index
|
||||||
on scores (map_md5);
|
on scores (map_md5);
|
||||||
create index scores_score_index
|
create index scores_score_index
|
||||||
on scores (score);
|
on scores (score);
|
||||||
create index scores_pp_index
|
create index scores_pp_index
|
||||||
on scores (pp);
|
on scores (pp);
|
||||||
create index scores_mods_index
|
create index scores_mods_index
|
||||||
on scores (mods);
|
on scores (mods);
|
||||||
create index scores_status_index
|
create index scores_status_index
|
||||||
on scores (status);
|
on scores (status);
|
||||||
create index scores_mode_index
|
create index scores_mode_index
|
||||||
on scores (mode);
|
on scores (mode);
|
||||||
create index scores_play_time_index
|
create index scores_play_time_index
|
||||||
on scores (play_time);
|
on scores (play_time);
|
||||||
create index scores_userid_index
|
create index scores_userid_index
|
||||||
on scores (userid);
|
on scores (userid);
|
||||||
create index scores_online_checksum_index
|
create index scores_online_checksum_index
|
||||||
on scores (online_checksum);
|
on scores (online_checksum);
|
||||||
|
|
||||||
create index stats_mode_index
|
create index stats_mode_index
|
||||||
on stats (mode);
|
on stats (mode);
|
||||||
create index stats_pp_index
|
create index stats_pp_index
|
||||||
on stats (pp);
|
on stats (pp);
|
||||||
create index stats_tscore_index
|
create index stats_tscore_index
|
||||||
on stats (tscore);
|
on stats (tscore);
|
||||||
create index stats_rscore_index
|
create index stats_rscore_index
|
||||||
on stats (rscore);
|
on stats (rscore);
|
||||||
|
|
||||||
create index tourney_pool_maps_mods_slot_index
|
create index tourney_pool_maps_mods_slot_index
|
||||||
on tourney_pool_maps (mods, slot);
|
on tourney_pool_maps (mods, slot);
|
||||||
|
|
||||||
create index user_achievements_achid_index
|
create index user_achievements_achid_index
|
||||||
on user_achievements (achid);
|
on user_achievements (achid);
|
||||||
create index user_achievements_userid_index
|
create index user_achievements_userid_index
|
||||||
on user_achievements (userid);
|
on user_achievements (userid);
|
||||||
|
|
||||||
create index users_priv_index
|
create index users_priv_index
|
||||||
on users (priv);
|
on users (priv);
|
||||||
create index users_clan_id_index
|
create index users_clan_id_index
|
||||||
on users (clan_id);
|
on users (clan_id);
|
||||||
create index users_clan_priv_index
|
create index users_clan_priv_index
|
||||||
on users (clan_priv);
|
on users (clan_priv);
|
||||||
create index users_country_index
|
create index users_country_index
|
||||||
on users (country);
|
on users (country);
|
||||||
|
|
||||||
# v5.2.2
|
# v5.2.2
|
||||||
create index scores_fetch_leaderboard_generic_index
|
create index scores_fetch_leaderboard_generic_index
|
||||||
on scores (map_md5, status, mode);
|
on scores (map_md5, status, mode);
|
||||||
|
|||||||
@@ -1,337 +1,337 @@
|
|||||||
-- Lazer API 数据同步脚本
|
-- Lazer API 数据同步脚本
|
||||||
-- 从现有的 bancho.py 表结构同步数据到新的 lazer 专用表
|
-- 从现有的 bancho.py 表结构同步数据到新的 lazer 专用表
|
||||||
-- 执行此脚本前请确保已执行 add_missing_fields.sql
|
-- 执行此脚本前请确保已执行 add_missing_fields.sql
|
||||||
|
|
||||||
-- ============================================
|
-- ============================================
|
||||||
-- 同步用户基本资料数据
|
-- 同步用户基本资料数据
|
||||||
-- ============================================
|
-- ============================================
|
||||||
|
|
||||||
-- 同步用户扩展资料
|
-- 同步用户扩展资料
|
||||||
INSERT INTO lazer_user_profiles (
|
INSERT INTO lazer_user_profiles (
|
||||||
user_id,
|
user_id,
|
||||||
is_active,
|
is_active,
|
||||||
is_bot,
|
is_bot,
|
||||||
is_deleted,
|
is_deleted,
|
||||||
is_online,
|
is_online,
|
||||||
is_supporter,
|
is_supporter,
|
||||||
is_restricted,
|
is_restricted,
|
||||||
session_verified,
|
session_verified,
|
||||||
has_supported,
|
has_supported,
|
||||||
pm_friends_only,
|
pm_friends_only,
|
||||||
default_group,
|
default_group,
|
||||||
last_visit,
|
last_visit,
|
||||||
join_date,
|
join_date,
|
||||||
profile_colour,
|
profile_colour,
|
||||||
profile_hue,
|
profile_hue,
|
||||||
avatar_url,
|
avatar_url,
|
||||||
cover_url,
|
cover_url,
|
||||||
discord,
|
discord,
|
||||||
twitter,
|
twitter,
|
||||||
website,
|
website,
|
||||||
title,
|
title,
|
||||||
title_url,
|
title_url,
|
||||||
interests,
|
interests,
|
||||||
location,
|
location,
|
||||||
occupation,
|
occupation,
|
||||||
playmode,
|
playmode,
|
||||||
support_level,
|
support_level,
|
||||||
max_blocks,
|
max_blocks,
|
||||||
max_friends,
|
max_friends,
|
||||||
post_count,
|
post_count,
|
||||||
page_html,
|
page_html,
|
||||||
page_raw
|
page_raw
|
||||||
)
|
)
|
||||||
SELECT
|
SELECT
|
||||||
u.id as user_id,
|
u.id as user_id,
|
||||||
-- 基本状态字段 (使用默认值,因为原表没有这些字段)
|
-- 基本状态字段 (使用默认值,因为原表没有这些字段)
|
||||||
1 as is_active,
|
1 as is_active,
|
||||||
CASE WHEN u.name = 'BanchoBot' THEN 1 ELSE 0 END as is_bot,
|
CASE WHEN u.name = 'BanchoBot' THEN 1 ELSE 0 END as is_bot,
|
||||||
0 as is_deleted,
|
0 as is_deleted,
|
||||||
1 as is_online,
|
1 as is_online,
|
||||||
CASE WHEN u.donor_end > UNIX_TIMESTAMP() THEN 1 ELSE 0 END as is_supporter,
|
CASE WHEN u.donor_end > UNIX_TIMESTAMP() THEN 1 ELSE 0 END as is_supporter,
|
||||||
CASE WHEN (u.priv & 1) = 0 THEN 1 ELSE 0 END as is_restricted,
|
CASE WHEN (u.priv & 1) = 0 THEN 1 ELSE 0 END as is_restricted,
|
||||||
0 as session_verified,
|
0 as session_verified,
|
||||||
CASE WHEN u.donor_end > 0 THEN 1 ELSE 0 END as has_supported,
|
CASE WHEN u.donor_end > 0 THEN 1 ELSE 0 END as has_supported,
|
||||||
0 as pm_friends_only,
|
0 as pm_friends_only,
|
||||||
|
|
||||||
-- 基本资料字段
|
-- 基本资料字段
|
||||||
'default' as default_group,
|
'default' as default_group,
|
||||||
CASE WHEN u.latest_activity > 0 THEN FROM_UNIXTIME(u.latest_activity) ELSE NULL END as last_visit,
|
CASE WHEN u.latest_activity > 0 THEN FROM_UNIXTIME(u.latest_activity) ELSE NULL END as last_visit,
|
||||||
CASE WHEN u.creation_time > 0 THEN FROM_UNIXTIME(u.creation_time) ELSE NULL END as join_date,
|
CASE WHEN u.creation_time > 0 THEN FROM_UNIXTIME(u.creation_time) ELSE NULL END as join_date,
|
||||||
NULL as profile_colour,
|
NULL as profile_colour,
|
||||||
NULL as profile_hue,
|
NULL as profile_hue,
|
||||||
|
|
||||||
-- 社交媒体和个人资料字段 (使用默认值)
|
-- 社交媒体和个人资料字段 (使用默认值)
|
||||||
CONCAT('https://a.ppy.sh/', u.id) as avatar_url,
|
CONCAT('https://a.ppy.sh/', u.id) as avatar_url,
|
||||||
CONCAT('https://assets.ppy.sh/user-profile-covers/banners/', u.id, '.jpg') as cover_url,
|
CONCAT('https://assets.ppy.sh/user-profile-covers/banners/', u.id, '.jpg') as cover_url,
|
||||||
NULL as discord,
|
NULL as discord,
|
||||||
NULL as twitter,
|
NULL as twitter,
|
||||||
NULL as website,
|
NULL as website,
|
||||||
u.custom_badge_name as title,
|
u.custom_badge_name as title,
|
||||||
NULL as title_url,
|
NULL as title_url,
|
||||||
NULL as interests,
|
NULL as interests,
|
||||||
CASE WHEN u.country != 'xx' THEN u.country ELSE NULL END as location,
|
CASE WHEN u.country != 'xx' THEN u.country ELSE NULL END as location,
|
||||||
NULL as occupation,
|
NULL as occupation,
|
||||||
|
|
||||||
-- 游戏相关字段
|
-- 游戏相关字段
|
||||||
CASE u.preferred_mode
|
CASE u.preferred_mode
|
||||||
WHEN 0 THEN 'osu'
|
WHEN 0 THEN 'osu'
|
||||||
WHEN 1 THEN 'taiko'
|
WHEN 1 THEN 'taiko'
|
||||||
WHEN 2 THEN 'fruits'
|
WHEN 2 THEN 'fruits'
|
||||||
WHEN 3 THEN 'mania'
|
WHEN 3 THEN 'mania'
|
||||||
ELSE 'osu'
|
ELSE 'osu'
|
||||||
END as playmode,
|
END as playmode,
|
||||||
CASE WHEN u.donor_end > UNIX_TIMESTAMP() THEN 1 ELSE 0 END as support_level,
|
CASE WHEN u.donor_end > UNIX_TIMESTAMP() THEN 1 ELSE 0 END as support_level,
|
||||||
100 as max_blocks,
|
100 as max_blocks,
|
||||||
500 as max_friends,
|
500 as max_friends,
|
||||||
0 as post_count,
|
0 as post_count,
|
||||||
|
|
||||||
-- 页面内容
|
-- 页面内容
|
||||||
u.userpage_content as page_html,
|
u.userpage_content as page_html,
|
||||||
u.userpage_content as page_raw
|
u.userpage_content as page_raw
|
||||||
|
|
||||||
FROM users u
|
FROM users u
|
||||||
ON DUPLICATE KEY UPDATE
|
ON DUPLICATE KEY UPDATE
|
||||||
last_visit = VALUES(last_visit),
|
last_visit = VALUES(last_visit),
|
||||||
join_date = VALUES(join_date),
|
join_date = VALUES(join_date),
|
||||||
is_supporter = VALUES(is_supporter),
|
is_supporter = VALUES(is_supporter),
|
||||||
is_restricted = VALUES(is_restricted),
|
is_restricted = VALUES(is_restricted),
|
||||||
has_supported = VALUES(has_supported),
|
has_supported = VALUES(has_supported),
|
||||||
title = VALUES(title),
|
title = VALUES(title),
|
||||||
location = VALUES(location),
|
location = VALUES(location),
|
||||||
playmode = VALUES(playmode),
|
playmode = VALUES(playmode),
|
||||||
support_level = VALUES(support_level),
|
support_level = VALUES(support_level),
|
||||||
page_html = VALUES(page_html),
|
page_html = VALUES(page_html),
|
||||||
page_raw = VALUES(page_raw);
|
page_raw = VALUES(page_raw);
|
||||||
|
|
||||||
-- 同步用户国家信息
|
-- 同步用户国家信息
|
||||||
INSERT INTO lazer_user_countries (
|
INSERT INTO lazer_user_countries (
|
||||||
user_id,
|
user_id,
|
||||||
code,
|
code,
|
||||||
name
|
name
|
||||||
)
|
)
|
||||||
SELECT
|
SELECT
|
||||||
u.id as user_id,
|
u.id as user_id,
|
||||||
UPPER(u.country) as code,
|
UPPER(u.country) as code,
|
||||||
CASE UPPER(u.country)
|
CASE UPPER(u.country)
|
||||||
WHEN 'CN' THEN 'China'
|
WHEN 'CN' THEN 'China'
|
||||||
WHEN 'US' THEN 'United States'
|
WHEN 'US' THEN 'United States'
|
||||||
WHEN 'JP' THEN 'Japan'
|
WHEN 'JP' THEN 'Japan'
|
||||||
WHEN 'KR' THEN 'South Korea'
|
WHEN 'KR' THEN 'South Korea'
|
||||||
WHEN 'CA' THEN 'Canada'
|
WHEN 'CA' THEN 'Canada'
|
||||||
WHEN 'GB' THEN 'United Kingdom'
|
WHEN 'GB' THEN 'United Kingdom'
|
||||||
WHEN 'DE' THEN 'Germany'
|
WHEN 'DE' THEN 'Germany'
|
||||||
WHEN 'FR' THEN 'France'
|
WHEN 'FR' THEN 'France'
|
||||||
WHEN 'AU' THEN 'Australia'
|
WHEN 'AU' THEN 'Australia'
|
||||||
WHEN 'RU' THEN 'Russia'
|
WHEN 'RU' THEN 'Russia'
|
||||||
ELSE 'Unknown'
|
ELSE 'Unknown'
|
||||||
END as name
|
END as name
|
||||||
FROM users u
|
FROM users u
|
||||||
WHERE u.country IS NOT NULL AND u.country != 'xx'
|
WHERE u.country IS NOT NULL AND u.country != 'xx'
|
||||||
ON DUPLICATE KEY UPDATE
|
ON DUPLICATE KEY UPDATE
|
||||||
code = VALUES(code),
|
code = VALUES(code),
|
||||||
name = VALUES(name);
|
name = VALUES(name);
|
||||||
|
|
||||||
-- 同步用户 Kudosu (使用默认值)
|
-- 同步用户 Kudosu (使用默认值)
|
||||||
INSERT INTO lazer_user_kudosu (
|
INSERT INTO lazer_user_kudosu (
|
||||||
user_id,
|
user_id,
|
||||||
available,
|
available,
|
||||||
total
|
total
|
||||||
)
|
)
|
||||||
SELECT
|
SELECT
|
||||||
u.id as user_id,
|
u.id as user_id,
|
||||||
0 as available,
|
0 as available,
|
||||||
0 as total
|
0 as total
|
||||||
FROM users u
|
FROM users u
|
||||||
ON DUPLICATE KEY UPDATE
|
ON DUPLICATE KEY UPDATE
|
||||||
available = VALUES(available),
|
available = VALUES(available),
|
||||||
total = VALUES(total);
|
total = VALUES(total);
|
||||||
|
|
||||||
-- 同步用户统计计数 (使用默认值)
|
-- 同步用户统计计数 (使用默认值)
|
||||||
INSERT INTO lazer_user_counts (
|
INSERT INTO lazer_user_counts (
|
||||||
user_id,
|
user_id,
|
||||||
beatmap_playcounts_count,
|
beatmap_playcounts_count,
|
||||||
comments_count,
|
comments_count,
|
||||||
favourite_beatmapset_count,
|
favourite_beatmapset_count,
|
||||||
follower_count,
|
follower_count,
|
||||||
graveyard_beatmapset_count,
|
graveyard_beatmapset_count,
|
||||||
guest_beatmapset_count,
|
guest_beatmapset_count,
|
||||||
loved_beatmapset_count,
|
loved_beatmapset_count,
|
||||||
mapping_follower_count,
|
mapping_follower_count,
|
||||||
nominated_beatmapset_count,
|
nominated_beatmapset_count,
|
||||||
pending_beatmapset_count,
|
pending_beatmapset_count,
|
||||||
ranked_beatmapset_count,
|
ranked_beatmapset_count,
|
||||||
ranked_and_approved_beatmapset_count,
|
ranked_and_approved_beatmapset_count,
|
||||||
unranked_beatmapset_count,
|
unranked_beatmapset_count,
|
||||||
scores_best_count,
|
scores_best_count,
|
||||||
scores_first_count,
|
scores_first_count,
|
||||||
scores_pinned_count,
|
scores_pinned_count,
|
||||||
scores_recent_count
|
scores_recent_count
|
||||||
)
|
)
|
||||||
SELECT
|
SELECT
|
||||||
u.id as user_id,
|
u.id as user_id,
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||||
FROM users u
|
FROM users u
|
||||||
ON DUPLICATE KEY UPDATE
|
ON DUPLICATE KEY UPDATE
|
||||||
user_id = VALUES(user_id);
|
user_id = VALUES(user_id);
|
||||||
|
|
||||||
-- ============================================
|
-- ============================================
|
||||||
-- 同步游戏统计数据
|
-- 同步游戏统计数据
|
||||||
-- ============================================
|
-- ============================================
|
||||||
|
|
||||||
-- 从 stats 表同步用户统计数据到 lazer_user_statistics
|
-- 从 stats 表同步用户统计数据到 lazer_user_statistics
|
||||||
INSERT INTO lazer_user_statistics (
|
INSERT INTO lazer_user_statistics (
|
||||||
user_id,
|
user_id,
|
||||||
mode,
|
mode,
|
||||||
count_100,
|
count_100,
|
||||||
count_300,
|
count_300,
|
||||||
count_50,
|
count_50,
|
||||||
count_miss,
|
count_miss,
|
||||||
level_current,
|
level_current,
|
||||||
level_progress,
|
level_progress,
|
||||||
global_rank,
|
global_rank,
|
||||||
country_rank,
|
country_rank,
|
||||||
pp,
|
pp,
|
||||||
ranked_score,
|
ranked_score,
|
||||||
hit_accuracy,
|
hit_accuracy,
|
||||||
total_score,
|
total_score,
|
||||||
total_hits,
|
total_hits,
|
||||||
maximum_combo,
|
maximum_combo,
|
||||||
play_count,
|
play_count,
|
||||||
play_time,
|
play_time,
|
||||||
replays_watched_by_others,
|
replays_watched_by_others,
|
||||||
is_ranked,
|
is_ranked,
|
||||||
grade_ss,
|
grade_ss,
|
||||||
grade_ssh,
|
grade_ssh,
|
||||||
grade_s,
|
grade_s,
|
||||||
grade_sh,
|
grade_sh,
|
||||||
grade_a
|
grade_a
|
||||||
)
|
)
|
||||||
SELECT
|
SELECT
|
||||||
s.id as user_id,
|
s.id as user_id,
|
||||||
CASE s.mode
|
CASE s.mode
|
||||||
WHEN 0 THEN 'osu'
|
WHEN 0 THEN 'osu'
|
||||||
WHEN 1 THEN 'taiko'
|
WHEN 1 THEN 'taiko'
|
||||||
WHEN 2 THEN 'fruits'
|
WHEN 2 THEN 'fruits'
|
||||||
WHEN 3 THEN 'mania'
|
WHEN 3 THEN 'mania'
|
||||||
ELSE 'osu'
|
ELSE 'osu'
|
||||||
END as mode,
|
END as mode,
|
||||||
|
|
||||||
-- 基本命中统计
|
-- 基本命中统计
|
||||||
s.n100 as count_100,
|
s.n100 as count_100,
|
||||||
s.n300 as count_300,
|
s.n300 as count_300,
|
||||||
s.n50 as count_50,
|
s.n50 as count_50,
|
||||||
s.nmiss as count_miss,
|
s.nmiss as count_miss,
|
||||||
|
|
||||||
-- 等级信息
|
-- 等级信息
|
||||||
1 as level_current,
|
1 as level_current,
|
||||||
0 as level_progress,
|
0 as level_progress,
|
||||||
|
|
||||||
-- 排名信息
|
-- 排名信息
|
||||||
NULL as global_rank,
|
NULL as global_rank,
|
||||||
NULL as country_rank,
|
NULL as country_rank,
|
||||||
|
|
||||||
-- PP 和分数
|
-- PP 和分数
|
||||||
s.pp as pp,
|
s.pp as pp,
|
||||||
s.rscore as ranked_score,
|
s.rscore as ranked_score,
|
||||||
CASE WHEN (s.n300 + s.n100 + s.n50 + s.nmiss) > 0
|
CASE WHEN (s.n300 + s.n100 + s.n50 + s.nmiss) > 0
|
||||||
THEN ROUND((s.n300 * 300 + s.n100 * 100 + s.n50 * 50) / ((s.n300 + s.n100 + s.n50 + s.nmiss) * 300) * 100, 2)
|
THEN ROUND((s.n300 * 300 + s.n100 * 100 + s.n50 * 50) / ((s.n300 + s.n100 + s.n50 + s.nmiss) * 300) * 100, 2)
|
||||||
ELSE 0.00
|
ELSE 0.00
|
||||||
END as hit_accuracy,
|
END as hit_accuracy,
|
||||||
s.tscore as total_score,
|
s.tscore as total_score,
|
||||||
(s.n300 + s.n100 + s.n50) as total_hits,
|
(s.n300 + s.n100 + s.n50) as total_hits,
|
||||||
s.max_combo as maximum_combo,
|
s.max_combo as maximum_combo,
|
||||||
|
|
||||||
-- 游戏统计
|
-- 游戏统计
|
||||||
s.plays as play_count,
|
s.plays as play_count,
|
||||||
s.playtime as play_time,
|
s.playtime as play_time,
|
||||||
0 as replays_watched_by_others,
|
0 as replays_watched_by_others,
|
||||||
CASE WHEN s.pp > 0 THEN 1 ELSE 0 END as is_ranked,
|
CASE WHEN s.pp > 0 THEN 1 ELSE 0 END as is_ranked,
|
||||||
|
|
||||||
-- 成绩等级计数
|
-- 成绩等级计数
|
||||||
0 as grade_ss,
|
0 as grade_ss,
|
||||||
0 as grade_ssh,
|
0 as grade_ssh,
|
||||||
0 as grade_s,
|
0 as grade_s,
|
||||||
0 as grade_sh,
|
0 as grade_sh,
|
||||||
0 as grade_a
|
0 as grade_a
|
||||||
|
|
||||||
FROM stats s
|
FROM stats s
|
||||||
WHERE EXISTS (SELECT 1 FROM users u WHERE u.id = s.id)
|
WHERE EXISTS (SELECT 1 FROM users u WHERE u.id = s.id)
|
||||||
ON DUPLICATE KEY UPDATE
|
ON DUPLICATE KEY UPDATE
|
||||||
count_100 = VALUES(count_100),
|
count_100 = VALUES(count_100),
|
||||||
count_300 = VALUES(count_300),
|
count_300 = VALUES(count_300),
|
||||||
count_50 = VALUES(count_50),
|
count_50 = VALUES(count_50),
|
||||||
count_miss = VALUES(count_miss),
|
count_miss = VALUES(count_miss),
|
||||||
pp = VALUES(pp),
|
pp = VALUES(pp),
|
||||||
ranked_score = VALUES(ranked_score),
|
ranked_score = VALUES(ranked_score),
|
||||||
hit_accuracy = VALUES(hit_accuracy),
|
hit_accuracy = VALUES(hit_accuracy),
|
||||||
total_score = VALUES(total_score),
|
total_score = VALUES(total_score),
|
||||||
total_hits = VALUES(total_hits),
|
total_hits = VALUES(total_hits),
|
||||||
maximum_combo = VALUES(maximum_combo),
|
maximum_combo = VALUES(maximum_combo),
|
||||||
play_count = VALUES(play_count),
|
play_count = VALUES(play_count),
|
||||||
play_time = VALUES(play_time),
|
play_time = VALUES(play_time),
|
||||||
is_ranked = VALUES(is_ranked);
|
is_ranked = VALUES(is_ranked);
|
||||||
|
|
||||||
-- ============================================
|
-- ============================================
|
||||||
-- 同步用户成就数据
|
-- 同步用户成就数据
|
||||||
-- ============================================
|
-- ============================================
|
||||||
|
|
||||||
-- 从 user_achievements 表同步数据(如果存在的话)
|
-- 从 user_achievements 表同步数据(如果存在的话)
|
||||||
INSERT IGNORE INTO lazer_user_achievements (
|
INSERT IGNORE INTO lazer_user_achievements (
|
||||||
user_id,
|
user_id,
|
||||||
achievement_id,
|
achievement_id,
|
||||||
achieved_at
|
achieved_at
|
||||||
)
|
)
|
||||||
SELECT
|
SELECT
|
||||||
ua.userid as user_id,
|
ua.userid as user_id,
|
||||||
ua.achid as achievement_id,
|
ua.achid as achievement_id,
|
||||||
NOW() as achieved_at -- 使用当前时间作为获得时间
|
NOW() as achieved_at -- 使用当前时间作为获得时间
|
||||||
FROM user_achievements ua
|
FROM user_achievements ua
|
||||||
WHERE EXISTS (SELECT 1 FROM users u WHERE u.id = ua.userid);
|
WHERE EXISTS (SELECT 1 FROM users u WHERE u.id = ua.userid);
|
||||||
|
|
||||||
-- ============================================
|
-- ============================================
|
||||||
-- 创建基础 OAuth 令牌记录(如果需要的话)
|
-- 创建基础 OAuth 令牌记录(如果需要的话)
|
||||||
-- ============================================
|
-- ============================================
|
||||||
|
|
||||||
-- 注意: OAuth 令牌通常在用户登录时动态创建,这里不需要预先填充
|
-- 注意: OAuth 令牌通常在用户登录时动态创建,这里不需要预先填充
|
||||||
|
|
||||||
-- ============================================
|
-- ============================================
|
||||||
-- 同步完成提示
|
-- 同步完成提示
|
||||||
-- ============================================
|
-- ============================================
|
||||||
|
|
||||||
-- 显示同步统计信息
|
-- 显示同步统计信息
|
||||||
SELECT
|
SELECT
|
||||||
'lazer_user_profiles' as table_name,
|
'lazer_user_profiles' as table_name,
|
||||||
COUNT(*) as synced_records
|
COUNT(*) as synced_records
|
||||||
FROM lazer_user_profiles
|
FROM lazer_user_profiles
|
||||||
UNION ALL
|
UNION ALL
|
||||||
SELECT
|
SELECT
|
||||||
'lazer_user_countries' as table_name,
|
'lazer_user_countries' as table_name,
|
||||||
COUNT(*) as synced_records
|
COUNT(*) as synced_records
|
||||||
FROM lazer_user_countries
|
FROM lazer_user_countries
|
||||||
UNION ALL
|
UNION ALL
|
||||||
SELECT
|
SELECT
|
||||||
'lazer_user_statistics' as table_name,
|
'lazer_user_statistics' as table_name,
|
||||||
COUNT(*) as synced_records
|
COUNT(*) as synced_records
|
||||||
FROM lazer_user_statistics
|
FROM lazer_user_statistics
|
||||||
UNION ALL
|
UNION ALL
|
||||||
SELECT
|
SELECT
|
||||||
'lazer_user_achievements' as table_name,
|
'lazer_user_achievements' as table_name,
|
||||||
COUNT(*) as synced_records
|
COUNT(*) as synced_records
|
||||||
FROM lazer_user_achievements;
|
FROM lazer_user_achievements;
|
||||||
|
|
||||||
-- 显示一些样本数据
|
-- 显示一些样本数据
|
||||||
SELECT
|
SELECT
|
||||||
u.id,
|
u.id,
|
||||||
u.name,
|
u.name,
|
||||||
lup.is_supporter,
|
lup.is_supporter,
|
||||||
lup.playmode,
|
lup.playmode,
|
||||||
luc.code as country_code,
|
luc.code as country_code,
|
||||||
lus.pp,
|
lus.pp,
|
||||||
lus.play_count
|
lus.play_count
|
||||||
FROM users u
|
FROM users u
|
||||||
LEFT JOIN lazer_user_profiles lup ON u.id = lup.user_id
|
LEFT JOIN lazer_user_profiles lup ON u.id = lup.user_id
|
||||||
LEFT JOIN lazer_user_countries luc ON u.id = luc.user_id
|
LEFT JOIN lazer_user_countries luc ON u.id = luc.user_id
|
||||||
LEFT JOIN lazer_user_statistics lus ON u.id = lus.user_id AND lus.mode = 'osu'
|
LEFT JOIN lazer_user_statistics lus ON u.id = lus.user_id AND lus.mode = 'osu'
|
||||||
ORDER BY u.id
|
ORDER BY u.id
|
||||||
LIMIT 10;
|
LIMIT 10;
|
||||||
|
|||||||
1470
requirements.txt
1470
requirements.txt
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user