forked from Dniel97/artemis
round database implenments
round database implenments idac: database upgrade script idac: unused upgrade script idac: even more round event implements idac: some bugfixes idac: convert round event file to UTF-8 idac: async round info loading idac: last round ranking impl idac: bugfixes idac: bugfixes idac: bugfixes idac: 160~240 number plate implemented idac: remove SQL comment idac: sort things out and make multi-season compatibility
This commit is contained in:
parent
1bb6891411
commit
e50fedad49
5
.gitignore
vendored
5
.gitignore
vendored
@ -160,4 +160,7 @@ config/*
|
|||||||
deliver/*
|
deliver/*
|
||||||
*.gz
|
*.gz
|
||||||
|
|
||||||
dbdump-*.json
|
dbdump-*.json
|
||||||
|
/.vs
|
||||||
|
/titles/id8
|
||||||
|
/titles/idac/battle.py
|
||||||
|
@ -0,0 +1,72 @@
|
|||||||
|
"""idac rounds event info added
|
||||||
|
|
||||||
|
Revision ID: 202d1ada1b39
|
||||||
|
Revises: e4e8d89c9b02
|
||||||
|
Create Date: 2024-05-03 15:51:02.384863
|
||||||
|
|
||||||
|
"""
|
||||||
|
from alembic import op
|
||||||
|
import sqlalchemy as sa
|
||||||
|
from sqlalchemy.dialects import mysql
|
||||||
|
|
||||||
|
|
||||||
|
# revision identifiers, used by Alembic.
|
||||||
|
revision = '202d1ada1b39'
|
||||||
|
down_revision = 'e4e8d89c9b02'
|
||||||
|
branch_labels = None
|
||||||
|
depends_on = None
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade():
|
||||||
|
op.create_table(
|
||||||
|
"idac_round_info",
|
||||||
|
sa.Column("id", sa.Integer(), nullable=False),
|
||||||
|
sa.Column("round_id_in_json", sa.Integer(), nullable=True),
|
||||||
|
sa.Column("name", String(64), nullable=True),
|
||||||
|
sa.Column("season", sa.Integer(), nullable=True),
|
||||||
|
sa.Column(
|
||||||
|
"start_dt",
|
||||||
|
sa.TIMESTAMP(),
|
||||||
|
server_default=sa.text("now()"),
|
||||||
|
nullable=True,
|
||||||
|
),
|
||||||
|
sa.Column(
|
||||||
|
"end_dt",
|
||||||
|
sa.TIMESTAMP(),
|
||||||
|
server_default=sa.text("now()"),
|
||||||
|
nullable=True,
|
||||||
|
),
|
||||||
|
sa.PrimaryKeyConstraint("id"),
|
||||||
|
mysql_charset="utf8mb4",
|
||||||
|
)
|
||||||
|
|
||||||
|
op.create_table(
|
||||||
|
"idac_user_round_info",
|
||||||
|
sa.Column("id", sa.Integer(), nullable=False),
|
||||||
|
sa.Column("user", sa.Integer(), nullable=False),
|
||||||
|
sa.Column("round_id", sa.Integer(), nullable=True),
|
||||||
|
sa.Column("count", sa.Integer(), nullable=True),
|
||||||
|
sa.Column("win", sa.Integer(), nullable=True),
|
||||||
|
sa.Column("point", sa.Integer(), nullable=True),
|
||||||
|
sa.Column(
|
||||||
|
"play_dt",
|
||||||
|
sa.TIMESTAMP(),
|
||||||
|
server_default=sa.text("now()"),
|
||||||
|
nullable=True,
|
||||||
|
),
|
||||||
|
sa.ForeignKeyConstraint(
|
||||||
|
["user"], ["aime_user.id"], onupdate="cascade", ondelete="cascade"
|
||||||
|
),
|
||||||
|
sa.ForeignKeyConstraint(
|
||||||
|
["round_id"], ["idac_round_info.id"], onupdate="cascade", ondelete="cascade"
|
||||||
|
),
|
||||||
|
sa.PrimaryKeyConstraint("id"),
|
||||||
|
sa.UniqueConstraint(
|
||||||
|
"user", "round_id", name="idac_user_round_info_uk"
|
||||||
|
),
|
||||||
|
mysql_charset="utf8mb4",
|
||||||
|
)
|
||||||
|
|
||||||
|
def downgrade():
|
||||||
|
op.drop_table("idac_round_info")
|
||||||
|
op.drop_table("idac_user_round_info")
|
@ -0,0 +1,39 @@
|
|||||||
|
"""idac plate number lottery added
|
||||||
|
|
||||||
|
Revision ID: 7e98c2c328b1
|
||||||
|
Revises: 202d1ada1b39
|
||||||
|
Create Date: 2024-05-07 12:25:27.606480
|
||||||
|
|
||||||
|
"""
|
||||||
|
from alembic import op
|
||||||
|
import sqlalchemy as sa
|
||||||
|
|
||||||
|
|
||||||
|
# revision identifiers, used by Alembic.
|
||||||
|
revision = '7e98c2c328b1'
|
||||||
|
down_revision = '202d1ada1b39'
|
||||||
|
branch_labels = None
|
||||||
|
depends_on = None
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade():
|
||||||
|
op.create_table(
|
||||||
|
"idac_user_lottery",
|
||||||
|
sa.Column("id", sa.Integer(), nullable=False),
|
||||||
|
sa.Column("user", sa.Integer(), nullable=False),
|
||||||
|
sa.Column("version", sa.Integer(), nullable=False),
|
||||||
|
sa.Column("saved_value", sa.Integer(), nullable=False),
|
||||||
|
sa.Column("lottery_count", sa.Integer(), nullable=False),
|
||||||
|
sa.ForeignKeyConstraint(
|
||||||
|
["user"], ["aime_user.id"], onupdate="cascade", ondelete="cascade"
|
||||||
|
),
|
||||||
|
sa.PrimaryKeyConstraint("id"),
|
||||||
|
sa.UniqueConstraint(
|
||||||
|
"user", "version", name="idac_user_lottery_uk"
|
||||||
|
),
|
||||||
|
mysql_charset="utf8mb4",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def downgrade():
|
||||||
|
op.drop_table("idac_user_lottery")
|
@ -28,3 +28,8 @@ timetrial:
|
|||||||
battle_event:
|
battle_event:
|
||||||
enabled: True
|
enabled: True
|
||||||
enabled_battle_event: "touhou_1st"
|
enabled_battle_event: "touhou_1st"
|
||||||
|
|
||||||
|
round_event:
|
||||||
|
enable: True
|
||||||
|
enabled_round: "S2R2"
|
||||||
|
last_round: "S2R1"
|
@ -149,6 +149,36 @@ class IDACTBattleGiftConfig:
|
|||||||
default="touhou_1st",
|
default="touhou_1st",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
class IDACRoundConfig:
|
||||||
|
def __init__(self, parent: "IDACConfig") -> None:
|
||||||
|
self.__config = parent
|
||||||
|
|
||||||
|
@property
|
||||||
|
def enable(self) -> bool:
|
||||||
|
return CoreConfig.get_config_field(
|
||||||
|
self.__config, "idac", "round_event", "enable", default=True
|
||||||
|
)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def enabled_round(self) -> str:
|
||||||
|
return CoreConfig.get_config_field(
|
||||||
|
self.__config,
|
||||||
|
"idac",
|
||||||
|
"round_event",
|
||||||
|
"enabled_round",
|
||||||
|
default="S1R1",
|
||||||
|
)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def last_round(self) -> str:
|
||||||
|
return CoreConfig.get_config_field(
|
||||||
|
self.__config,
|
||||||
|
"idac",
|
||||||
|
"round_event",
|
||||||
|
"last_round",
|
||||||
|
default="S1R1",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class IDACConfig(dict):
|
class IDACConfig(dict):
|
||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
@ -157,3 +187,4 @@ class IDACConfig(dict):
|
|||||||
self.stamp = IDACStampConfig(self)
|
self.stamp = IDACStampConfig(self)
|
||||||
self.timetrial = IDACTimetrialConfig(self)
|
self.timetrial = IDACTimetrialConfig(self)
|
||||||
self.battle_gift = IDACTBattleGiftConfig(self)
|
self.battle_gift = IDACTBattleGiftConfig(self)
|
||||||
|
self.round_event = IDACRoundConfig(self)
|
||||||
|
183
titles/idac/data/rounds/season2/S2R1.json
Normal file
183
titles/idac/data/rounds/season2/S2R1.json
Normal file
@ -0,0 +1,183 @@
|
|||||||
|
{
|
||||||
|
"round_event_id": 9,
|
||||||
|
"round_event_nm": "シーズン2 特別ラウンド",
|
||||||
|
"start_dt": 1647468000,
|
||||||
|
"end_dt": 1648062000,
|
||||||
|
"round_start_rank": 0,
|
||||||
|
"save_filename": "",
|
||||||
|
"vscount": [
|
||||||
|
{
|
||||||
|
"reward_upper_limit": 30,
|
||||||
|
"reward_lower_limit": 30,
|
||||||
|
"reward": [
|
||||||
|
{
|
||||||
|
"reward_category": 21,
|
||||||
|
"reward_type": 379
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"reward_upper_limit": 10,
|
||||||
|
"reward_lower_limit": 10,
|
||||||
|
"reward": [
|
||||||
|
{
|
||||||
|
"reward_category": 21,
|
||||||
|
"reward_type": 367
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"rank": [
|
||||||
|
{
|
||||||
|
"reward_upper_limit": 1,
|
||||||
|
"reward_lower_limit": 1,
|
||||||
|
"reward": [
|
||||||
|
{
|
||||||
|
"reward_category": 24,
|
||||||
|
"reward_type": 4328
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"reward_upper_limit": 2,
|
||||||
|
"reward_lower_limit": 10,
|
||||||
|
"reward": [
|
||||||
|
{
|
||||||
|
"reward_category": 24,
|
||||||
|
"reward_type": 4329
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"reward_upper_limit": 11,
|
||||||
|
"reward_lower_limit": 50,
|
||||||
|
"reward": [
|
||||||
|
{
|
||||||
|
"reward_category": 24,
|
||||||
|
"reward_type": 4330
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"reward_upper_limit": 51,
|
||||||
|
"reward_lower_limit": 100,
|
||||||
|
"reward": [
|
||||||
|
{
|
||||||
|
"reward_category": 24,
|
||||||
|
"reward_type": 4331
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"reward_upper_limit": 101,
|
||||||
|
"reward_lower_limit": 1000,
|
||||||
|
"reward": [
|
||||||
|
{
|
||||||
|
"reward_category": 24,
|
||||||
|
"reward_type": 4332
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"point": [
|
||||||
|
|
||||||
|
],
|
||||||
|
"playable_course_list": [
|
||||||
|
{
|
||||||
|
"course_id": 0,
|
||||||
|
"course_day": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"course_id": 0,
|
||||||
|
"course_day": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"course_id": 2,
|
||||||
|
"course_day": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"course_id": 2,
|
||||||
|
"course_day": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"course_id": 36,
|
||||||
|
"course_day": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"course_id": 36,
|
||||||
|
"course_day": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"course_id": 38,
|
||||||
|
"course_day": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"course_id": 38,
|
||||||
|
"course_day": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"course_id": 4,
|
||||||
|
"course_day": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"course_id": 4,
|
||||||
|
"course_day": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"course_id": 6,
|
||||||
|
"course_day": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"course_id": 6,
|
||||||
|
"course_day": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"course_id": 12,
|
||||||
|
"course_day": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"course_id": 12,
|
||||||
|
"course_day": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"course_id": 14,
|
||||||
|
"course_day": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"course_id": 14,
|
||||||
|
"course_day": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"course_id": 8,
|
||||||
|
"course_day": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"course_id": 8,
|
||||||
|
"course_day": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"course_id": 10,
|
||||||
|
"course_day": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"course_id": 10,
|
||||||
|
"course_day": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"course_id": 16,
|
||||||
|
"course_day": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"course_id": 16,
|
||||||
|
"course_day": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"course_id": 18,
|
||||||
|
"course_day": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"course_id": 18,
|
||||||
|
"course_day": 1
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
229
titles/idac/data/rounds/season2/S2R2.json
Normal file
229
titles/idac/data/rounds/season2/S2R2.json
Normal file
@ -0,0 +1,229 @@
|
|||||||
|
{
|
||||||
|
"round_event_id": 10,
|
||||||
|
"round_event_nm": "シーズン2 2ndラウンド",
|
||||||
|
"start_dt": 1648072800,
|
||||||
|
"end_dt": 1651086000,
|
||||||
|
"round_start_rank": 0,
|
||||||
|
"save_filename": "",
|
||||||
|
"vscount": [
|
||||||
|
{
|
||||||
|
"reward_upper_limit": 180,
|
||||||
|
"reward_lower_limit": 180,
|
||||||
|
"reward": [
|
||||||
|
{
|
||||||
|
"reward_category": 21,
|
||||||
|
"reward_type": 462
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"reward_upper_limit": 120,
|
||||||
|
"reward_lower_limit": 120,
|
||||||
|
"reward": [
|
||||||
|
{
|
||||||
|
"reward_category": 21,
|
||||||
|
"reward_type": 461
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"reward_upper_limit": 80,
|
||||||
|
"reward_lower_limit": 80,
|
||||||
|
"reward": [
|
||||||
|
{
|
||||||
|
"reward_category": 22,
|
||||||
|
"reward_type": 516
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"reward_upper_limit": 40,
|
||||||
|
"reward_lower_limit": 40,
|
||||||
|
"reward": [
|
||||||
|
{
|
||||||
|
"reward_category": 21,
|
||||||
|
"reward_type": 484
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"reward_upper_limit": 10,
|
||||||
|
"reward_lower_limit": 10,
|
||||||
|
"reward": [
|
||||||
|
{
|
||||||
|
"reward_category": 21,
|
||||||
|
"reward_type": 483
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"rank": [
|
||||||
|
{
|
||||||
|
"reward_upper_limit": 1,
|
||||||
|
"reward_lower_limit": 1,
|
||||||
|
"reward": [
|
||||||
|
{
|
||||||
|
"reward_category": 24,
|
||||||
|
"reward_type": 4333
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"reward_upper_limit": 2,
|
||||||
|
"reward_lower_limit": 10,
|
||||||
|
"reward": [
|
||||||
|
{
|
||||||
|
"reward_category": 24,
|
||||||
|
"reward_type": 4334
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"reward_upper_limit": 11,
|
||||||
|
"reward_lower_limit": 50,
|
||||||
|
"reward": [
|
||||||
|
{
|
||||||
|
"reward_category": 24,
|
||||||
|
"reward_type": 4335
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"reward_upper_limit": 51,
|
||||||
|
"reward_lower_limit": 100,
|
||||||
|
"reward": [
|
||||||
|
{
|
||||||
|
"reward_category": 24,
|
||||||
|
"reward_type": 4336
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"reward_upper_limit": 101,
|
||||||
|
"reward_lower_limit": 1000,
|
||||||
|
"reward": [
|
||||||
|
{
|
||||||
|
"reward_category": 24,
|
||||||
|
"reward_type": 4337
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"point": [
|
||||||
|
|
||||||
|
],
|
||||||
|
"playable_course_list": [
|
||||||
|
{
|
||||||
|
"course_id": 4,
|
||||||
|
"course_day": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"course_id": 4,
|
||||||
|
"course_day": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"course_id": 6,
|
||||||
|
"course_day": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"course_id": 6,
|
||||||
|
"course_day": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"course_id": 12,
|
||||||
|
"course_day": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"course_id": 12,
|
||||||
|
"course_day": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"course_id": 14,
|
||||||
|
"course_day": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"course_id": 14,
|
||||||
|
"course_day": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"course_id": 16,
|
||||||
|
"course_day": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"course_id": 16,
|
||||||
|
"course_day": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"course_id": 18,
|
||||||
|
"course_day": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"course_id": 18,
|
||||||
|
"course_day": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"course_id": 20,
|
||||||
|
"course_day": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"course_id": 20,
|
||||||
|
"course_day": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"course_id": 22,
|
||||||
|
"course_day": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"course_id": 22,
|
||||||
|
"course_day": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"course_id": 24,
|
||||||
|
"course_day": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"course_id": 24,
|
||||||
|
"course_day": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"course_id": 26,
|
||||||
|
"course_day": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"course_id": 26,
|
||||||
|
"course_day": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"course_id": 44,
|
||||||
|
"course_day": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"course_id": 44,
|
||||||
|
"course_day": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"course_id": 46,
|
||||||
|
"course_day": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"course_id": 46,
|
||||||
|
"course_day": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"course_id": 48,
|
||||||
|
"course_day": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"course_id": 48,
|
||||||
|
"course_day": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"course_id": 50,
|
||||||
|
"course_day": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"course_id": 50,
|
||||||
|
"course_day": 1
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
@ -2,6 +2,8 @@ from core.data import Data
|
|||||||
from core.config import CoreConfig
|
from core.config import CoreConfig
|
||||||
from titles.idac.schema.profile import IDACProfileData
|
from titles.idac.schema.profile import IDACProfileData
|
||||||
from titles.idac.schema.item import IDACItemData
|
from titles.idac.schema.item import IDACItemData
|
||||||
|
from titles.idac.schema.rounds import IDACOnlineRounds
|
||||||
|
from titles.idac.schema.factory import IDACFactoryData
|
||||||
|
|
||||||
|
|
||||||
class IDACData(Data):
|
class IDACData(Data):
|
||||||
@ -10,3 +12,5 @@ class IDACData(Data):
|
|||||||
|
|
||||||
self.profile = IDACProfileData(cfg, self.session)
|
self.profile = IDACProfileData(cfg, self.session)
|
||||||
self.item = IDACItemData(cfg, self.session)
|
self.item = IDACItemData(cfg, self.session)
|
||||||
|
self.rounds = IDACOnlineRounds(cfg, self.session)
|
||||||
|
self.factory = IDACFactoryData(cfg, self.session)
|
||||||
|
60
titles/idac/schema/factory.py
Normal file
60
titles/idac/schema/factory.py
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
from typing import Dict, Optional, List
|
||||||
|
from sqlalchemy import (
|
||||||
|
Table,
|
||||||
|
Column,
|
||||||
|
UniqueConstraint,
|
||||||
|
PrimaryKeyConstraint,
|
||||||
|
and_,
|
||||||
|
update,
|
||||||
|
)
|
||||||
|
from sqlalchemy.types import Integer, String, TIMESTAMP, Boolean, JSON
|
||||||
|
from sqlalchemy.schema import ForeignKey
|
||||||
|
from sqlalchemy.engine import Row
|
||||||
|
from sqlalchemy.sql import func, select
|
||||||
|
from sqlalchemy.dialects.mysql import insert
|
||||||
|
|
||||||
|
from core.data.schema import BaseData, metadata
|
||||||
|
|
||||||
|
lottery = Table(
|
||||||
|
"idac_user_lottery",
|
||||||
|
metadata,
|
||||||
|
Column("id", Integer, primary_key=True, nullable=False),
|
||||||
|
Column("user", ForeignKey("aime_user.id", ondelete="cascade", onupdate="cascade")),
|
||||||
|
Column("version", Integer, nullable=False),
|
||||||
|
Column("saved_value", Integer, nullable=False),
|
||||||
|
Column("lottery_count", Integer, nullable=False),
|
||||||
|
UniqueConstraint("user", "version", name="idac_user_lottery_uk"),
|
||||||
|
mysql_charset="utf8mb4",
|
||||||
|
)
|
||||||
|
|
||||||
|
class IDACFactoryData(BaseData):
|
||||||
|
async def get_lottery(self, aime_id: int, version: int) -> Optional[Row]:
|
||||||
|
sql = select(lottery).where(
|
||||||
|
and_(
|
||||||
|
lottery.c.user == aime_id,
|
||||||
|
lottery.c.version == version
|
||||||
|
)
|
||||||
|
)
|
||||||
|
result = await self.execute(sql)
|
||||||
|
if result is None:
|
||||||
|
return None
|
||||||
|
return result.fetchone()
|
||||||
|
|
||||||
|
async def put_lottery(
|
||||||
|
self, aime_id: int, version: int, saved_value: int, lottery_count: int
|
||||||
|
) -> Optional[int]:
|
||||||
|
|
||||||
|
lottery_data = {}
|
||||||
|
lottery_data["user"] = aime_id
|
||||||
|
lottery_data["version"] = version
|
||||||
|
lottery_data["saved_value"] = saved_value
|
||||||
|
lottery_data["lottery_count"] = lottery_count
|
||||||
|
|
||||||
|
sql = insert(lottery).values(**lottery_data)
|
||||||
|
conflict = sql.on_duplicate_key_update(**lottery_data)
|
||||||
|
result = await self.execute(conflict)
|
||||||
|
|
||||||
|
if result is None:
|
||||||
|
self.logger.warn(f"put_lottery: Failed to update! aime_id: {aime_id}")
|
||||||
|
return None
|
||||||
|
return result.lastrowid
|
138
titles/idac/schema/rounds.py
Normal file
138
titles/idac/schema/rounds.py
Normal file
@ -0,0 +1,138 @@
|
|||||||
|
from typing import Dict, List, Optional
|
||||||
|
from sqlalchemy import Table, Column, UniqueConstraint, PrimaryKeyConstraint, and_, update
|
||||||
|
from sqlalchemy.types import Integer, String, TIMESTAMP, Boolean, JSON, BigInteger
|
||||||
|
from sqlalchemy.engine.base import Connection
|
||||||
|
from sqlalchemy.schema import ForeignKey
|
||||||
|
from sqlalchemy.sql import func, select
|
||||||
|
from sqlalchemy.engine import Row
|
||||||
|
from sqlalchemy.dialects.mysql import insert
|
||||||
|
|
||||||
|
from core.data.schema import BaseData, metadata
|
||||||
|
from core.config import CoreConfig
|
||||||
|
import datetime
|
||||||
|
|
||||||
|
round_details = Table(
|
||||||
|
"idac_round_info",
|
||||||
|
metadata,
|
||||||
|
Column("id", Integer, primary_key=True, nullable=False),
|
||||||
|
Column("round_id_in_json", Integer),
|
||||||
|
Column("name", String(64)),
|
||||||
|
Column("season", Integer),
|
||||||
|
Column("start_dt", TIMESTAMP, server_default=func.now()),
|
||||||
|
Column("end_dt", TIMESTAMP, server_default=func.now()),
|
||||||
|
mysql_charset="utf8mb4",
|
||||||
|
)
|
||||||
|
|
||||||
|
round_info = Table(
|
||||||
|
"idac_user_round_info",
|
||||||
|
metadata,
|
||||||
|
Column("id", Integer, primary_key=True, nullable=False),
|
||||||
|
Column("user", ForeignKey("aime_user.id", ondelete="cascade", onupdate="cascade")),
|
||||||
|
Column("round_id", ForeignKey("idac_round_info.id", ondelete="cascade", onupdate="cascade")),
|
||||||
|
Column("count", Integer),
|
||||||
|
Column("win", Integer),
|
||||||
|
Column("point", Integer),
|
||||||
|
Column("play_dt", TIMESTAMP, server_default=func.now()),
|
||||||
|
UniqueConstraint("user", "round_id", name="idac_user_round_info_uk"),
|
||||||
|
mysql_charset="utf8mb4",
|
||||||
|
)
|
||||||
|
|
||||||
|
class IDACOnlineRounds(BaseData):
|
||||||
|
# get player's ranking from a specified round event
|
||||||
|
async def get_round_rank_by_id(self, aime_id: int, round_event_id: int) -> Optional[Row]:
|
||||||
|
subquery = (
|
||||||
|
select([func.group_concat(func.concat(round_info.c.user, '|', round_info.c.point),order_by=[round_info.c.point.desc(), round_info.c.play_dt])])
|
||||||
|
.select_from(round_info)
|
||||||
|
.where(round_info.c.round_id == round_event_id)
|
||||||
|
.as_scalar()
|
||||||
|
)
|
||||||
|
|
||||||
|
sql = (
|
||||||
|
select([func.find_in_set(func.concat(round_info.c.user, '|', round_info.c.point), subquery.label('rank'))])
|
||||||
|
.select_from(round_info)
|
||||||
|
.where(
|
||||||
|
and_(
|
||||||
|
round_info.c.user == aime_id,
|
||||||
|
round_info.c.round_id == round_event_id
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
result = await self.execute(sql)
|
||||||
|
if result is None:
|
||||||
|
return None
|
||||||
|
return result.fetchone()
|
||||||
|
|
||||||
|
|
||||||
|
# get player's info from a specified round event
|
||||||
|
async def get_round_info_by_id(self, aime_id: int, round_event_id: int) -> Optional[Row]:
|
||||||
|
sql = select(round_info).where(
|
||||||
|
and_(
|
||||||
|
round_info.c.user == aime_id,
|
||||||
|
round_info.c.round_id == round_event_id
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
result = await self.execute(sql)
|
||||||
|
if result is None:
|
||||||
|
return None
|
||||||
|
return result.fetchone()
|
||||||
|
|
||||||
|
# get top 5 of a specified round event
|
||||||
|
async def get_round_top_five(self, round_event_id: int) -> Optional[Row]:
|
||||||
|
subquery = (
|
||||||
|
select([func.group_concat(func.concat(round_info.c.user, '|', round_info.c.point),order_by=[round_info.c.point.desc(), round_info.c.play_dt])])
|
||||||
|
.select_from(round_info)
|
||||||
|
.where(round_info.c.round_id == round_event_id)
|
||||||
|
.as_scalar()
|
||||||
|
)
|
||||||
|
|
||||||
|
sql = (
|
||||||
|
select([func.find_in_set(func.concat(round_info.c.user, '|', round_info.c.point), subquery.label('rank'))], round_info.c.user)
|
||||||
|
.select_from(round_info)
|
||||||
|
.where(round_info.c.round_id == round_event_id)
|
||||||
|
.limit(5)
|
||||||
|
)
|
||||||
|
|
||||||
|
result = await self.execute(sql)
|
||||||
|
if result is None:
|
||||||
|
return None
|
||||||
|
return result.fetchall()
|
||||||
|
|
||||||
|
# save players info to a specified round event
|
||||||
|
async def put_round_event(
|
||||||
|
self, aime_id: int, round_id: int, round_data: Dict
|
||||||
|
) -> Optional[int]:
|
||||||
|
round_data["user"] = aime_id
|
||||||
|
round_data["round_id"] = round_id
|
||||||
|
|
||||||
|
sql = insert(round_info).values(**round_data)
|
||||||
|
conflict = sql.on_duplicate_key_update(**round_data)
|
||||||
|
result = await self.execute(conflict)
|
||||||
|
|
||||||
|
if result is None:
|
||||||
|
self.logger.warn(f"putround: Failed to update! aime_id: {aime_id}")
|
||||||
|
return None
|
||||||
|
return result.lastrowid
|
||||||
|
|
||||||
|
# insert if the event does not exist in database
|
||||||
|
async def _try_load_round_event(
|
||||||
|
self, round_id: int, version: int, round_data: Dict
|
||||||
|
) -> Optional[int]:
|
||||||
|
sql = select(round_details).where(
|
||||||
|
round_details.c.round_id_in_json == round_id
|
||||||
|
)
|
||||||
|
result = await self.execute(sql)
|
||||||
|
rid = result.fetchone()
|
||||||
|
if rid is None:
|
||||||
|
tmp = {}
|
||||||
|
tmp["round_id_in_json"] = round_id
|
||||||
|
tmp["name"] = round_data["round_event_nm"]
|
||||||
|
tmp["season"] = version
|
||||||
|
tmp["start_dt"] = datetime.datetime.fromtimestamp(round_data["start_dt"])
|
||||||
|
tmp["end_dt"] = datetime.datetime.fromtimestamp(round_data["end_dt"])
|
||||||
|
sql = insert(round_details).values(**tmp)
|
||||||
|
result = await self.execute(sql)
|
||||||
|
return result.lastrowid
|
||||||
|
return rid["id"]
|
||||||
|
#TODO: get top five players of last round event for Boot/GetConfigData
|
@ -4,6 +4,7 @@ from random import choice, randint
|
|||||||
from typing import Any, Dict, List
|
from typing import Any, Dict, List
|
||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
|
import asyncio
|
||||||
|
|
||||||
from core.config import CoreConfig
|
from core.config import CoreConfig
|
||||||
from core.utils import Utils
|
from core.utils import Utils
|
||||||
@ -60,6 +61,9 @@ class IDACSeason2(IDACBase):
|
|||||||
"timetrial_event_id"
|
"timetrial_event_id"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# load the user configured round event (only one)
|
||||||
|
asyncio.create_task(self._load_round_event())
|
||||||
|
|
||||||
# load the user configured battle gifts (only one)
|
# load the user configured battle gifts (only one)
|
||||||
self.battle_gift_event = None
|
self.battle_gift_event = None
|
||||||
if self.game_config.battle_gift.enable:
|
if self.game_config.battle_gift.enable:
|
||||||
@ -79,6 +83,117 @@ class IDACSeason2(IDACBase):
|
|||||||
) as f:
|
) as f:
|
||||||
self.battle_gift_event = self._fix_dates(json.load(f))
|
self.battle_gift_event = self._fix_dates(json.load(f))
|
||||||
|
|
||||||
|
async def _load_round_event(self):
|
||||||
|
self.round_event_id = 0
|
||||||
|
self.round_event = []
|
||||||
|
self.last_round_event_id = 0
|
||||||
|
self.last_round_event = []
|
||||||
|
self.last_round_event_ranking = []
|
||||||
|
if self.game_config.round_event.enable:
|
||||||
|
# Load current round event
|
||||||
|
round = self.game_config.round_event.enabled_round
|
||||||
|
if round is not None:
|
||||||
|
if not os.path.exists(f"./titles/idac/data/rounds/season{self.version+1}/{round}.json"):
|
||||||
|
self.logger.warning(f"Round info {round} is enabled but json file does not exist!")
|
||||||
|
else:
|
||||||
|
with open(
|
||||||
|
f"./titles/idac/data/rounds/season{self.version+1}/{round}.json", encoding="UTF-8"
|
||||||
|
) as f:
|
||||||
|
self.logger.debug(f"Loading round info {round}...")
|
||||||
|
tmp = json.load(f)
|
||||||
|
self.round_event_id = await self.data.rounds._try_load_round_event(tmp["round_event_id"], self.version, tmp)
|
||||||
|
self.round_event.append(self._fix_dates(tmp))
|
||||||
|
self.logger.debug(f"Loaded round id for database: {self.round_event_id}...")
|
||||||
|
|
||||||
|
# Load last round event
|
||||||
|
round = self.game_config.round_event.last_round
|
||||||
|
if round is not None:
|
||||||
|
if not os.path.exists(f"./titles/idac/data/rounds/season{self.version+1}/{round}.json"):
|
||||||
|
self.logger.warning(f"Round info {round} is enabled but json file does not exist!")
|
||||||
|
else:
|
||||||
|
with open(
|
||||||
|
f"./titles/idac/data/rounds/season{self.version+1}/{round}.json", encoding="UTF-8"
|
||||||
|
) as f:
|
||||||
|
self.logger.debug(f"Loading round info {round}...")
|
||||||
|
tmp = json.load(f)
|
||||||
|
self.last_round_event_id = await self.data.rounds._try_load_round_event(tmp["round_event_id"], self.version, tmp)
|
||||||
|
self.last_round_event.append(tmp)
|
||||||
|
self.logger.debug(f"Loaded round id for database: {self.last_round_event_id}...")
|
||||||
|
|
||||||
|
# Load top five of last round event
|
||||||
|
|
||||||
|
# class LastRoundEventRanking(BaseModel):
|
||||||
|
# round_rank: int
|
||||||
|
# round_point: int
|
||||||
|
# round_play_count: int
|
||||||
|
|
||||||
|
ranking = await self.data.rounds.get_round_top_five(self.last_round_event_id)
|
||||||
|
if ranking is not None:
|
||||||
|
rank_profile = {
|
||||||
|
"round_rank": 0,
|
||||||
|
"round_point": 0,
|
||||||
|
"round_play_count": 0,
|
||||||
|
"username": "DUMMY",
|
||||||
|
"country": 9,
|
||||||
|
"store": self.core_cfg.server.name,
|
||||||
|
"online_battle_rank": 0,
|
||||||
|
"mytitle_id": 0,
|
||||||
|
"mytitle_effect_id": 0,
|
||||||
|
"car_data": [],
|
||||||
|
"user_avatar": []
|
||||||
|
}
|
||||||
|
for user in ranking:
|
||||||
|
# get the user's profile
|
||||||
|
p = await self.data.profile.get_profile(user["user"], self.version)
|
||||||
|
user_data = p._asdict()
|
||||||
|
arcade = await self.data.arcade.get_arcade(user_data["store"])
|
||||||
|
user_data["store_name"] = (
|
||||||
|
self.core_cfg.server.name if arcade is None else arcade["name"]
|
||||||
|
)
|
||||||
|
rank_profile["username"] = user_data["username"]
|
||||||
|
rank_profile["country"] = user_data["country"]
|
||||||
|
rank_profile["store"] = user_data["store_name"]
|
||||||
|
rank_profile["mytitle_id"] = user_data["mytitle_id"]
|
||||||
|
rank_profile["mytitle_effect_id"] = user_data["mytitle_effect_id"]
|
||||||
|
|
||||||
|
# get the user's avatar
|
||||||
|
a = await self.data.profile.get_profile_avatar(user["user"])
|
||||||
|
avatar_data = a._asdict()
|
||||||
|
del avatar_data["id"]
|
||||||
|
del avatar_data["user"]
|
||||||
|
rank_profile["user_avatar"] = avatar_data
|
||||||
|
|
||||||
|
# get the user's rank
|
||||||
|
r = await self.data.profile.get_profile_rank(user_id, self.version)
|
||||||
|
rank_data = r._asdict()
|
||||||
|
del rank_data["id"]
|
||||||
|
del rank_data["user"]
|
||||||
|
del rank_data["version"]
|
||||||
|
rank_profile["online_battle_rank"] = rank_data["online_battle_rank"]
|
||||||
|
|
||||||
|
# get the user's car
|
||||||
|
cars = await self.data.item.get_cars(self.version, user_id, only_pickup=True)
|
||||||
|
fulltune_count = 0
|
||||||
|
total_car_parts_count = 0
|
||||||
|
car_data = []
|
||||||
|
for car in cars:
|
||||||
|
tmp = car._asdict()
|
||||||
|
del tmp["id"]
|
||||||
|
del tmp["user"]
|
||||||
|
del tmp["version"]
|
||||||
|
car_data.append(tmp)
|
||||||
|
rank_profile["car_data"] = car_data
|
||||||
|
|
||||||
|
# get round info
|
||||||
|
ri = await self.data.rounds.get_round_info_by_id(user["user"], self.last_round_event_id)
|
||||||
|
if ri is not None:
|
||||||
|
ri = ri._asdict()
|
||||||
|
rank_profile["round_rank"] = user["find_in_set_1"]
|
||||||
|
rank_profile["round_point"] = ri["point"]
|
||||||
|
rank_profile["round_play_count"] = ri["count"]
|
||||||
|
|
||||||
|
self.last_round_event_ranking.append(rank_profile)
|
||||||
|
|
||||||
async def handle_alive_get_request(self, data: Dict, headers: Dict):
|
async def handle_alive_get_request(self, data: Dict, headers: Dict):
|
||||||
return {
|
return {
|
||||||
"status_code": "0",
|
"status_code": "0",
|
||||||
@ -170,106 +285,9 @@ class IDACSeason2(IDACBase):
|
|||||||
[self.battle_gift_event] if self.battle_gift_event else []
|
[self.battle_gift_event] if self.battle_gift_event else []
|
||||||
),
|
),
|
||||||
# online battle round event
|
# online battle round event
|
||||||
"round_event": [
|
"round_event": self.round_event,
|
||||||
{
|
"last_round_event": self.last_round_event,
|
||||||
"round_event_id": 30,
|
"last_round_event_ranking": self.last_round_event_ranking,
|
||||||
"round_event_nm": f"{self.core_cfg.server.name} Event",
|
|
||||||
"start_dt": int(
|
|
||||||
datetime.strptime("2023-01-01", "%Y-%m-%d").timestamp()
|
|
||||||
),
|
|
||||||
"end_dt": int(
|
|
||||||
datetime.strptime("2029-01-01", "%Y-%m-%d").timestamp()
|
|
||||||
),
|
|
||||||
"round_start_rank": 0,
|
|
||||||
"save_filename": "0",
|
|
||||||
# https://info-initialdac.sega.jp/1898/
|
|
||||||
"vscount": [
|
|
||||||
{
|
|
||||||
"reward_upper_limit": 10,
|
|
||||||
"reward_lower_limit": 10,
|
|
||||||
"reward": [{"reward_category": 21, "reward_type": 483}],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"reward_upper_limit": 40,
|
|
||||||
"reward_lower_limit": 40,
|
|
||||||
"reward": [{"reward_category": 21, "reward_type": 484}],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"reward_upper_limit": 80,
|
|
||||||
"reward_lower_limit": 80,
|
|
||||||
"reward": [{"reward_category": 22, "reward_type": 516}],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"reward_upper_limit": 120,
|
|
||||||
"reward_lower_limit": 120,
|
|
||||||
"reward": [{"reward_category": 21, "reward_type": 461}],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"reward_upper_limit": 180,
|
|
||||||
"reward_lower_limit": 180,
|
|
||||||
"reward": [{"reward_category": 21, "reward_type": 462}],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
"rank": [],
|
|
||||||
"point": [],
|
|
||||||
"playable_course_list": [
|
|
||||||
{"course_id": 4, "course_day": 0},
|
|
||||||
{"course_id": 4, "course_day": 1},
|
|
||||||
{"course_id": 6, "course_day": 0},
|
|
||||||
{"course_id": 6, "course_day": 1},
|
|
||||||
{"course_id": 8, "course_day": 0},
|
|
||||||
{"course_id": 8, "course_day": 1},
|
|
||||||
{"course_id": 10, "course_day": 0},
|
|
||||||
{"course_id": 10, "course_day": 1},
|
|
||||||
{"course_id": 12, "course_day": 0},
|
|
||||||
{"course_id": 12, "course_day": 1},
|
|
||||||
{"course_id": 14, "course_day": 0},
|
|
||||||
{"course_id": 14, "course_day": 1},
|
|
||||||
{"course_id": 16, "course_day": 0},
|
|
||||||
{"course_id": 16, "course_day": 1},
|
|
||||||
{"course_id": 18, "course_day": 0},
|
|
||||||
{"course_id": 18, "course_day": 1},
|
|
||||||
{"course_id": 20, "course_day": 0},
|
|
||||||
{"course_id": 20, "course_day": 1},
|
|
||||||
{"course_id": 22, "course_day": 0},
|
|
||||||
{"course_id": 22, "course_day": 1},
|
|
||||||
{"course_id": 24, "course_day": 0},
|
|
||||||
{"course_id": 24, "course_day": 1},
|
|
||||||
{"course_id": 26, "course_day": 0},
|
|
||||||
{"course_id": 26, "course_day": 1},
|
|
||||||
{"course_id": 36, "course_day": 0},
|
|
||||||
{"course_id": 36, "course_day": 1},
|
|
||||||
{"course_id": 38, "course_day": 0},
|
|
||||||
{"course_id": 38, "course_day": 1},
|
|
||||||
{"course_id": 40, "course_day": 0},
|
|
||||||
{"course_id": 40, "course_day": 1},
|
|
||||||
{"course_id": 42, "course_day": 0},
|
|
||||||
{"course_id": 42, "course_day": 1},
|
|
||||||
{"course_id": 44, "course_day": 0},
|
|
||||||
{"course_id": 44, "course_day": 1},
|
|
||||||
{"course_id": 46, "course_day": 0},
|
|
||||||
{"course_id": 46, "course_day": 1},
|
|
||||||
{"course_id": 48, "course_day": 0},
|
|
||||||
{"course_id": 48, "course_day": 1},
|
|
||||||
{"course_id": 50, "course_day": 0},
|
|
||||||
{"course_id": 50, "course_day": 1},
|
|
||||||
{"course_id": 52, "course_day": 0},
|
|
||||||
{"course_id": 52, "course_day": 1},
|
|
||||||
{"course_id": 54, "course_day": 0},
|
|
||||||
{"course_id": 54, "course_day": 1},
|
|
||||||
{"course_id": 56, "course_day": 0},
|
|
||||||
{"course_id": 56, "course_day": 1},
|
|
||||||
{"course_id": 58, "course_day": 0},
|
|
||||||
{"course_id": 58, "course_day": 1},
|
|
||||||
{"course_id": 68, "course_day": 0},
|
|
||||||
{"course_id": 68, "course_day": 1},
|
|
||||||
{"course_id": 70, "course_day": 0},
|
|
||||||
{"course_id": 70, "course_day": 1},
|
|
||||||
],
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"last_round_event": [],
|
|
||||||
"last_round_event_ranking": [],
|
|
||||||
"round_event_exp": [],
|
"round_event_exp": [],
|
||||||
"stamp_info": self.stamp_info,
|
"stamp_info": self.stamp_info,
|
||||||
# 0 = use default data, 1+ = server version of timereleasedata response
|
# 0 = use default data, 1+ = server version of timereleasedata response
|
||||||
@ -843,6 +861,57 @@ class IDACSeason2(IDACBase):
|
|||||||
vs_info["course_select_priority"] = data.get("course_select_priority")
|
vs_info["course_select_priority"] = data.get("course_select_priority")
|
||||||
return vs_info
|
return vs_info
|
||||||
|
|
||||||
|
async def _update_round_info(self, user_id: int, round_event_id: int, point: int, win: int) -> Dict:
|
||||||
|
# get the round info data from database
|
||||||
|
round_info = []
|
||||||
|
ri = await self.data.rounds.get_round_info_by_id(user_id, round_event_id)
|
||||||
|
if ri is not None:
|
||||||
|
tmp = ri._asdict()
|
||||||
|
|
||||||
|
del tmp["id"]
|
||||||
|
|
||||||
|
# calculate new round points and info
|
||||||
|
tmp["point"] = 0 if tmp["point"] + point < 1 else tmp["point"] + point
|
||||||
|
tmp["count"] += 1
|
||||||
|
tmp["win"] += win
|
||||||
|
tmp["play_dt"] = datetime.now()
|
||||||
|
|
||||||
|
# update players round info
|
||||||
|
await self.data.rounds.put_round_event(user_id, round_event_id, tmp)
|
||||||
|
|
||||||
|
del tmp["play_dt"]
|
||||||
|
|
||||||
|
# get players new round ranking
|
||||||
|
r = await self.data.rounds.get_round_rank_by_id(user_id, round_event_id)
|
||||||
|
round_ranking = r._asdict()
|
||||||
|
tmp["rank"] = round_ranking["find_in_set_1"] if tmp["point"] > 0 else 0
|
||||||
|
|
||||||
|
# TODO: get players historical earned points
|
||||||
|
tmp["total_round_point"] = 0
|
||||||
|
|
||||||
|
round_info.append(tmp)
|
||||||
|
else:
|
||||||
|
# new player of now-going round event
|
||||||
|
tmp = {}
|
||||||
|
tmp["point"] = 0 if point < 1 else point
|
||||||
|
tmp["count"] = 1
|
||||||
|
tmp["win"] = win
|
||||||
|
tmp["play_dt"] = datetime.now()
|
||||||
|
await self.data.rounds.put_round_event(user_id, round_event_id, tmp)
|
||||||
|
|
||||||
|
del tmp["play_dt"]
|
||||||
|
|
||||||
|
r = await self.data.rounds.get_round_rank_by_id(user_id, round_event_id)
|
||||||
|
round_ranking = r._asdict()
|
||||||
|
tmp["rank"] = round_ranking["find_in_set_1"] if tmp["point"] > 0 else 0
|
||||||
|
|
||||||
|
# TODO: get players historical earned points
|
||||||
|
tmp["total_round_point"] = 0
|
||||||
|
|
||||||
|
round_info.append(tmp)
|
||||||
|
return round_info
|
||||||
|
|
||||||
|
|
||||||
def _choose_gift_id(self) -> Dict:
|
def _choose_gift_id(self) -> Dict:
|
||||||
gift_data = self.battle_gift_event["gift_data"]
|
gift_data = self.battle_gift_event["gift_data"]
|
||||||
# calculate the total_rate based on the first_distribution_rate
|
# calculate the total_rate based on the first_distribution_rate
|
||||||
@ -925,6 +994,25 @@ class IDACSeason2(IDACBase):
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# get the users'd round data
|
||||||
|
|
||||||
|
round_info = []
|
||||||
|
ri = await self.data.rounds.get_round_info_by_id(user_id, self.round_event_id)
|
||||||
|
if ri is not None:
|
||||||
|
r = await self.data.rounds.get_round_rank_by_id(user_id, self.round_event_id)
|
||||||
|
round_ranking = r._asdict()
|
||||||
|
tmp = ri._asdict()
|
||||||
|
del tmp["id"]
|
||||||
|
del tmp["user"]
|
||||||
|
del tmp["round_id"]
|
||||||
|
del tmp["play_dt"]
|
||||||
|
|
||||||
|
tmp["rank"] = round_ranking["find_in_set_1"]
|
||||||
|
# TODO: calculate this
|
||||||
|
tmp["total_round_point"] = 0
|
||||||
|
|
||||||
|
round_info.append(tmp)
|
||||||
|
|
||||||
# get the user's course, required for the "course proeficiency"
|
# get the user's course, required for the "course proeficiency"
|
||||||
courses = await self.data.item.get_courses(user_id)
|
courses = await self.data.item.get_courses(user_id)
|
||||||
course_data = []
|
course_data = []
|
||||||
@ -1206,7 +1294,7 @@ class IDACSeason2(IDACBase):
|
|||||||
# first_distribution related are useless since this is all handled by server
|
# first_distribution related are useless since this is all handled by server
|
||||||
"battle_gift_data": battle_gift_data,
|
"battle_gift_data": battle_gift_data,
|
||||||
"ticket_data": ticket_data,
|
"ticket_data": ticket_data,
|
||||||
"round_event": [],
|
"round_event": round_info,
|
||||||
"last_round_event": [],
|
"last_round_event": [],
|
||||||
"past_round_event": [],
|
"past_round_event": [],
|
||||||
"total_round_point": 0,
|
"total_round_point": 0,
|
||||||
@ -2849,6 +2937,7 @@ class IDACSeason2(IDACBase):
|
|||||||
}
|
}
|
||||||
|
|
||||||
async def handle_user_updateonlinebattle_request(self, data: Dict, headers: Dict):
|
async def handle_user_updateonlinebattle_request(self, data: Dict, headers: Dict):
|
||||||
|
#TODO: voiding cheaters' result. which will need to analysis historical battle results returned by the game.
|
||||||
return {
|
return {
|
||||||
"status_code": "0",
|
"status_code": "0",
|
||||||
"bothwin_penalty": 1,
|
"bothwin_penalty": 1,
|
||||||
@ -2922,18 +3011,12 @@ class IDACSeason2(IDACBase):
|
|||||||
user_id, self.version, {"online_battle_play_count": tips["online_battle_play_count"] + 1}
|
user_id, self.version, {"online_battle_play_count": tips["online_battle_play_count"] + 1}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
round_info = await self._update_round_info(user_id, self.round_event_id, data.pop("round_point"), data.pop("win_flg"))
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"status_code": "0",
|
"status_code": "0",
|
||||||
"vsinfo_data": vs_info,
|
"vsinfo_data": vs_info,
|
||||||
"round_event": [
|
"round_event": round_info,
|
||||||
{
|
|
||||||
"count": 1,
|
|
||||||
"win": 1,
|
|
||||||
"rank": 1,
|
|
||||||
"point": 1,
|
|
||||||
"total_round_point": 1,
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"car_use_count": [],
|
"car_use_count": [],
|
||||||
"maker_use_count": [],
|
"maker_use_count": [],
|
||||||
}
|
}
|
||||||
@ -3026,3 +3109,79 @@ class IDACSeason2(IDACBase):
|
|||||||
"car_use_count": [],
|
"car_use_count": [],
|
||||||
"maker_use_count": [],
|
"maker_use_count": [],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async def handle_factory_numberlotterybefore_request(self, data: Dict, headers: Dict):
|
||||||
|
user_id = headers["session"]
|
||||||
|
win_list = []
|
||||||
|
lottery_count = 0
|
||||||
|
|
||||||
|
p = await self.data.factory.get_lottery(user_id, self.version)
|
||||||
|
if p is not None:
|
||||||
|
lottery_data = p._asdict()
|
||||||
|
lottery_count = lottery_data["lottery_count"]
|
||||||
|
number = 0
|
||||||
|
while number < 10:
|
||||||
|
if int(lottery_data["saved_value"]) & 1:
|
||||||
|
win_list_data = {
|
||||||
|
"m_number_lottery_schedule_no": 1,
|
||||||
|
"win_number": 0
|
||||||
|
}
|
||||||
|
|
||||||
|
win_list_data["win_number"] = number*1111
|
||||||
|
win_list.append(win_list_data)
|
||||||
|
|
||||||
|
lottery_data["saved_value"] = lottery_data["saved_value"] / 2
|
||||||
|
number = number + 1
|
||||||
|
|
||||||
|
return {
|
||||||
|
"status_code": "0",
|
||||||
|
"lottery_info": {
|
||||||
|
"lottery_count": lottery_count,
|
||||||
|
"win_list": win_list
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async def handle_factory_numberlotteryresult_request(self, data: Dict, headers: Dict):
|
||||||
|
user_id = headers["session"]
|
||||||
|
win_number = data.pop("win_number")
|
||||||
|
lottery_count = data.pop("lottery_count")
|
||||||
|
|
||||||
|
# save count if not a lucky number otherwise save all
|
||||||
|
if win_number != 10000:
|
||||||
|
shifted = win_number / 1111
|
||||||
|
number = 1 << int(shifted)
|
||||||
|
p = await self.data.factory.get_lottery(user_id, self.version)
|
||||||
|
if p is not None:
|
||||||
|
lottery_data = p._asdict()
|
||||||
|
saved_value = lottery_data["saved_value"] + number
|
||||||
|
else:
|
||||||
|
saved_value = number
|
||||||
|
|
||||||
|
await self.data.factory.put_lottery(user_id, self.version, saved_value, lottery_count)
|
||||||
|
else:
|
||||||
|
p = await self.data.factory.get_lottery(user_id, self.version)
|
||||||
|
if p is not None:
|
||||||
|
lottery_data = p._asdict()
|
||||||
|
saved_value = lottery_data["saved_value"]
|
||||||
|
else:
|
||||||
|
saved_value = 0
|
||||||
|
await self.data.factory.put_lottery(user_id, self.version, saved_value, lottery_count)
|
||||||
|
|
||||||
|
# save car data if lottery ended
|
||||||
|
car = {}
|
||||||
|
car["style_car_id"] = data.pop("style_car_id")
|
||||||
|
car["l_no"] = data.pop("l_no")
|
||||||
|
if data.pop("isEnd") == 1:
|
||||||
|
await self.data.item.put_car(user_id, self.version, car)
|
||||||
|
|
||||||
|
# save ticket data
|
||||||
|
for ticket in data.pop("ticket_data"):
|
||||||
|
await self.data.item.put_ticket(user_id, ticket)
|
||||||
|
|
||||||
|
# save cash
|
||||||
|
await self.data.profile.put_profile(user_id, self.version, data)
|
||||||
|
|
||||||
|
return {
|
||||||
|
"status_code": "0"
|
||||||
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user