Merge pull request 'Billing playlimit improvements' (#250) from bugfix/drop_billing_playcount_unique into develop

Reviewed-on: https://gitea.tendokyu.moe/Hay1tsme/artemis/pulls/250
This commit is contained in:
Hay1tsme
2026-07-10 19:57:25 +00:00
5 changed files with 80 additions and 44 deletions

View File

@@ -722,16 +722,19 @@ class BillingServlet:
# Technically if a cab resets it's playcount and then does more plays then the previous
# playcount before a billing checkin occours, we will lose plays equal to the current playcount.
if req.playcnt < last_playct: await self.data.arcade.billing_add_playcount(machine['id'], req.gameid, req.playcnt)
elif req.playcnt == last_playct: pass # No plays since last checkin, skip update
else: await self.data.arcade.billing_add_playcount(machine['id'], req.gameid, req.playcnt - last_playct)
if req.playcnt < last_playct:
await self.data.arcade.billing_add_playcount(machine['id'], req.gameid, req.playcnt)
elif req.playcnt == last_playct:
pass # No plays since last checkin, skip update
else:
await self.data.arcade.billing_add_playcount(machine['id'], req.gameid, req.playcnt - last_playct)
plays = await self.data.arcade.billing_get_playcount_3mo(machine['id'], req.gameid)
if plays is not None and len(plays) > 0:
playhist = ""
for x in range(len(plays) - 1, -1, -1): playhist += f"{plays[x]['year']:04d}{plays[x]['month']:02d}/{plays[x]['playct']}:"
playhist = playhist[:-1]
if plays:
playhist = ":".join(
f"{p['year']:04d}{p['month']:02d}/{p['playct']}"
for p in reversed(plays)
)
for x in range(1, len(req_dict)):
if not req_dict[x]:
@@ -814,10 +817,10 @@ class BillingServlet:
return PlainTextResponse("result=6&waittime=0&linelimit=20\r\n")
playlimit = req.playlimit
while req.playcnt > playlimit:
while req.playcnt >= playlimit - req.nearfull:
playlimit += 1024
nearfull = req.nearfull + (req.billingtype.value * 0x00010000)
nearfull = req.nearfull | (req.billingtype.value << 16)
digest.update(playlimit.to_bytes(4, "little") + kc_serial_bytes)
playlimit_sig = signer.sign(digest).hex()

View File

@@ -18,39 +18,48 @@ depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.create_table('campaign',
sa.Column('id', sa.INTEGER(), nullable=False),
sa.Column('name', sa.TEXT(length=127), nullable=False),
sa.Column('announce_date', sa.TIMESTAMP(), nullable=True),
sa.Column('start_date', sa.TIMESTAMP(), nullable=True),
sa.Column('end_date', sa.TIMESTAMP(), nullable=True),
sa.Column('distrib_start_date', sa.TIMESTAMP(), nullable=True),
sa.Column('distrib_end_date', sa.TIMESTAMP(), nullable=True),
sa.Column('info0', sa.INTEGER(), nullable=True),
sa.Column('info1', sa.INTEGER(), nullable=True),
sa.Column('info2', sa.INTEGER(), nullable=True),
sa.Column('info3', sa.INTEGER(), nullable=True),
sa.PrimaryKeyConstraint('id'),
mysql_charset='utf8mb4'
op.create_table(
'campaign',
sa.Column('id', sa.INTEGER(), nullable=False),
sa.Column('name', sa.String(127), nullable=False),
sa.Column('announce_date', sa.TIMESTAMP(), nullable=True),
sa.Column('start_date', sa.TIMESTAMP(), nullable=True),
sa.Column('end_date', sa.TIMESTAMP(), nullable=True),
sa.Column('distrib_start_date', sa.TIMESTAMP(), nullable=True),
sa.Column('distrib_end_date', sa.TIMESTAMP(), nullable=True),
sa.Column('info0', sa.INTEGER(), nullable=True),
sa.Column('info1', sa.INTEGER(), nullable=True),
sa.Column('info2', sa.INTEGER(), nullable=True),
sa.Column('info3', sa.INTEGER(), nullable=True),
sa.PrimaryKeyConstraint('id'),
mysql_charset='utf8mb4',
)
op.create_table('campaign_game',
sa.Column('campaign_id', sa.INTEGER(), nullable=False),
sa.Column('game_id', sa.TEXT(length=5), nullable=False),
sa.ForeignKeyConstraint(['campaign_id'], ['campaign.id'], onupdate='cascade', ondelete='cascade'),
sa.UniqueConstraint('campaign_id', 'game_id', name='campaign_game_uk'),
mysql_charset='utf8mb4'
op.create_table(
'campaign_game',
sa.Column('campaign_id', sa.INTEGER(), nullable=False),
sa.Column('game_id', sa.String(5), nullable=False),
sa.ForeignKeyConstraint(
['campaign_id'], ['campaign.id'], onupdate='cascade', ondelete='cascade'
),
sa.UniqueConstraint('campaign_id', 'game_id', name='campaign_game_uk'),
mysql_charset='utf8mb4',
)
op.create_table('campaign_progress',
sa.Column('id', sa.BIGINT(), autoincrement=True, nullable=False),
sa.Column('user_id', sa.Integer(), nullable=False),
sa.Column('campaign_id', sa.INTEGER(), nullable=False),
sa.Column('is_participating', sa.INTEGER(), server_default='0', nullable=False),
sa.Column('progress', sa.INTEGER(), server_default='0', nullable=False),
sa.ForeignKeyConstraint(['campaign_id'], ['campaign.id'], onupdate='cascade', ondelete='cascade'),
sa.ForeignKeyConstraint(['user_id'], ['aime_user.id'], onupdate='cascade', ondelete='cascade'),
sa.PrimaryKeyConstraint('id'),
sa.UniqueConstraint('campaign_id', 'user_id', name='campaign_progress_uk'),
mysql_charset='utf8mb4'
op.create_table(
'campaign_progress',
sa.Column('id', sa.BIGINT(), autoincrement=True, nullable=False),
sa.Column('user_id', sa.Integer(), nullable=False),
sa.Column('campaign_id', sa.INTEGER(), nullable=False),
sa.Column('is_participating', sa.INTEGER(), server_default='0', nullable=False),
sa.Column('progress', sa.INTEGER(), server_default='0', nullable=False),
sa.ForeignKeyConstraint(
['campaign_id'], ['campaign.id'], onupdate='cascade', ondelete='cascade'
),
sa.ForeignKeyConstraint(
['user_id'], ['aime_user.id'], onupdate='cascade', ondelete='cascade'
),
sa.PrimaryKeyConstraint('id'),
sa.UniqueConstraint('campaign_id', 'user_id', name='campaign_progress_uk'),
mysql_charset='utf8mb4',
)
# ### end Alembic commands ###

View File

@@ -0,0 +1,24 @@
"""drop billing playcount unique constraint
Revision ID: 63f1fc2e334c
Revises: 1b78db5898f4
Create Date: 2026-07-03 18:01:52.160242
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = '63f1fc2e334c'
down_revision = '1b78db5898f4'
branch_labels = None
depends_on = None
def upgrade():
op.drop_constraint('machine', 'machine_billing_playcount', type_='unique')
def downgrade():
op.create_unique_constraint('machine', 'machine_billing_playcount', ['machine'])

View File

@@ -142,7 +142,7 @@ billing_playct: Table = Table(
"machine",
Integer,
ForeignKey("machine.id", ondelete="cascade", onupdate="cascade"),
nullable=False, unique=True
nullable=False
),
Column("game_id", CHAR(5), nullable=False),
Column("year", INTEGER, nullable=False),

View File

@@ -43,7 +43,7 @@ campaign: Table = Table(
"campaign",
metadata,
Column("id", INTEGER, primary_key=True, nullable=False),
Column("name", TEXT(127), nullable=False),
Column("name", String(127), nullable=False),
Column("announce_date", TIMESTAMP), # None = start announcing now
Column("start_date", TIMESTAMP), # None = start now
Column("end_date", TIMESTAMP), # None = never end
@@ -62,7 +62,7 @@ campaign_game: Table = Table(
"campaign_game",
metadata,
Column("campaign_id", INTEGER, ForeignKey("campaign.id", ondelete="cascade", onupdate="cascade"), nullable=False),
Column("game_id", TEXT(5), nullable=False),
Column("game_id", String(5), nullable=False),
UniqueConstraint("campaign_id", "game_id", name="campaign_game_uk"),
mysql_charset="utf8mb4",
)