2022-05-28 16:55:56 +03:00
// @ts-check
2022-05-24 08:55:57 +03:00
const { MongoClient , ServerApiVersion } = require ( 'mongodb' );
let ecoimport = require ( "./econ.js" );
2022-05-29 20:59:39 +03:00
let { handle } = require ( "./battle.js" ); //PROBLEM (CIRCULAR DEPENDANCY)
2022-05-25 22:33:42 +03:00
let snowflake = require ( "./addons/snowflake.js" );
2022-05-24 08:55:57 +03:00
const STATE = ecoimport . STATE ;
2022-05-25 22:33:42 +03:00
const BASE = ecoimport . BASE ;
2022-05-24 08:55:57 +03:00
2022-05-29 20:59:39 +03:00
const { winGame , loseGame } = require ( './external_game_functions.js' );
2022-05-24 08:55:57 +03:00
//Has a list of all games (used to change player state)
const allGames = [ 'battle' ];
// const { NULL } = require('mysql/lib/protocol/constants/types');
//#region functions (NOT GAME SPECIFIC)
/** Adds the game type tag to the user(s) so the system can tell what game they're playing
* @param other_dbo optional, include if the game has two players
*/
2022-05-28 16:55:56 +03:00
async function Initialize ( bot , user_dbo , command , message , first , second , other_dbo = null ) {
return new Promise ( async function ( resolve , reject ) {
user_dbo . find ({ "game" : { $exists : true }}). toArray ( function ( err , docs ){
let doc = docs [ 0 ];
if ( allGames . indexOf ( command ) != - 1 ) {
if ( other_dbo != null ) {
user_dbo . updateOne ( { "game" : { $exists : true } }, { $set : { game : command , opponent : other_dbo . s . namespace . collection , state : STATE . FIGHTING }});
other_dbo . updateOne ({ "game" : { $exists : true } }, { $set : { game : command , opponent : user_dbo . s . namespace . collection , state : STATE . FIGHTING }});
} else {
user_dbo . updateOne ({ "game" : { $exists : true } }, { $set : { game : command , state : STATE . FIGHTING }});
}
2022-05-25 22:33:42 +03:00
2022-05-28 16:55:56 +03:00
} else { message . reply ( `ERROR! ${ command } IS NOT A GAME!` ); }
});
//Create a new thread for the game (maybe uneccesary???) - done before initialize
let name_first = await bot . users . cache . get ( first );
let name_second = await bot . users . cache . get ( second );
2022-05-25 22:33:42 +03:00
2022-05-28 16:55:56 +03:00
// message.reply(`${first} [${name_first}], ${second} [${name_second}]`); throw 'ERR';
const threadname = ` ${ name_first . username } VS ${ name_second . username } [ ${ command . toUpperCase () } ]` ;
const thread = await message . channel . threads . create ({
name : threadname ,
// type: 'GUILD_PRIVATE_THREAD',
autoArchiveDuration : 60 ,
reason : `N/A` ,
});
//Need lvl 2 boost for this
// thread.add(first);
// thread.add(second);
message . channel . send ( `<@ ${ first } > and <@ ${ second } > have started a game of *** ${ command . toUpperCase () } !***` );
resolve ( thread );
});
2022-05-25 22:33:42 +03:00
}
//#endregion
2022-05-28 16:55:56 +03:00
//replies to the message with current game specifics
function getGame ( message , args , db ) {
let id ;
var temp ;
if ( args . length == 1 && String ( args [ 0 ]). startsWith ( '<' )) { id = args [ 0 ]. substr ( 2 , args [ 0 ]. length - 3 )}
else { id = message . author . id ; }
var user_dbo = db . collection ( message . author . id );
2022-05-24 08:55:57 +03:00
user_dbo . find ({ "game" : { $exists : true }}). toArray ( function ( err , docs ){
2022-05-25 22:33:42 +03:00
const doc = docs [ 0 ];
2022-05-28 16:55:56 +03:00
if ( doc . game == null ) {
return message . reply ( `<@ ${ id } > is not currently playing a game!` );
}
2022-05-25 22:33:42 +03:00
2022-05-28 16:55:56 +03:00
temp = `<@ ${ id } > is currently playing " ${ doc . game } "` ;
2022-05-25 22:33:42 +03:00
if ( doc . opponent != null ) {
2022-05-28 16:55:56 +03:00
temp += ` with <@ ${ doc . opponent } >`
2022-05-25 22:33:42 +03:00
}
2022-05-28 16:55:56 +03:00
2022-05-25 22:33:42 +03:00
message . reply ( temp );
2022-05-24 08:55:57 +03:00
});
}
2022-05-28 16:55:56 +03:00
function acceptIsValid ( bot , other_discord , message , msg , tag_len ) {
2022-05-25 22:33:42 +03:00
if ( other_discord == undefined ) {
message . reply ( "This is not a valid invite!" );
return false ;
}
//Make sure the bot was the one creating the invite
let check0 = msg . author . bot ;
//Author
2022-05-28 16:55:56 +03:00
let tag = msg . content . substr ( 2 , tag_len );
let check1 = Number ( tag ) == Number ( message . author . id );
2022-05-25 22:33:42 +03:00
//Time (within the last 5 min)
let prev = snowflake . convertSnowflakeToDate ( msg . id );
let now = snowflake . convertSnowflakeToDate ( message . id );
2022-05-28 16:55:56 +03:00
// @ts-ignore
2022-05-25 22:33:42 +03:00
let diff = now - prev ;
var minutes = Math . floor (( diff / 1000 ) / 60 );
2022-05-28 16:55:56 +03:00
let check2 = minutes <= 5 || bot . inDebugMode ;
2022-05-24 08:55:57 +03:00
2022-05-25 22:33:42 +03:00
if ( ! check0 ) { message . reply ( "really?" ); }
else if ( ! check1 && check2 ) { message . reply ( "_INVALID USER_" ); }
else if ( check1 && ! check2 ) { message . reply ( "_THIS INVITE EXPIRED!_" ); }
else if ( ! check1 && ! check2 ) { message . reply ( "_THIS MESSAGE HAS AN INVALID USER AND HAS EXPIRED_" )}
return ( check0 && check1 && check2 );
2022-05-24 08:55:57 +03:00
}
2022-05-28 16:55:56 +03:00
function hpmp ( message , command , dbo ) {
2022-05-30 20:37:15 +03:00
// throw 'THIS HAS NOT BEEN UPDATED WITH THE MOST RECENT VERSION OF THE MONGODB STRUCTURE!';
2022-05-28 16:55:56 +03:00
if ( command == 'hp' ) {
2022-06-01 20:38:39 +03:00
dbo . find ({ "hpmp" : { $exists : true }}). toArray ( function ( err , doc ) {
2022-05-30 20:37:15 +03:00
return message . reply ( `You have ${ String ( doc [ 0 ]. hpmp . hp ) } hp left!` );
2022-05-28 16:55:56 +03:00
});
} else if ( command == 'mp' ) {
2022-06-01 20:38:39 +03:00
dbo . find ({ "hpmp" : { $exists : true }}). toArray ( function ( err , doc ) {
2022-05-30 20:37:15 +03:00
return message . reply ( `You have ${ String ( doc [ 0 ]. hpmp . hp ) } mp left!` );
2022-05-28 16:55:56 +03:00
});
}
}
2022-06-01 20:38:39 +03:00
function equip ( client , message , command , dbo , bot ) {
//Check if the user is already in a game
}
2022-05-24 08:55:57 +03:00
//#endregion
2022-05-28 16:55:56 +03:00
//#region GAME SPECIFIC
2022-05-29 20:59:39 +03:00
function in_game_redirector ( bot , interaction , threadname , doc , client , mongouri , items , xp_collection ) {
2022-05-28 16:55:56 +03:00
//Maybe fix this later......
let turn = doc . turn ;
const user1 = doc [ turn ];
const user2 = doc [ Number ( ! turn )];
const db = client . db ( interaction . guildId + "[ECON]" );
const dbo = db . collection ( user1 );
const other = db . collection ( user2 );
const thread = interaction . channel ;
dbo . find ({ 'game' : { $exists : true }}). toArray ( function ( err , docs ) {
const game = docs [ 0 ]. game
switch ( game ) {
2022-05-29 20:59:39 +03:00
case 'battle' : handle ( client , dbo , other , bot , thread , interaction . customId . toLowerCase (), mongouri , items , interaction , xp_collection );
2022-05-28 16:55:56 +03:00
}
});
}
2022-05-24 08:55:57 +03:00
module . exports = {
name : "game" ,
description : "Play a game using Selmer Bot!" ,
async execute ( bot , message , args , command , Discord , mongouri , items , xp_collection ) {
2022-05-25 22:33:42 +03:00
if ( ! bot . inDebugMode ) { return message . reply ( "This command is currently in development!" ); }
2022-05-28 16:55:56 +03:00
//#region Setup
2022-05-24 08:55:57 +03:00
const id = message . author . id ;
const server = message . guild . id ;
2022-05-28 16:55:56 +03:00
// @ts-ignore
2022-05-24 08:55:57 +03:00
const client = new MongoClient ( mongouri , { useNewUrlParser : true , useUnifiedTopology : true , serverApi : ServerApiVersion . v1 });
if ( client . writeConcern || client . writeConcern ) {
client . close ();
return message . reply ( "Something went wrong with the database, please try again later and contact support if this problem persists!" );
2022-05-28 16:55:56 +03:00
}
const botdb = client . db ( 'B|S' + bot . user . id );
const serverinbotdb = botdb . collection ( server );
2022-05-24 08:55:57 +03:00
//Initialize if necessary
ecoimport . CreateNewCollection ( message , client , server , id );
command = args [ 0 ];
//Check for a second person and create a second database entry if neccessary
if ( message . mentions . users . first () != undefined ) {
2022-05-28 16:55:56 +03:00
//#TODO //FIX THIS (NOT THE RIGHT CLIENT 100% OF THE TIME!!!!!!!)
2022-05-24 08:55:57 +03:00
ecoimport . CreateNewCollection ( message , client , server , message . mentions . users . first (). id );
}
2022-05-28 16:55:56 +03:00
//#endregion
2022-05-24 08:55:57 +03:00
client . connect ( err => {
const db = client . db ( String ( server ) + "[ECON]" );
const dbo = db . collection ( id );
if ( err ) { return console . log ( err ); }
//Check if the client is currently in a game and act accordingly
2022-05-28 16:55:56 +03:00
//#region Check Game
2022-05-24 08:55:57 +03:00
dbo . find ({ "game" : { $exists : true }}). toArray ( async function ( err , docs ){
2022-05-28 16:55:56 +03:00
if ( err ) { return console . log ( err ); }
2022-05-24 08:55:57 +03:00
let doc = docs [ 0 ];
2022-05-25 22:33:42 +03:00
let game = null ;
if ( doc ) { game = doc . game ; }
2022-05-28 16:55:56 +03:00
//#endregion
2022-05-24 08:55:57 +03:00
2022-05-28 16:55:56 +03:00
//#region non-game-specific commands
//For TWO+ PLAYER games only!!!
2022-05-24 08:55:57 +03:00
if ( command == 'accept' ) {
//Handle the messages
if ( message . reference == null ) { return message . reply ( "Please reply to a valid battle request message!" ); }
let mid = message . reference . messageId ;
let msg = await message . channel . messages . fetch ( mid );
//Check if the person actually challenged you
2022-05-28 16:55:56 +03:00
//Get the length of any user tag
2022-05-24 08:55:57 +03:00
let mentioned = msg . mentions . users . keys ();
2022-05-28 16:55:56 +03:00
let tag_len = String ( mentioned . next (). value ). length ;
//<@tage_len>, <@ --2+tag_len+2+3 = 7+tag_len
let other_tag = msg . content . substr ( 7 + tag_len , tag_len );
const other_discord = msg . mentions . users . get ( other_tag );
//Should also check if the player is already playing a game!!!
if ( ! acceptIsValid ( bot , other_discord , message , msg , tag_len )) { return ; }
2022-05-25 22:33:42 +03:00
2022-05-24 08:55:57 +03:00
//Get the opponent
2022-05-28 16:55:56 +03:00
const other = db . collection ( other_discord . id );
2022-05-25 22:33:42 +03:00
let startPos = msg . content . indexOf ( '"' ) + 1 ;
let newCommand = msg . content . substr ( startPos , msg . content . lastIndexOf ( '"' ) - startPos );
2022-05-28 16:55:56 +03:00
//#region BOT SECTION
//Store both IDs in the database (for turns)
let name_first = await bot . users . cache . get ( id );
let name_second = await bot . users . cache . get ( other_discord . id );
// message.reply(`${first} [${name_first}], ${second} [${name_second}]`); throw 'ERR';
const threadname = ` ${ name_first . username } VS ${ name_second . username } [ ${ newCommand . toUpperCase () } ]` ;
var newObj = { 0 : id , 1 : other_discord . id , turn : 0 , thread : threadname };
serverinbotdb . insertOne ( newObj );
//#endregion
2022-05-25 22:33:42 +03:00
if ( newCommand == 'battle' ) {
2022-05-28 16:55:56 +03:00
const result = Initialize ( bot , dbo , newCommand , msg , id , other_discord . id , other );
result . then ( function ( thread ) {
2022-05-29 20:59:39 +03:00
handle ( client , dbo , other , bot , thread , 'initalize' , mongouri , items , null , xp_collection );
2022-05-28 16:55:56 +03:00
});
2022-05-25 22:33:42 +03:00
}
2022-05-28 16:55:56 +03:00
} else if ( command == 'quit' ) {
const channel = bot . channels . cache . get ( message . channel . parentId );
//Remove the turn counter from the bot's database
serverinbotdb . deleteOne ({ 0 : id } || { 1 : id });
if ( doc . opponent != null ) {
// let other = message.guild.members.cache.get(doc.opponent);
let other = db . collection ( doc . opponent );
channel . send ( `<@ ${ message . author . id } > has quit a game of " ${ game } " with <@ ${ doc . opponent } >!` );
winGame ( client , bot , db , other , xp_collection , message );
} else {
loseGame ( dbo , xp_collection , message , bot );
channel . send ( `<@ ${ message . author . id } > has quit a game of " ${ game } "!` );
}
}
else if ( command == 'status' ) {
getGame ( message , args , db );
} else if ( command == 'hp' || command == 'mp' ) {
hpmp ( message , command , dbo );
}
//#endregion
//#region game-specific commands
else {
if ( game == 'battle' || command == 'battle' ) {
2022-05-24 08:55:57 +03:00
//Handle sending the request and making sure the user exists here
let other_discord = message . mentions . users . first ();
if ( other_discord == undefined ) {
return message . reply ( ` ${ args [ 1 ] } is not a valid user!` );
}
2022-05-25 22:33:42 +03:00
message . channel . send ( ` ${ other_discord } , <@ ${ message . author . id } > has invited you to play "battle", to accept, please reply to this message with _!game accept_` );
2022-05-24 08:55:57 +03:00
}
//Catch statement (invalid command)
else {
2022-05-25 22:33:42 +03:00
if ( command == undefined ) { message . reply ( "Please specify a game or use _!game help_" ); }
else { message . reply ( `'!game ${ command } ' is not a command!` ); }
2022-05-24 08:55:57 +03:00
}
}
2022-05-28 16:55:56 +03:00
//#endregion
2022-05-24 08:55:57 +03:00
});
});
client . close ();
2022-05-28 16:55:56 +03:00
}, allGames , in_game_redirector
2022-05-24 08:55:57 +03:00
}