diff --git a/core/allnet.py b/core/allnet.py index 821c5de..25581fd 100644 --- a/core/allnet.py +++ b/core/allnet.py @@ -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() diff --git a/core/data/alembic/versions/1b78db5898f4_add_campaigns.py b/core/data/alembic/versions/1b78db5898f4_add_campaigns.py index 847cd68..1435384 100644 --- a/core/data/alembic/versions/1b78db5898f4_add_campaigns.py +++ b/core/data/alembic/versions/1b78db5898f4_add_campaigns.py @@ -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 ### diff --git a/core/data/alembic/versions/63f1fc2e334c_drop_billing_playcount_unique_constraint.py b/core/data/alembic/versions/63f1fc2e334c_drop_billing_playcount_unique_constraint.py new file mode 100644 index 0000000..cba9f02 --- /dev/null +++ b/core/data/alembic/versions/63f1fc2e334c_drop_billing_playcount_unique_constraint.py @@ -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']) diff --git a/core/data/schema/arcade.py b/core/data/schema/arcade.py index d587f71..f10f4cc 100644 --- a/core/data/schema/arcade.py +++ b/core/data/schema/arcade.py @@ -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), diff --git a/core/data/schema/base.py b/core/data/schema/base.py index 7934cd0..d8be455 100644 --- a/core/data/schema/base.py +++ b/core/data/schema/base.py @@ -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", )