This commit is contained in:
copyrighttxt
2026-07-06 13:28:00 -04:00
commit 05211f73ef
441 changed files with 94128 additions and 0 deletions
+47
View File
@@ -0,0 +1,47 @@
{% extends '__layout__.html' %}
{% block title %}Redeem{% endblock %}
{% block head %}
<link href="/static/css/settings.css" rel="stylesheet"/> <!-- Its just easier to resuse this-->
<script src="https://challenges.cloudflare.com/turnstile/v0/api.js" async defer></script>
<style>
.text-secondary {
color: rgb(199, 199, 199) !important;
}
</style>
{% endblock %}
{% block content %}
<div id="main">
<div class="settings-container" style="max-width: 700px;">
<h1 class="mb-2">Giftcard Redeem</h1>
{% with messages = get_flashed_messages(with_categories=true) %}
{% if messages %}
<div>
{% for category, message in messages %}
{% if category == 'error': %}
<div class="alert border p-2 text-center alert-danger border-danger">
{{ message }}
</div>
{% endif %}
{% if category == 'success': %}
<div class="alert border p-2 text-center alert-success border-success">
{{ message }}
</div>
{% endif %}
{% endfor %}
</div>
{% endif %}
{% endwith %}
<form method="post">
<input type="text" name="giftcard-key" class="form-control w-100" placeholder="Giftcard Key ( eg. AAAAA-12345-BBBBB-67890-CCCCC )" required>
<div class="d-flex justify-content-end align-items-top mt-2">
<p class="m-0 text-secondary me-1" style="font-size:11px;">Note: If you are redeeming a higher membership than your current one, your expiration date will not be brought over and will be resetted</p>
<div class="cf-turnstile" data-theme="dark" data-sitekey="{{turnstilekey}}"></div>
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/>
<div class="ms-3">
<button type="submit" class="btn btn-primary btn-sm">Redeem</button>
</div>
</div>
</form>
</div>
</div>
{% endblock %}
+136
View File
@@ -0,0 +1,136 @@
from flask import Blueprint, render_template, request, redirect, url_for, flash
from app.models.giftcard_key import GiftcardKey
from app.enums.GiftcardType import GiftcardType
from app.extensions import db, redis_controller, limiter
from app.util import auth, websiteFeatures, turnstile, redislock, membership
from datetime import datetime, timedelta
from app.models.user import User
from app.enums.MembershipType import MembershipType
from app.services import economy
GiftcardRedeemRoute = Blueprint('giftcardredeem', __name__, template_folder='pages')
@GiftcardRedeemRoute.errorhandler(429)
def ratelimit_handler(e):
flash("Please slow down", "error")
return redirect("/giftcard-redeem")
@GiftcardRedeemRoute.route('/giftcard-redeem', methods=['GET'])
@auth.authenticated_required
def giftcard_redeem():
return render_template('giftcardredeem/index.html')
@GiftcardRedeemRoute.route('/giftcard-redeem', methods=['POST'])
@auth.authenticated_required
@limiter.limit("10/minute")
def giftcard_post():
if not websiteFeatures.GetWebsiteFeature("GiftcardRedeem"):
flash("Redeeming giftcards is temporarily disabled", "error")
return redirect("/giftcard-redeem")
GiftcardInput = request.form.get( key="giftcard-key", default=None, type=str)
CFTurnstileResponse = request.form.get( key="cf-turnstile-response", default=None, type=str)
if GiftcardInput is None or CFTurnstileResponse is None:
flash("Please fill in all the fields", "error")
return redirect("/giftcard-redeem")
if not turnstile.VerifyToken(CFTurnstileResponse):
flash("Invalid captcha", "error")
return redirect("/giftcard-redeem")
RedeemLock = redislock.acquire_lock( f"Giftcard_Redeem:{GiftcardInput}", acquire_timeout=20, lock_timeout=1)
GiftcardKeyObject : GiftcardKey = GiftcardKey.query.filter_by(key=GiftcardInput).first()
if GiftcardKeyObject is None:
flash("Invalid giftcard key", "error")
return redirect("/giftcard-redeem")
if GiftcardKeyObject.redeemed_by is not None:
flash("This giftcard has already been redeemed", "error")
return redirect("/giftcard-redeem")
AuthenticatedUser : User = auth.GetCurrentUser()
if GiftcardKeyObject.type == GiftcardType.Outrageous_BuildersClub:
UserCurrentMembership : MembershipType = membership.GetUserMembership(AuthenticatedUser)
if UserCurrentMembership == MembershipType.OutrageousBuildersClub:
membership.IncrementExpirationLength(
AuthenticatedUser,
timedelta(days=(31 * GiftcardKeyObject.value))
)
flash(f"Your OBC membership has been extended by {GiftcardKeyObject.value} months", "success")
else:
membership.GiveUserMembership(
TargetUser = AuthenticatedUser,
Membership = MembershipType.OutrageousBuildersClub,
expiration = timedelta(days=(31 * GiftcardKeyObject.value))
)
flash(f"You have been given OBC membership for {GiftcardKeyObject.value} months", "success")
GiftcardKeyObject.redeemed_by = AuthenticatedUser.id
GiftcardKeyObject.redeemed_at = datetime.utcnow()
db.session.commit()
redislock.release_lock(f"Giftcard_Redeem:{GiftcardInput}", RedeemLock)
return redirect("/giftcard-redeem")
elif GiftcardKeyObject.type == GiftcardType.Turbo_BuildersClub:
UserCurrentMembership : MembershipType = membership.GetUserMembership(AuthenticatedUser)
if UserCurrentMembership == MembershipType.OutrageousBuildersClub:
flash("You cannot downgrade your membership", "error")
return redirect("/giftcard-redeem")
elif UserCurrentMembership == MembershipType.TurboBuildersClub:
membership.IncrementExpirationLength(
AuthenticatedUser,
timedelta(days=(7 * GiftcardKeyObject.value))
)
flash(f"Your TBC membership has been extended by {GiftcardKeyObject.value} weeks", "success")
else:
membership.GiveUserMembership(
TargetUser = AuthenticatedUser,
Membership = MembershipType.TurboBuildersClub,
expiration = timedelta(days=(7 * GiftcardKeyObject.value))
)
flash(f"You have been given TBC membership for {GiftcardKeyObject.value} weeks", "success")
GiftcardKeyObject.redeemed_by = AuthenticatedUser.id
GiftcardKeyObject.redeemed_at = datetime.utcnow()
db.session.commit()
redislock.release_lock(f"Giftcard_Redeem:{GiftcardInput}", RedeemLock)
return redirect("/giftcard-redeem")
elif GiftcardKeyObject.type == GiftcardType.RobuxCurrency:
economy.IncrementTargetBalance(AuthenticatedUser, GiftcardKeyObject.value, 0)
flash(f"You have been given {GiftcardKeyObject.value} robux", "success")
GiftcardKeyObject.redeemed_by = AuthenticatedUser.id
GiftcardKeyObject.redeemed_at = datetime.utcnow()
db.session.commit()
redislock.release_lock(f"Giftcard_Redeem:{GiftcardInput}", RedeemLock)
return redirect("/giftcard-redeem")
elif GiftcardKeyObject.type == GiftcardType.TixCurrency:
economy.IncrementTargetBalance(AuthenticatedUser, GiftcardKeyObject.value, 1)
flash(f"You have been given {GiftcardKeyObject.value} tickets", "success")
GiftcardKeyObject.redeemed_by = AuthenticatedUser.id
GiftcardKeyObject.redeemed_at = datetime.utcnow()
db.session.commit()
redislock.release_lock(f"Giftcard_Redeem:{GiftcardInput}", RedeemLock)
return redirect("/giftcard-redeem")
elif GiftcardKeyObject.type == GiftcardType.Item:
from app.models.userassets import UserAsset
from app.models.asset import Asset
AssetObject : Asset = Asset.query.filter_by(id=GiftcardKeyObject.value).first()
if AssetObject is None:
flash("An issue occured when redeeming this giftcard, please contact support", "error")
return redirect("/giftcard-redeem")
UserAssetObject : UserAsset = UserAsset.query.filter_by(userid=AuthenticatedUser.id, assetid=AssetObject.id).first()
if UserAssetObject is not None:
flash("You already own this item", "error")
return redirect("/giftcard-redeem")
UserAssetObject : UserAsset = UserAsset(
userid = AuthenticatedUser.id,
assetid = AssetObject.id
)
db.session.add(UserAssetObject)
db.session.commit()
flash(f"You have been given the item {AssetObject.name}", "success")
GiftcardKeyObject.redeemed_by = AuthenticatedUser.id
GiftcardKeyObject.redeemed_at = datetime.utcnow()
db.session.commit()
redislock.release_lock(f"Giftcard_Redeem:{GiftcardInput}", RedeemLock)
return redirect("/giftcard-redeem")
else:
flash("An issue occured when redeeming this giftcard, please contact support", "error")
return redirect("/giftcard-redeem")