diff --git a/database.js b/database.js index f7a2c88..5f5d6a7 100644 --- a/database.js +++ b/database.js @@ -194,7 +194,9 @@ function dbGetDeckList(){ const dPromise = new Promise((resolve, reject) => { let cards = []; let sql = `SELECT - cardId + deckId + ,playerId + ,cardId ,cardCount FROM deck_cards `; @@ -217,7 +219,6 @@ function dbGetCards(){ ,cardAttack ,cardRarity FROM card - LIMIT 2 `; con.query(sql, function (err, result, fields) { diff --git a/server.js b/server.js index 8ce6104..3f3d8af 100644 --- a/server.js +++ b/server.js @@ -44,10 +44,14 @@ for (let roomId = 1; roomId <= numRoomsToPreGen; roomId++) { // Maybe if this works, put it into a deck and card module // Doing similar to I have to other stuff, that will need to be // migrated serverside anyways. + +/* let item = []; let deckItem = {}; let deckList = {}; let cardItem = {}; +*/ + // cardClass, cardColourRequirement // may want to be seperate too (as well as in cardItem), so that // during match they can be altered by effects while keeping the OG card @@ -59,111 +63,133 @@ let cardItem = {}; // then will rejig when needed. // Should all cards, effects, classes etc. be loaded in on server start // then just load decks and decklists when needed? -function getDecks(deckId, playerId){ +function getDecks(deckId, playerId, item = [], deckItem = {}){ // Await promise, once it's done get the data, if errors send err - database.dbGetDecks().then(data => { - data.forEach((deck) => { - let itemId = item.length; - item.push(itemId); // Add the next available item - // Add the deck info to deckItem - deckItem[itemId] = { - 'deckId': deck.deckId, - 'playerId': deck.playerId, - 'deckName': deck.deckName, - }; - }); - //console.log(item); - //console.log(deckItem); - }) - .catch(err => { throw err; }) + const dPromise = new Promise((resolve, reject) => { + + database.dbGetDecks().then(data => { + + let decks = []; + + data.forEach((deck) => { + //let itemId = item.length; + //item.push(itemId); // Add the next available item + // Add the deck info to deckItem + // deckItem[itemId] = {}; + decks.push({ + 'deckId': deck.deckId, + 'playerId': deck.playerId, + 'deckName': deck.deckName, + }); + }); + + // Resolve the decks pulled + resolve(decks); + + //console.log(item); + //console.log(deckItem); + //console.log(decks); + }) + .catch(err => { throw err; }) + + }); + return dPromise; } -getDecks(); +//getDecks(); function getDeckList(){ - database.dbGetDeckList().then(data => { - data.forEach((listItem) => { - let itemId = item.length; - item.push(itemId); // Add the next available item - // Add the deck info to deckItem - deckList[itemId] = { - 'cardId': listItem.cardId, - 'cardCount': listItem.cardCount, - }; - }); - //console.log(item); - //console.log(deckList); - }) - .catch(err => { throw err; }) + const dPromise = new Promise((resolve, reject) => { + + database.dbGetDeckList().then(data => { + + let deckList = []; + + data.forEach((listItem) => { + // Add the deck info to deckItem + deckList.push({ + 'deckId': listItem.deckId, + 'playerId': listItem.playerId, + 'cardId': listItem.cardId, + 'cardCount': listItem.cardCount, + }); + resolve(deckList); + }); + }) + .catch(err => { throw err; }) + }); + return dPromise; } -getDeckList(); +//getDeckList(); function getCards(){ - console.log - database.dbGetCards().then(data => { - data.forEach((card) => { - let itemId = item.length; - item.push(itemId); // Add the next available item - // Add the deck info to deckItem - cardItem[itemId] = { - 'cardId': card.id, - 'cardName': card.cardName, - 'cardCost': card.cardCost, - 'cardType': card.cardType, - 'cardAttack': card.cardAttack, - 'cardRarity': card.cardRarity, - 'cardClass': [], - 'cardColourRequirement': [], - }; - }); - //console.log(item); - //console.log(cardItem); - }) - .catch(err => { throw err; }) + const dPromise = new Promise((resolve, reject) => { + + database.dbGetCards().then(data => { + + let cards = []; + + data.forEach((card) => { + cards.push({ + 'id': card.id, + 'cardName': card.cardName, + 'cardCost': card.cardCost, + 'cardType': card.cardType, + 'cardAttack': card.cardAttack, + 'cardRarity': card.cardRarity, + 'cardClass': [], + 'cardColourRequirement': [], + }); + }); + resolve(cards); + }) + .catch(err => { throw err; }) + + }); + return dPromise; } -getCards(); +//getCards(); function getCardClasses(){ - database.dbGetCardClasses().then(data => { - data.forEach((cardClass) => { - - // Loop existing cardItems, compare cardId - // If there's a match add cardClass to the card? - for(let i = 0; i < item.length; i++){ - // If the item has a cardItem - if(i in cardItem){ - // And the cardId matches the linked table - if(cardItem[i].cardId == cardClass.cardId){ - cardItem[i].cardClass.push(cardClass.classId); - } - } - } - }); - //console.log(item); - //console.log(cardItem); - }) - .catch(err => { throw err; }) + const dPromise = new Promise((resolve, reject) => { + database.dbGetCardClasses().then(data => { + + let cardClasses = []; + + data.forEach((cardClass) => { + + cardClasses.push({ + 'cardId': cardClass.cardId, + 'classId': cardClass.classId, + }); + + }); + resolve(cardClasses); + }) + .catch(err => { throw err; }) + }); + return dPromise; } -getCardClasses(); +//getCardClasses(); function getCardColourRequirement(){ - database.dbGetCardColourRequirement().then(data => { - data.forEach((cardColourReq) => { - - // Loop existing cardItems, compare cardId - // If there's a match add cardClass to the card? - for(let i = 0; i < item.length; i++){ - // If the item has a cardItem (needed to add reqs.) - if(i in cardItem){ - // And the cardId matches the linked table - if(cardItem[i].cardId == cardColourReq.cardId){ - cardItem[i].cardColourRequirement.push([cardColourReq.colourId, cardColourReq.cost]); - } - } - } - }); - //console.log(item); - console.log(util.inspect(cardItem, true, 4, true)); - //console.log(cardItem); - }) - .catch(err => { throw err; }) + const dPromise = new Promise((resolve, reject) => { + database.dbGetCardColourRequirement().then(data => { + + let colourRequirements = []; + + data.forEach((cardColourReq) => { + + colourRequirements.push({ + 'cardId': cardColourReq.cardId, + 'colourId': cardColourReq.colourId, + 'cost': cardColourReq.cost, + }); + + }); + resolve(colourRequirements); + + }) + .catch(err => { throw err; }) + }); + return dPromise; } -getCardColourRequirement(); +//getCardColourRequirement(); // Then effects which will have effects with parent triggers, and unit type checks // colour checks, all sorts. So will be more difficult. Basic (flight, etc) // shouldn't be too bad @@ -174,6 +200,185 @@ getCardColourRequirement(); // but better than hard coding anything more than basic effects and effect check logic // TODO: effect (as above) +// request a deck in the format CURRENTLY used in the game +// decks will likely be changed around + +// https://www.geeksforgeeks.org/how-to-wait-for-multiple-promises-in-javascript/ +// using last example +async function requestDeck(playerId, deckId){ + + // Get the deck(s) requested. + // Not 100% on how to do two differening atm + // Besides all of playerId, and all of deckId. But 1,2/2,3 for instance + const [decks, deckList] = + await Promise.all([ + getDecks(), + getDeckList() + // Don't need to do this for each when awaiting all + // Instead it'll wait until each is done, set the data to the const + // Then do the stuff after the variable's are set!! + /* + getDecks().then(data => { + //console.log(data); + }).catch(err => { throw err; }), + */ + + ]); + + //console.log(decks); + //console.log(deckList); + // Now loop the deckList for the cardIds + let deckCardIds = []; + deckList.forEach((deckItem) => { + deckCardIds.push(deckItem.cardId); + + }); + //console.log(deckCardIds); + + // Next, get the cards in the deck by their ID + // TODO: https://stackoverflow.com/a/65510676 + // Change SQL to accept for just the cards passed + + // Get each cards data, colourReqs, and classes + const [cards, cardClasses, cardColourRequirements] = + await Promise.all([ + getCards(), + getCardClasses(), + getCardColourRequirement(), + ]); + // ^^^^ Classes async? Can pass the cardsIds, then loop classes, if the class cardId + // matches the cardId in cards[] then push the class to cards[x].classes + + // TODO: Build the card so far async for it's done alongside getting effects? + // Then when both done add the effects to the existing cardObjects? Yep good idea me + //console.log(cards); + //console.info(cardClasses); + //console.log(cardColourRequirements); + + const [builtCards] = + await Promise.all([ + buildCards(cards, cardClasses, cardColourRequirements), + // TODO: builtEffects + ]); + + //console.log(builtCards); + // TODO: addEffectsToCards + // TODO: Finally do the effects for each card. This will be the complicater + // since it's not 100% thought out yet... ( + + // Add the cards (x of how many cardObjects with cardId are in count in decklist) + // to a deck array to pass through. Or decks array with deckId specified? + console.log(deckList); + // These are the four basic fellas for this + // from public/board.js where current game testing/logic is applied + // So creating as a test for a 'room' to see if it's simple enough to + // send and play with + // BUILD THE DATA TO SEND TO CLIENTS! (Kinda) + let item = []; + let itemCount = 0; + let deckData = {}; // New but may be useful + let cardData = {}; + let boardElement = {}; + // TODO: Set the player. For now will do this in front-end as testing currently + + // Loop each item in the deckList + // Loop inside it X times where X is cardCount + // Add the builtCard with same cardId as deckList item X times + deckList.forEach((deckListItem) => { + // Check if it's a new deck (not sure how) + if(false){ // TODO: Logic check + item.push(itemCount); // Add new item to add stuff for + deckData[itemCount] = [deckListItem.deckId, deckListItem.playerId]; + boardElement[itemCount] = 'realDeck'; + itemCount++; + } + + // For each new card, loop to the cardCount (how many cards in deck) + // and add to the deck + for(let i = 0; i < deckListItem.cardCount; i++){ + item.push(itemCount); // Add new item to add stuff for + // ^ not using item.length incase anything in future gets deleted + // from item for instance + cardData[itemCount] = builtCards[deckListItem.cardId]; // builtCards id set to cardId from DB, so adding the builtCard object is based on the deckList's cardId (from DB) + boardElement[itemCount] = 'deck'; // Add all cards to deck at match start + itemCount++; // Increment item to not overwrite + } + + }); + + //console.log(cardData); + + let response = {'success':true, 'message':'Nothing happened'}; + response.message = cardData; // Add the cardData generated to the response + io.to(socket.id).emit('responseGetDeck', response); + // TODO: In future the item inc. all the decks, cards, locations, and other attributes + // will come from here + + // TODO: unrelated, but thought. If lots of players on, generating cards each time + // will be a big hit, as well as all the DB hits, so may need to load all cardObjects + // into memory/array when server starts. This then prevents any DB changes to alter + // things, but outside of testing that won't occur(?), may need to test this at some + // point to see. For now DB, and generating is ok, as still working on it +} + +function buildCards(cards, cardClasses, cardColourRequirements){ + + const dPromise = new Promise((resolve, reject) => { + + builtCards = {}; + + //console.log(cards); + // Loop the cards and build the base + cards.forEach((card) => { + + let builtCard = { + id: card.id, + name: card.cardName, + colour: [], + cost: card.cardCost, + costReq: [], + type: card.cardType, + atk: card.cardAttack, + rarity: card.cardRarity, + effect: [], + cardClass: [], + }; + // Give the card an easily accessible Id for compares + // and to add to the cardItem being built + builtCards[card.id] = builtCard; + + }); + //console.log(builtCards); + + // Next loop each class, and add to the new builtCard (if cardIds match) + cardClasses.forEach((cardClass) => { + + // Check the card exists (it should always, but don't want jank) + if(cardClass.cardId in builtCards){ + // It's the Id for now + // TODO: Send the text too (from join) but don't use for compares + //console.log(cardClass.cardId); + //console.log(cardClass.classId); + //console.log('---'); + //console.log(builtCards[cardClass.cardId]); + + // Add the class to the class array (cards can have multiple) + builtCards[cardClass.cardId].cardClass.push(cardClass.classId); + + // TODO: As an array [classId, className] then + // card.classes[x][0] can be compared as numeric in code + } + + }); + + resolve(builtCards); + + }); + return dPromise; +} +// TODO: Add the effects onto the cards passed through +// Takes cards array (of obj), and array of effects (from DB or built, probabaly pre-built?) +function addCardsEffects(){} // End For testing @@ -185,6 +390,12 @@ function onConnection(socket){ socket.on('requestGetCards', function(deckId, playerId) { requestGetCards(socket, deckId, playerId); }); + // New testing fella (working afaik) + // TODO: request specific deckId/playerId (and multiples, i.e. get 6 decks at same + // time, based on deckId/playerId combo. Maybe pass as array [deckId, playerId],[deck + socket.on('requestDeck', function() { + requestDeck(socket); + }); socket.on('requestRooms', function(filter) { requestRooms(socket, filter); @@ -365,4 +576,3 @@ function requestGetCards(socket, deckId, playerId){ io.to(socket.id).emit('responseGetCards', err); }) } -