mirror of
https://github.com/qwerfd2/Groove_Coaster_2_Server.git
synced 2025-12-22 03:30:18 +00:00
Update
This commit is contained in:
@@ -9,13 +9,13 @@ from api.database import player_database, accounts, results, devices, whitelists
|
||||
from api.misc import crc32_decimal
|
||||
|
||||
TABLE_MAP = {
|
||||
"accounts": (accounts, ["id", "username", "password_hash", "save_crc", "save_timestamp", "save_id", "coin_mp", "title", "avatar", "created_at", "updated_at"]),
|
||||
"results": (results, ["id", "device_id", "stts", "song_id", "mode", "avatar", "score", "high_score", "play_rslt", "item", "os", "os_ver", "ver", "created_at", "updated_at"]),
|
||||
"devices": (devices, ["device_id", "user_id", "my_stage", "my_avatar", "item", "daily_day", "coin", "lvl", "title", "avatar", "mobile_sum", "arcade_sum", "total_sum", "created_at", "updated_at", "last_login_at"]),
|
||||
"accounts": (accounts, ["id", "username", "password_hash", "save_crc", "save_timestamp", "save_id", "coin_mp", "title", "avatar", "mobile_delta", "arcade_delta", "total_delta", "created_at", "updated_at"]),
|
||||
"results": (results, ["id", "device_id", "stts", "song_id", "mode", "avatar", "score", "high_score", "play_rslt", "item", "os", "os_ver", "ver", "created_at"]),
|
||||
"devices": (devices, ["device_id", "user_id", "my_stage", "my_avatar", "item", "daily_day", "coin", "lvl", "title", "avatar", "created_at", "updated_at", "last_login_at"]),
|
||||
"whitelist": (whitelists, ["id", "device_id"]),
|
||||
"blacklist": (blacklists, ["id", "ban_terms", "reason"]),
|
||||
"batch_tokens": (batch_tokens, ["id", "batch_token", "expire_at", "uses_left", "auth_id", "created_at", "updated_at"]),
|
||||
"binds": (binds, ["id", "user_id", "bind_account", "bind_code", "is_verified", "auth_token", "created_at", "updated_at"]),
|
||||
"binds": (binds, ["id", "user_id", "bind_account", "bind_code", "is_verified", "auth_token", "bind_date"]),
|
||||
"webs": (webs, ["id", "user_id", "permission", "web_token", "last_save_export", "created_at", "updated_at"]),
|
||||
"logs": (logs, ["id", "user_id", "filename", "filesize", "timestamp"]),
|
||||
}
|
||||
|
||||
@@ -28,11 +28,16 @@ async def batch_handler(request: Request):
|
||||
if result['expire_at'] < int(time.time()):
|
||||
return HTMLResponse(content="Token expired", status_code=400)
|
||||
|
||||
if result['uses_left'] <= 0:
|
||||
return HTMLResponse(content="No uses left for this token", status_code=400)
|
||||
uses_left = result['uses_left']
|
||||
if uses_left > 0:
|
||||
uses_left -= 1
|
||||
|
||||
else:
|
||||
uses_left = -1
|
||||
return HTMLResponse(content="No uses left", status_code=400)
|
||||
|
||||
update_query = batch_tokens.update().where(batch_tokens.c.token == token).values(
|
||||
uses_left=result['uses_left'] - 1,
|
||||
uses_left=uses_left,
|
||||
updated_at=datetime.utcnow()
|
||||
)
|
||||
await player_database.execute(update_query)
|
||||
|
||||
@@ -20,7 +20,7 @@ async def serve_file(request: Request):
|
||||
if not filename.endswith(".zip") and not filename.endswith(".pak"):
|
||||
return Response("Unauthorized", status_code=403)
|
||||
|
||||
existing_batch_token = select(batch_tokens).where(batch_tokens.c.batch_token == auth_token)
|
||||
existing_batch_token = select(batch_tokens).where((batch_tokens.c.batch_token == auth_token) & (batch_tokens.c.uses_left > -1))
|
||||
batch_result = await player_database.fetch_one(existing_batch_token)
|
||||
if batch_result:
|
||||
pass
|
||||
|
||||
@@ -6,9 +6,8 @@ import secrets
|
||||
import bcrypt
|
||||
import hashlib
|
||||
import re
|
||||
import aiofiles
|
||||
import xml.etree.ElementTree as ET
|
||||
from config import MODEL, TUNEFILE, SKIN, AUTHORIZATION_NEEDED, AUTHORIZATION_MODE, GRANDFATHERED_ACCOUNT_LIMIT
|
||||
from config import MODEL, TUNEFILE, SKIN, AUTHORIZATION_NEEDED, AUTHORIZATION_MODE, GRANDFATHERED_ACCOUNT_LIMIT, BIND_SALT
|
||||
from api.database import get_bind, check_whitelist, check_blacklist, decrypt_fields_to_user_info, user_id_to_user_info_simple
|
||||
|
||||
FMAX_VER = None
|
||||
@@ -66,7 +65,6 @@ def verify_password(password, hashed_password):
|
||||
if type(hashed_password) == str:
|
||||
hashed_password = hashed_password.encode('utf-8')
|
||||
|
||||
print("hashed_password:", hashed_password)
|
||||
return bcrypt.checkpw(password.encode('utf-8'), hashed_password)
|
||||
|
||||
def is_alphanumeric(username):
|
||||
@@ -281,12 +279,11 @@ async def should_serve_web(user_id):
|
||||
return should_serve
|
||||
|
||||
async def generate_salt(user_id):
|
||||
SALT = "jHENR3wq$zX9@LpO"
|
||||
user_info = await user_id_to_user_info_simple(user_id)
|
||||
user_pw_hash = user_info['password_hash']
|
||||
username = user_info['username']
|
||||
|
||||
combined = f"{username}{user_id}{user_pw_hash}{SALT}".encode('utf-8')
|
||||
combined = f"{username}{user_id}{user_pw_hash}{BIND_SALT}".encode('utf-8')
|
||||
crc32_hash = binascii.crc32(combined) & 0xFFFFFFFF
|
||||
return str(crc32_hash)
|
||||
|
||||
|
||||
@@ -259,8 +259,6 @@ async def user_ranking_individual(request: Request):
|
||||
}
|
||||
}
|
||||
|
||||
print("toital_count: " + str(total_count))
|
||||
|
||||
return JSONResponse(payload)
|
||||
|
||||
async def user_ranking_total(request: Request):
|
||||
@@ -316,7 +314,6 @@ async def user_ranking_total(request: Request):
|
||||
await write_rank_cache(cache_key, records, expire_seconds=120)
|
||||
|
||||
total_count = len(records)
|
||||
print("total_count fetched: " + str(total_count))
|
||||
for index, record in enumerate(records):
|
||||
if index >= page_number * page_count and index < (page_number + 1) * page_count:
|
||||
rank_user = await user_id_to_user_info_simple(record["id"])
|
||||
|
||||
@@ -81,7 +81,6 @@ async def api_shop_player_data(request: Request):
|
||||
item_id for item_id in range(item_low_end, item_high_end)
|
||||
]
|
||||
|
||||
print(my_stage)
|
||||
if 700 in my_stage and os.path.isfile('./files/4max_ver.txt'):
|
||||
is_fmax_purchased = True
|
||||
|
||||
@@ -263,7 +262,6 @@ async def api_shop_purchase_item(request: Request):
|
||||
return JSONResponse({"state": 0, "message": "EXTRA already owned. Exit the shop and it will be added to the game."}, status_code=400)
|
||||
|
||||
if price > device_info['coin']:
|
||||
print("Insufficient coins for purchase.")
|
||||
return JSONResponse({"state": 0, "message": "Insufficient coins."}, status_code=400)
|
||||
|
||||
new_coin_amount = device_info['coin'] - price
|
||||
|
||||
@@ -113,8 +113,6 @@ async def start(request: Request):
|
||||
my_stage, my_avatar = await get_user_entitlement_from_devices(user_id)
|
||||
coin = device_info['coin'] if device_info is not None else 0
|
||||
|
||||
print("user has entitlements:", my_stage, my_avatar)
|
||||
|
||||
elif device_info:
|
||||
# This is a guest user with existing data
|
||||
my_avatar = set(device_info['my_avatar']) if device_info['my_avatar'] else START_AVATARS
|
||||
|
||||
@@ -67,6 +67,7 @@ SMTP_PASSWORD = "test"
|
||||
# For auth mode 2
|
||||
DISCORD_BOT_SECRET = "test"
|
||||
DISCORD_BOT_API_KEY = "test"
|
||||
BIND_SALT = "SET YOUR SALT HERE"
|
||||
|
||||
# Daily download limit per account in bytes (only activates for AUTHORIZATION_MODE 1 and 2)
|
||||
|
||||
|
||||
@@ -73,9 +73,9 @@
|
||||
</button>
|
||||
<div class="collapse navbar-collapse" id="mainNavbar">
|
||||
<ul class="navbar-nav ms-4">
|
||||
<li class="nav-item"><a class="nav-link" href="#" id="usersTab">Users</a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="#" id="accountsTab">Accounts</a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="#" id="resultsTab">Results</a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="#" id="dailyRewardsTab">DailyRewards</a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="#" id="devicesTab">Devices</a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="#" id="whitelistTab">Whitelist</a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="#" id="blacklistTab">Blacklist</a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="#" id="batchTokensTab">BatchTokens</a></li>
|
||||
@@ -196,7 +196,7 @@ function showTable(tabName) {
|
||||
responsiveLayout: "collapse",
|
||||
sortMode: "remote",
|
||||
autoColumnsDefinitions: function(definitions){
|
||||
if (tabName === "users") {
|
||||
if (tabName === "accounts") {
|
||||
definitions.push({
|
||||
title: "data",
|
||||
field: "__data",
|
||||
@@ -281,7 +281,7 @@ function showTable(tabName) {
|
||||
}
|
||||
return value;
|
||||
};
|
||||
if (col.field !== "id" && col.field !== "objectId" && col.field !== "__delete" && col.field !== "__data") {
|
||||
if (col.field !== "id" && col.field !== "__delete" && col.field !== "__data") {
|
||||
col.editor = function(cell, onRendered, success, cancel){
|
||||
const value = cell.getValue();
|
||||
let input;
|
||||
@@ -473,13 +473,13 @@ document.getElementById('dataModalSaveBtn').onclick = async function() {
|
||||
}
|
||||
};
|
||||
|
||||
document.getElementById('usersTab').onclick = () => showTable("users");
|
||||
document.getElementById('accountsTab').onclick = () => showTable("accounts");
|
||||
document.getElementById('resultsTab').onclick = () => showTable("results");
|
||||
document.getElementById('dailyRewardsTab').onclick = () => showTable("daily_rewards");
|
||||
document.getElementById('devicesTab').onclick = () => showTable("devices");
|
||||
document.getElementById('whitelistTab').onclick = () => showTable("whitelist");
|
||||
document.getElementById('blacklistTab').onclick = () => showTable("blacklist");
|
||||
document.getElementById('batchTokensTab').onclick = () => showTable("batch_tokens");
|
||||
document.getElementById('bindTab').onclick = () => showTable("bind");
|
||||
document.getElementById('bindTab').onclick = () => showTable("binds");
|
||||
document.getElementById('logsTab').onclick = () => showTable("logs");
|
||||
|
||||
document.getElementById('logoutBtn').addEventListener('click', function() {
|
||||
@@ -570,12 +570,12 @@ document.getElementById('insertRowForm').onsubmit = async function(e) {
|
||||
}
|
||||
};
|
||||
|
||||
const validTabs = ["users", "results", "daily_rewards", "whitelist", "blacklist", "batch_tokens", "bind", "logs"];
|
||||
const validTabs = ["accounts", "results", "devices", "whitelist", "blacklist", "batch_tokens", "binds", "logs"];
|
||||
const lastTab = getCookie("lastTab");
|
||||
if (validTabs.includes(lastTab)) {
|
||||
showTable(lastTab);
|
||||
} else {
|
||||
showTable("users");
|
||||
showTable("accounts");
|
||||
}
|
||||
|
||||
function getCookie(name) {
|
||||
|
||||
@@ -161,8 +161,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
document.addEventListener("DOMContentLoaded", fetchUserData);
|
||||
</script>
|
||||
</body>
|
||||
|
||||
Reference in New Issue
Block a user