mirror of
https://github.com/cassoule/flopobot_v2.git
synced 2026-01-18 16:37:40 +01:00
Merge branch 'main' into market-place
This commit is contained in:
36
.env.sample
36
.env.sample
@@ -1,36 +0,0 @@
|
||||
APP_ID=
|
||||
DISCORD_TOKEN=
|
||||
PUBLIC_KEY=
|
||||
|
||||
# Server, used only for chaos timer
|
||||
GUILD_ID=
|
||||
|
||||
# Role that can vote, only people with this role will be considered to calculate the majority
|
||||
VOTING_ROLE_ID=
|
||||
|
||||
# Polls max up time, in seconds
|
||||
# default: 300 (5 minutes)
|
||||
POLL_TIME=300
|
||||
|
||||
# Minimum votes needed, active if greater than majority
|
||||
# default: 2 (prevents votes needed to be 1 if majority == 1)
|
||||
MIN_VOTES=2
|
||||
|
||||
# Probability of quoi -> feur, between 0 and 1
|
||||
# default : 0.3 (30% chance of Flopobot saying 'feur' when someone says 'quoi')
|
||||
FEUR_PROB=0.3
|
||||
|
||||
# Probability of triggering the chaos timer at midnight, between 0 and 1
|
||||
# default : 0.1 (10% chance of Flopobot picking randomely a user to time out for 12 hours at midnight)
|
||||
CHAOS_PROB=0.1
|
||||
|
||||
# Everyone can be picked at the chaos timer
|
||||
# default : false (Only VOTING_ROLE_ID users can be picked)
|
||||
EVERYONE_IN_CHAOS=false
|
||||
|
||||
# Every time the death roulette, cron expression
|
||||
# default : '0 0 * * *' (Every day at midnight)
|
||||
#CRON_EXPR='*/1 * * * * *'
|
||||
CRON_EXPR='0 0 * * *'
|
||||
|
||||
OPENAI_API_KEY=
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -3,3 +3,5 @@ node_modules
|
||||
flopobot.db
|
||||
flopobot.db-shm
|
||||
flopobot.db-wal
|
||||
.idea
|
||||
flopobot_bc.db
|
||||
|
||||
8
.idea/.gitignore
generated
vendored
8
.idea/.gitignore
generated
vendored
@@ -1,8 +0,0 @@
|
||||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# Editor-based HTTP Client requests
|
||||
/httpRequests/
|
||||
# Datasource local storage ignored files
|
||||
/dataSources/
|
||||
/dataSources.local.xml
|
||||
61
.idea/codeStyles/Project.xml
generated
61
.idea/codeStyles/Project.xml
generated
@@ -1,61 +0,0 @@
|
||||
<component name="ProjectCodeStyleConfiguration">
|
||||
<code_scheme name="Project" version="173">
|
||||
<HTMLCodeStyleSettings>
|
||||
<option name="HTML_SPACE_INSIDE_EMPTY_TAG" value="true" />
|
||||
</HTMLCodeStyleSettings>
|
||||
<JSCodeStyleSettings version="0">
|
||||
<option name="FORCE_SEMICOLON_STYLE" value="true" />
|
||||
<option name="SPACE_BEFORE_FUNCTION_LEFT_PARENTH" value="false" />
|
||||
<option name="FORCE_QUOTE_STYlE" value="true" />
|
||||
<option name="ENFORCE_TRAILING_COMMA" value="Remove" />
|
||||
<option name="SPACES_WITHIN_OBJECT_LITERAL_BRACES" value="true" />
|
||||
<option name="SPACES_WITHIN_IMPORTS" value="true" />
|
||||
</JSCodeStyleSettings>
|
||||
<TypeScriptCodeStyleSettings version="0">
|
||||
<option name="FORCE_SEMICOLON_STYLE" value="true" />
|
||||
<option name="SPACE_BEFORE_FUNCTION_LEFT_PARENTH" value="false" />
|
||||
<option name="FORCE_QUOTE_STYlE" value="true" />
|
||||
<option name="ENFORCE_TRAILING_COMMA" value="Remove" />
|
||||
<option name="SPACES_WITHIN_OBJECT_LITERAL_BRACES" value="true" />
|
||||
<option name="SPACES_WITHIN_IMPORTS" value="true" />
|
||||
</TypeScriptCodeStyleSettings>
|
||||
<VueCodeStyleSettings>
|
||||
<option name="INTERPOLATION_NEW_LINE_AFTER_START_DELIMITER" value="false" />
|
||||
<option name="INTERPOLATION_NEW_LINE_BEFORE_END_DELIMITER" value="false" />
|
||||
</VueCodeStyleSettings>
|
||||
<codeStyleSettings language="HTML">
|
||||
<option name="SOFT_MARGINS" value="80" />
|
||||
<indentOptions>
|
||||
<option name="INDENT_SIZE" value="2" />
|
||||
<option name="CONTINUATION_INDENT_SIZE" value="2" />
|
||||
<option name="TAB_SIZE" value="2" />
|
||||
<option name="USE_TAB_CHARACTER" value="true" />
|
||||
</indentOptions>
|
||||
</codeStyleSettings>
|
||||
<codeStyleSettings language="JavaScript">
|
||||
<option name="SOFT_MARGINS" value="80" />
|
||||
<indentOptions>
|
||||
<option name="INDENT_SIZE" value="2" />
|
||||
<option name="CONTINUATION_INDENT_SIZE" value="2" />
|
||||
<option name="TAB_SIZE" value="2" />
|
||||
<option name="USE_TAB_CHARACTER" value="true" />
|
||||
</indentOptions>
|
||||
</codeStyleSettings>
|
||||
<codeStyleSettings language="TypeScript">
|
||||
<option name="SOFT_MARGINS" value="80" />
|
||||
<indentOptions>
|
||||
<option name="INDENT_SIZE" value="2" />
|
||||
<option name="CONTINUATION_INDENT_SIZE" value="2" />
|
||||
<option name="TAB_SIZE" value="2" />
|
||||
<option name="USE_TAB_CHARACTER" value="true" />
|
||||
</indentOptions>
|
||||
</codeStyleSettings>
|
||||
<codeStyleSettings language="Vue">
|
||||
<option name="SOFT_MARGINS" value="80" />
|
||||
<indentOptions>
|
||||
<option name="CONTINUATION_INDENT_SIZE" value="2" />
|
||||
<option name="USE_TAB_CHARACTER" value="true" />
|
||||
</indentOptions>
|
||||
</codeStyleSettings>
|
||||
</code_scheme>
|
||||
</component>
|
||||
5
.idea/codeStyles/codeStyleConfig.xml
generated
5
.idea/codeStyles/codeStyleConfig.xml
generated
@@ -1,5 +0,0 @@
|
||||
<component name="ProjectCodeStyleConfiguration">
|
||||
<state>
|
||||
<option name="USE_PER_PROJECT_SETTINGS" value="true" />
|
||||
</state>
|
||||
</component>
|
||||
12
.idea/dataSources.xml
generated
12
.idea/dataSources.xml
generated
@@ -1,12 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="DataSourceManagerImpl" format="xml" multifile-model="true">
|
||||
<data-source source="LOCAL" name="flopobot" uuid="e5d4b6d8-8572-4545-b4a6-246b3cba87a8">
|
||||
<driver-ref>sqlite.xerial</driver-ref>
|
||||
<synchronize>true</synchronize>
|
||||
<jdbc-driver>org.sqlite.JDBC</jdbc-driver>
|
||||
<jdbc-url>jdbc:sqlite:C:\Users\milog\coding\bot_discord\flopobot_v2\flopobot.db</jdbc-url>
|
||||
<working-dir>$ProjectFileDir$</working-dir>
|
||||
</data-source>
|
||||
</component>
|
||||
</project>
|
||||
8
.idea/flopobot_v2.iml
generated
8
.idea/flopobot_v2.iml
generated
@@ -1,8 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="WEB_MODULE" version="4">
|
||||
<component name="NewModuleRootManager">
|
||||
<content url="file://$MODULE_DIR$" />
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
||||
6
.idea/inspectionProfiles/Project_Default.xml
generated
6
.idea/inspectionProfiles/Project_Default.xml
generated
@@ -1,6 +0,0 @@
|
||||
<component name="InspectionProjectProfileManager">
|
||||
<profile version="1.0">
|
||||
<option name="myName" value="Project Default" />
|
||||
<inspection_tool class="Eslint" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||
</profile>
|
||||
</component>
|
||||
6
.idea/jsLibraryMappings.xml
generated
6
.idea/jsLibraryMappings.xml
generated
@@ -1,6 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="JavaScriptLibraryMappings">
|
||||
<includedPredefinedLibrary name="Node.js Core" />
|
||||
</component>
|
||||
</project>
|
||||
6
.idea/jsLinters/eslint.xml
generated
6
.idea/jsLinters/eslint.xml
generated
@@ -1,6 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="EslintConfiguration">
|
||||
<option name="fix-on-save" value="true" />
|
||||
</component>
|
||||
</project>
|
||||
8
.idea/laravel-idea.xml
generated
8
.idea/laravel-idea.xml
generated
@@ -1,8 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="InertiaPackage">
|
||||
<option name="directoryPaths">
|
||||
<list />
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
||||
8
.idea/modules.xml
generated
8
.idea/modules.xml
generated
@@ -1,8 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/flopobot_v2.iml" filepath="$PROJECT_DIR$/.idea/flopobot_v2.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
||||
34
.idea/php.xml
generated
34
.idea/php.xml
generated
@@ -1,34 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="MessDetectorOptionsConfiguration">
|
||||
<option name="transferred" value="true" />
|
||||
</component>
|
||||
<component name="PHPCSFixerOptionsConfiguration">
|
||||
<option name="transferred" value="true" />
|
||||
</component>
|
||||
<component name="PHPCodeSnifferOptionsConfiguration">
|
||||
<option name="highlightLevel" value="WARNING" />
|
||||
<option name="transferred" value="true" />
|
||||
</component>
|
||||
<component name="PhpCodeSniffer">
|
||||
<phpcs_settings>
|
||||
<phpcs_by_interpreter asDefaultInterpreter="true" interpreter_id="ceb1e1c5-a5b2-49ae-acba-ec4afdb2ab09" timeout="30000" />
|
||||
</phpcs_settings>
|
||||
</component>
|
||||
<component name="PhpStan">
|
||||
<PhpStan_settings>
|
||||
<phpstan_by_interpreter asDefaultInterpreter="true" interpreter_id="ceb1e1c5-a5b2-49ae-acba-ec4afdb2ab09" timeout="60000" />
|
||||
</PhpStan_settings>
|
||||
</component>
|
||||
<component name="PhpStanOptionsConfiguration">
|
||||
<option name="transferred" value="true" />
|
||||
</component>
|
||||
<component name="Psalm">
|
||||
<Psalm_settings>
|
||||
<psalm_fixer_by_interpreter asDefaultInterpreter="true" interpreter_id="ceb1e1c5-a5b2-49ae-acba-ec4afdb2ab09" timeout="60000" />
|
||||
</Psalm_settings>
|
||||
</component>
|
||||
<component name="PsalmOptionsConfiguration">
|
||||
<option name="transferred" value="true" />
|
||||
</component>
|
||||
</project>
|
||||
7
.idea/prettier.xml
generated
7
.idea/prettier.xml
generated
@@ -1,7 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="PrettierConfiguration">
|
||||
<option name="myConfigurationMode" value="AUTOMATIC" />
|
||||
<option name="myRunOnSave" value="true" />
|
||||
</component>
|
||||
</project>
|
||||
6
.idea/sqldialects.xml
generated
6
.idea/sqldialects.xml
generated
@@ -1,6 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="SqlDialectMappings">
|
||||
<file url="PROJECT" dialect="SQLite" />
|
||||
</component>
|
||||
</project>
|
||||
6
.idea/vcs.xml
generated
6
.idea/vcs.xml
generated
@@ -1,6 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
||||
BIN
flopobot.db
Normal file
BIN
flopobot.db
Normal file
Binary file not shown.
@@ -8,7 +8,7 @@ import { InteractionResponseType, MessageComponentTypes, ButtonStyleTypes } from
|
||||
*/
|
||||
export async function handleFlopoSiteCommand(req, res) {
|
||||
// The URL for the link button. Consider moving to .env if it changes.
|
||||
const siteUrl = process.env.FLOPOSITE_URL || "https://floposite.com";
|
||||
const siteUrl = process.env.FLOPOSITE_URL;
|
||||
|
||||
// The URL for the thumbnail image.
|
||||
const thumbnailUrl = `${process.env.API_URL}/public/images/flopo.png`;
|
||||
|
||||
@@ -2,6 +2,123 @@ import Database from "better-sqlite3";
|
||||
|
||||
export const flopoDB = new Database("flopobot.db");
|
||||
|
||||
/* -------------------------
|
||||
CREATE ALL TABLES FIRST
|
||||
----------------------------*/
|
||||
flopoDB.exec(`
|
||||
CREATE TABLE IF NOT EXISTS users
|
||||
(
|
||||
id TEXT PRIMARY KEY,
|
||||
username TEXT NOT NULL,
|
||||
globalName TEXT,
|
||||
warned BOOLEAN DEFAULT 0,
|
||||
warns INTEGER DEFAULT 0,
|
||||
allTimeWarns INTEGER DEFAULT 0,
|
||||
totalRequests INTEGER DEFAULT 0,
|
||||
coins INTEGER DEFAULT 0,
|
||||
dailyQueried BOOLEAN DEFAULT 0,
|
||||
avatarUrl TEXT DEFAULT NULL,
|
||||
isAkhy BOOLEAN DEFAULT 0
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS skins
|
||||
(
|
||||
uuid TEXT PRIMARY KEY,
|
||||
displayName TEXT,
|
||||
contentTierUuid TEXT,
|
||||
displayIcon TEXT,
|
||||
user_id TEXT REFERENCES users,
|
||||
tierRank TEXT,
|
||||
tierColor TEXT,
|
||||
tierText TEXT,
|
||||
basePrice TEXT,
|
||||
currentLvl INTEGER DEFAULT NULL,
|
||||
currentChroma INTEGER DEFAULT NULL,
|
||||
currentPrice INTEGER DEFAULT NULL,
|
||||
maxPrice INTEGER DEFAULT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS market_offers
|
||||
(
|
||||
id PRIMARY KEY,
|
||||
skin_uuid TEXT REFERENCES skins,
|
||||
seller_id TEXT REFERENCES users,
|
||||
starting_price INTEGER NOT NULL,
|
||||
buyout_price INTEGER DEFAULT NULL,
|
||||
final_price INTEGER DEFAULT NULL,
|
||||
status TEXT NOT NULL,
|
||||
posted_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
opening_at TIMESTAMP NOT NULL,
|
||||
closing_at TIMESTAMP NOT NULL,
|
||||
buyer_id TEXT REFERENCES users DEFAULT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS bids
|
||||
(
|
||||
id PRIMARY KEY,
|
||||
bidder_id TEXT REFERENCES users,
|
||||
market_offer_id REFERENCES market_offers,
|
||||
offer_amount INTEGER,
|
||||
offered_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS logs
|
||||
(
|
||||
id PRIMARY KEY,
|
||||
user_id TEXT REFERENCES users,
|
||||
action TEXT,
|
||||
target_user_id TEXT REFERENCES users,
|
||||
coins_amount INTEGER,
|
||||
user_new_amount INTEGER,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS games
|
||||
(
|
||||
id PRIMARY KEY,
|
||||
p1 TEXT REFERENCES users,
|
||||
p2 TEXT REFERENCES users,
|
||||
p1_score INTEGER,
|
||||
p2_score INTEGER,
|
||||
p1_elo INTEGER,
|
||||
p2_elo INTEGER,
|
||||
p1_new_elo INTEGER,
|
||||
p2_new_elo INTEGER,
|
||||
type TEXT,
|
||||
timestamp TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS elos
|
||||
(
|
||||
id PRIMARY KEY REFERENCES users,
|
||||
elo INTEGER
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS sotd
|
||||
(
|
||||
id INT PRIMARY KEY,
|
||||
tableauPiles TEXT,
|
||||
foundationPiles TEXT,
|
||||
stockPile TEXT,
|
||||
wastePile TEXT,
|
||||
isDone BOOLEAN DEFAULT false,
|
||||
seed TEXT
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS sotd_stats
|
||||
(
|
||||
id TEXT PRIMARY KEY,
|
||||
user_id TEXT REFERENCES users,
|
||||
time INTEGER,
|
||||
moves INTEGER,
|
||||
score INTEGER
|
||||
);
|
||||
`);
|
||||
|
||||
/* -----------------------------------------------------
|
||||
PREPARE ANY CREATE TABLE STATEMENT OBJECTS (kept for parity)
|
||||
------------------------------------------------------*/
|
||||
|
||||
export const stmtUsers = flopoDB.prepare(`
|
||||
CREATE TABLE IF NOT EXISTS users
|
||||
(
|
||||
@@ -19,6 +136,7 @@ export const stmtUsers = flopoDB.prepare(`
|
||||
)
|
||||
`);
|
||||
stmtUsers.run();
|
||||
|
||||
export const stmtSkins = flopoDB.prepare(`
|
||||
CREATE TABLE IF NOT EXISTS skins
|
||||
(
|
||||
@@ -39,6 +157,106 @@ export const stmtSkins = flopoDB.prepare(`
|
||||
`);
|
||||
stmtSkins.run();
|
||||
|
||||
export const stmtMarketOffers = flopoDB.prepare(`
|
||||
CREATE TABLE IF NOT EXISTS market_offers
|
||||
(
|
||||
id PRIMARY KEY,
|
||||
skin_uuid TEXT REFERENCES skins,
|
||||
seller_id TEXT REFERENCES users,
|
||||
starting_price INTEGER NOT NULL,
|
||||
buyout_price INTEGER DEFAULT NULL,
|
||||
final_price INTEGER DEFAULT NULL,
|
||||
status TEXT NOT NULL,
|
||||
posted_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
opening_at TIMESTAMP NOT NULL,
|
||||
closing_at TIMESTAMP NOT NULL,
|
||||
buyer_id TEXT REFERENCES users DEFAULT NULL
|
||||
)
|
||||
`);
|
||||
stmtMarketOffers.run();
|
||||
|
||||
export const stmtBids = flopoDB.prepare(`
|
||||
CREATE TABLE IF NOT EXISTS bids
|
||||
(
|
||||
id PRIMARY KEY,
|
||||
bidder_id TEXT REFERENCES users,
|
||||
market_offer_id REFERENCES market_offers,
|
||||
offer_amount INTEGER,
|
||||
offered_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
)
|
||||
`);
|
||||
stmtBids.run();
|
||||
|
||||
export const stmtLogs = flopoDB.prepare(`
|
||||
CREATE TABLE IF NOT EXISTS logs
|
||||
(
|
||||
id PRIMARY KEY,
|
||||
user_id TEXT REFERENCES users,
|
||||
action TEXT,
|
||||
target_user_id TEXT REFERENCES users,
|
||||
coins_amount INTEGER,
|
||||
user_new_amount INTEGER,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
)
|
||||
`);
|
||||
stmtLogs.run();
|
||||
|
||||
export const stmtGames = flopoDB.prepare(`
|
||||
CREATE TABLE IF NOT EXISTS games
|
||||
(
|
||||
id PRIMARY KEY,
|
||||
p1 TEXT REFERENCES users,
|
||||
p2 TEXT REFERENCES users,
|
||||
p1_score INTEGER,
|
||||
p2_score INTEGER,
|
||||
p1_elo INTEGER,
|
||||
p2_elo INTEGER,
|
||||
p1_new_elo INTEGER,
|
||||
p2_new_elo INTEGER,
|
||||
type TEXT,
|
||||
timestamp TIMESTAMP
|
||||
)
|
||||
`);
|
||||
stmtGames.run();
|
||||
|
||||
export const stmtElos = flopoDB.prepare(`
|
||||
CREATE TABLE IF NOT EXISTS elos
|
||||
(
|
||||
id PRIMARY KEY REFERENCES users,
|
||||
elo INTEGER
|
||||
)
|
||||
`);
|
||||
stmtElos.run();
|
||||
|
||||
export const stmtSOTD = flopoDB.prepare(`
|
||||
CREATE TABLE IF NOT EXISTS sotd
|
||||
(
|
||||
id INT PRIMARY KEY,
|
||||
tableauPiles TEXT,
|
||||
foundationPiles TEXT,
|
||||
stockPile TEXT,
|
||||
wastePile TEXT,
|
||||
isDone BOOLEAN DEFAULT false,
|
||||
seed TEXT
|
||||
)
|
||||
`);
|
||||
stmtSOTD.run();
|
||||
|
||||
export const stmtSOTDStats = flopoDB.prepare(`
|
||||
CREATE TABLE IF NOT EXISTS sotd_stats
|
||||
(
|
||||
id TEXT PRIMARY KEY,
|
||||
user_id TEXT REFERENCES users,
|
||||
time INTEGER,
|
||||
moves INTEGER,
|
||||
score INTEGER
|
||||
)
|
||||
`);
|
||||
stmtSOTDStats.run();
|
||||
|
||||
/* -------------------------
|
||||
USER statements
|
||||
----------------------------*/
|
||||
export const insertUser = flopoDB.prepare(
|
||||
`INSERT INTO users (id, username, globalName, warned, warns, allTimeWarns, totalRequests, avatarUrl, isAkhy)
|
||||
VALUES (@id, @username, @globalName, @warned, @warns, @allTimeWarns, @totalRequests, @avatarUrl, @isAkhy)`,
|
||||
@@ -68,6 +286,9 @@ export const getAllAkhys = flopoDB.prepare(
|
||||
"SELECT users.*,elos.elo FROM users LEFT JOIN elos ON elos.id = users.id WHERE isAkhy = 1 ORDER BY coins DESC",
|
||||
);
|
||||
|
||||
/* -------------------------
|
||||
SKINS statements
|
||||
----------------------------*/
|
||||
export const insertSkin = flopoDB.prepare(
|
||||
`INSERT INTO skins (uuid, displayName, contentTierUuid, displayIcon, user_id, tierRank, tierColor, tierText,
|
||||
basePrice, currentLvl, currentChroma, currentPrice, maxPrice)
|
||||
@@ -106,36 +327,9 @@ export const getUserInventory = flopoDB.prepare(
|
||||
);
|
||||
export const getTopSkins = flopoDB.prepare("SELECT * FROM skins ORDER BY maxPrice DESC LIMIT 10");
|
||||
|
||||
export const stmtMarketOffers = flopoDB.prepare(`
|
||||
CREATE TABLE IF NOT EXISTS market_offers
|
||||
(
|
||||
id PRIMARY KEY,
|
||||
skin_uuid TEXT REFERENCES skins,
|
||||
seller_id TEXT REFERENCES users,
|
||||
starting_price INTEGER NOT NULL,
|
||||
buyout_price INTEGER DEFAULT NULL,
|
||||
final_price INTEGER DEFAULT NULL,
|
||||
status TEXT NOT NULL,
|
||||
posted_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
opening_at TIMESTAMP NOT NULL,
|
||||
closing_at TIMESTAMP NOT NULL,
|
||||
buyer_id TEXT REFERENCES users DEFAULT NULL
|
||||
)
|
||||
`);
|
||||
stmtMarketOffers.run();
|
||||
|
||||
export const stmtBids = flopoDB.prepare(`
|
||||
CREATE TABLE IF NOT EXISTS bids
|
||||
(
|
||||
id PRIMARY KEY,
|
||||
bidder_id TEXT REFERENCES users,
|
||||
market_offer_id REFERENCES market_offers,
|
||||
offer_amount INTEGER,
|
||||
offered_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
)
|
||||
`);
|
||||
stmtBids.run();
|
||||
|
||||
/* -------------------------
|
||||
MARKET / BIDS / OFFERS
|
||||
----------------------------*/
|
||||
export const getMarketOffers = flopoDB.prepare(`
|
||||
SELECT *
|
||||
FROM market_offers
|
||||
@@ -177,6 +371,9 @@ export const insertMarketOffer = flopoDB.prepare(`
|
||||
VALUES (@id, @skin_uuid, @seller_id, @starting_price, @buyout_price, @status, @opening_at, @closing_at)
|
||||
`);
|
||||
|
||||
/* -------------------------
|
||||
BIDS
|
||||
----------------------------*/
|
||||
export const getBids = flopoDB.prepare(`
|
||||
SELECT bids.*,
|
||||
bidder.username AS bidderName,
|
||||
@@ -204,48 +401,41 @@ export const insertBid = flopoDB.prepare(`
|
||||
VALUES (@id, @bidder_id, @market_offer_id, @offer_amount)
|
||||
`);
|
||||
|
||||
export const insertManyUsers = flopoDB.transaction(async (users) => {
|
||||
/* -------------------------
|
||||
BULK TRANSACTIONS (synchronous)
|
||||
----------------------------*/
|
||||
export const insertManyUsers = flopoDB.transaction((users) => {
|
||||
for (const user of users)
|
||||
try {
|
||||
await insertUser.run(user);
|
||||
insertUser.run(user);
|
||||
} catch (e) {}
|
||||
});
|
||||
export const updateManyUsers = flopoDB.transaction(async (users) => {
|
||||
|
||||
export const updateManyUsers = flopoDB.transaction((users) => {
|
||||
for (const user of users)
|
||||
try {
|
||||
await updateUser.run(user);
|
||||
updateUser.run(user);
|
||||
} catch (e) {
|
||||
console.log(`[${Date.now()}] user update failed`);
|
||||
}
|
||||
});
|
||||
|
||||
export const insertManySkins = flopoDB.transaction(async (skins) => {
|
||||
export const insertManySkins = flopoDB.transaction((skins) => {
|
||||
for (const skin of skins)
|
||||
try {
|
||||
await insertSkin.run(skin);
|
||||
insertSkin.run(skin);
|
||||
} catch (e) {}
|
||||
});
|
||||
export const updateManySkins = flopoDB.transaction(async (skins) => {
|
||||
export const updateManySkins = flopoDB.transaction((skins) => {
|
||||
for (const skin of skins)
|
||||
try {
|
||||
await updateSkin.run(skin);
|
||||
updateSkin.run(skin);
|
||||
} catch (e) {}
|
||||
});
|
||||
|
||||
export const stmtLogs = flopoDB.prepare(`
|
||||
CREATE TABLE IF NOT EXISTS logs
|
||||
(
|
||||
id PRIMARY KEY,
|
||||
user_id TEXT REFERENCES users,
|
||||
action TEXT,
|
||||
target_user_id TEXT REFERENCES users,
|
||||
coins_amount INTEGER,
|
||||
user_new_amount INTEGER,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
)
|
||||
`);
|
||||
stmtLogs.run();
|
||||
|
||||
/* -------------------------
|
||||
LOGS
|
||||
----------------------------*/
|
||||
export const insertLog = flopoDB.prepare(
|
||||
`INSERT INTO logs (id, user_id, action, target_user_id, coins_amount, user_new_amount)
|
||||
VALUES (@id, @user_id, @action, @target_user_id, @coins_amount, @user_new_amount)`,
|
||||
@@ -253,24 +443,9 @@ export const insertLog = flopoDB.prepare(
|
||||
export const getLogs = flopoDB.prepare("SELECT * FROM logs");
|
||||
export const getUserLogs = flopoDB.prepare("SELECT * FROM logs WHERE user_id = @user_id");
|
||||
|
||||
export const stmtGames = flopoDB.prepare(`
|
||||
CREATE TABLE IF NOT EXISTS games
|
||||
(
|
||||
id PRIMARY KEY,
|
||||
p1 TEXT REFERENCES users,
|
||||
p2 TEXT REFERENCES users,
|
||||
p1_score INTEGER,
|
||||
p2_score INTEGER,
|
||||
p1_elo INTEGER,
|
||||
p2_elo INTEGER,
|
||||
p1_new_elo INTEGER,
|
||||
p2_new_elo INTEGER,
|
||||
type TEXT,
|
||||
timestamp TIMESTAMP
|
||||
)
|
||||
`);
|
||||
stmtGames.run();
|
||||
|
||||
/* -------------------------
|
||||
GAMES
|
||||
----------------------------*/
|
||||
export const insertGame = flopoDB.prepare(
|
||||
`INSERT INTO games (id, p1, p2, p1_score, p2_score, p1_elo, p2_elo, p1_new_elo, p2_new_elo, type, timestamp)
|
||||
VALUES (@id, @p1, @p2, @p1_score, @p2_score, @p1_elo, @p2_elo, @p1_new_elo, @p2_new_elo, @type, @timestamp)`,
|
||||
@@ -280,15 +455,9 @@ export const getUserGames = flopoDB.prepare(
|
||||
"SELECT * FROM games WHERE p1 = @user_id OR p2 = @user_id ORDER BY timestamp",
|
||||
);
|
||||
|
||||
export const stmtElos = flopoDB.prepare(`
|
||||
CREATE TABLE IF NOT EXISTS elos
|
||||
(
|
||||
id PRIMARY KEY REFERENCES users,
|
||||
elo INTEGER
|
||||
)
|
||||
`);
|
||||
stmtElos.run();
|
||||
|
||||
/* -------------------------
|
||||
ELOS
|
||||
----------------------------*/
|
||||
export const insertElos = flopoDB.prepare(`INSERT INTO elos (id, elo)
|
||||
VALUES (@id, @elo)`);
|
||||
export const getElos = flopoDB.prepare(`SELECT *
|
||||
@@ -302,20 +471,9 @@ export const getUsersByElo = flopoDB.prepare(
|
||||
"SELECT * FROM users JOIN elos ON elos.id = users.id ORDER BY elos.elo DESC",
|
||||
);
|
||||
|
||||
export const stmtSOTD = flopoDB.prepare(`
|
||||
CREATE TABLE IF NOT EXISTS sotd
|
||||
(
|
||||
id INT PRIMARY KEY,
|
||||
tableauPiles TEXT,
|
||||
foundationPiles TEXT,
|
||||
stockPile TEXT,
|
||||
wastePile TEXT,
|
||||
isDone BOOLEAN DEFAULT false,
|
||||
seed TEXT
|
||||
)
|
||||
`);
|
||||
stmtSOTD.run();
|
||||
|
||||
/* -------------------------
|
||||
SOTD
|
||||
----------------------------*/
|
||||
export const getSOTD = flopoDB.prepare(`SELECT *
|
||||
FROM sotd
|
||||
WHERE id = '0'`);
|
||||
@@ -326,18 +484,6 @@ export const deleteSOTD = flopoDB.prepare(`DELETE
|
||||
FROM sotd
|
||||
WHERE id = '0'`);
|
||||
|
||||
export const stmtSOTDStats = flopoDB.prepare(`
|
||||
CREATE TABLE IF NOT EXISTS sotd_stats
|
||||
(
|
||||
id TEXT PRIMARY KEY,
|
||||
user_id TEXT REFERENCES users,
|
||||
time INTEGER,
|
||||
moves INTEGER,
|
||||
score INTEGER
|
||||
)
|
||||
`);
|
||||
stmtSOTDStats.run();
|
||||
|
||||
export const getAllSOTDStats = flopoDB.prepare(`SELECT sotd_stats.*, users.globalName
|
||||
FROM sotd_stats
|
||||
JOIN users ON users.id = sotd_stats.user_id
|
||||
@@ -353,6 +499,13 @@ export const deleteUserSOTDStats = flopoDB.prepare(`DELETE
|
||||
FROM sotd_stats
|
||||
WHERE user_id = ?`);
|
||||
|
||||
/* -------------------------
|
||||
Market queries already declared above (kept for completeness)
|
||||
----------------------------*/
|
||||
|
||||
/* -------------------------
|
||||
pruneOldLogs
|
||||
----------------------------*/
|
||||
export async function pruneOldLogs() {
|
||||
const users = flopoDB
|
||||
.prepare(
|
||||
|
||||
@@ -34,7 +34,7 @@ export async function gork(messageHistory) {
|
||||
|
||||
try {
|
||||
// --- OpenAI Provider ---
|
||||
if (modelProvider === "OpenAI" && openai) {
|
||||
if (modelProvider.toLowerCase() === "openai" && openai) {
|
||||
const completion = await openai.chat.completions.create({
|
||||
model: "gpt-5", // Using a modern, cost-effective model
|
||||
reasoning_effort: "low",
|
||||
@@ -44,7 +44,7 @@ export async function gork(messageHistory) {
|
||||
}
|
||||
|
||||
// --- Google Gemini Provider ---
|
||||
else if (modelProvider === "Gemini" && gemini) {
|
||||
else if (modelProvider.toLowerCase() === "gemini" && gemini) {
|
||||
// Gemini requires a slightly different history format.
|
||||
messageHistory.forEach((message) => {
|
||||
console.log(message.role);
|
||||
@@ -76,7 +76,7 @@ export async function gork(messageHistory) {
|
||||
}
|
||||
|
||||
// --- Mistral Provider ---
|
||||
else if (modelProvider === "Mistral" && mistral) {
|
||||
else if (modelProvider.toLowerCase() === "mistral" && mistral) {
|
||||
const chatResponse = await mistral.chat({
|
||||
model: "mistral-large-latest",
|
||||
messages: messageHistory,
|
||||
|
||||
@@ -136,7 +136,7 @@ export function setupCronJobs(client, io) {
|
||||
});
|
||||
|
||||
// Daily at midnight: Reset daily rewards and init SOTD
|
||||
cron.schedule("0 0 * * *", async () => {
|
||||
cron.schedule(process.env.CRON_EXPR, async () => {
|
||||
console.log("[Cron] Running daily midnight tasks...");
|
||||
try {
|
||||
resetDailyReward.run();
|
||||
|
||||
Reference in New Issue
Block a user