diff --git a/sdvx@asphyxia/handlers/profiles.ts b/sdvx@asphyxia/handlers/profiles.ts index f2690bd..2ab5d88 100644 --- a/sdvx@asphyxia/handlers/profiles.ts +++ b/sdvx@asphyxia/handlers/profiles.ts @@ -1,944 +1,950 @@ -import { Skill } from '../models/skill'; -import { SDVX_AUTOMATION_SONGS } from '../data/vvw'; -import { Item } from '../models/item'; -import { Param } from '../models/param'; -import { Arena } from '../models/arena'; -import { MusicRecord } from '../models/music_record'; -import { CourseRecord } from '../models/course_record'; -import { Profile } from '../models/profile'; -import { getVersion, IDToCode } from '../utils'; -import { Mix } from '../models/mix'; -import { ARENA, EVENT_SONGS6, RESTRICTED_SONGS6 } from '../data/exg'; - -async function getAutomationMixes(params: Param[]) { - const mixids = params - .filter(p => p.id == 3) - .reduce((res, p) => _.union(res, p.param), []); - return await DB.Find({ collection: 'mix', id: { $in: mixids } }); -} - -function unlockNavigators(items: Partial[]) { - for (let i = 0; i < 300; ++i) items.push({ type: 11, id: i, param: 15 }); - console.log("Unlocking Navigators"); - // 10 genesis card for MITSURU's voice - items.push({ type: 4, id: 599, param: 10 }); - return items; -} - -function unlockAppealCards(items: Partial[]) { - for (let i = 0; i < 6000; ++i) items.push({ type: 1, id: i, param: 1 }); - console.log("Unlocking Appeal Cards"); - - return items; -} - -function removeStampItems(items: Partial[]) { - let itemsToRemove = [] - for (let index in items) { - if (items[index].type === 17 && items[index].id % 4 != 0) { - itemsToRemove.push(index) - } - } - - for (let itemIndex in itemsToRemove.reverse()) { - items.splice(itemsToRemove[itemIndex], 1) - } - - for (let x=0; x { - console.log("Now loading score"); - const version = Math.abs(getVersion(info)); - console.log("Got version: " + version); - let refid = $(data).str('refid', $(data).attr().dataid); - if (version === 2) refid = $(data).str('dataid', '0'); - //console.log('loading score'); - console.log("DataID:" + refid); - if (!refid) return send.deny(); - console.log('Finding record'); - const records = await DB.Find(refid, { collection: 'music' }); - - - //console.log(version); - if (version === 1) { - return send.object({ - music: records.map(r => (K.ATTR({ music_id: String(r.mid) }, { - type: (() => { - const records = []; - - for (let i = 1; i <= 3; i++) { - if (r.type != i) continue; - records.push(K.ATTR({ - type_id: String(i), - score: String(r.score), - clear_type: String(r.clear), - score_grade: String(r.grade), - cnt: "0" - })); - } - - return records; - })() - }))) - }); - } - - if (version === 2) { - let temp = Array.from(records.values()).filter(r => (r.mid <= 554)); - //console.log([...temp]); - //return send.pugFile('templates/infiniteinfection/score.pug', { - // temp}); - return send.object( - { - "new": { - music: temp.map(r => ({ - music_id: K.ITEM('u32', r.mid), - music_type: K.ITEM('u32', r.type), - score: K.ITEM('u32', r.score), - cnt: K.ITEM('u32', 1), - clear_type: K.ITEM('u32', r.clear), - score_grade: K.ITEM('u32', r.grade), - btn_rate: K.ITEM('u32', r.buttonRate), - long_rate: K.ITEM('u32', r.longRate), - vol_rate: K.ITEM('u32', r.volRate), - })) - }, old: {} - }, { rootName: "game" }); - } - - if (version === 6) { - return send.object({ - music: { - info: records.map(r => ({ - param: K.ARRAY('u32', [ - r.mid, - r.type, - r.score, - r.exscore, - r.clear, - r.grade, - 0, - 0, - r.buttonRate, - r.longRate, - r.volRate, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - ]), - })), - }, - }); - } - - if (version === 4 || version === 3) { - let temp = Array.from(records.values()).filter(r => (r.mid <= 1368)); - - - return send.object({ - music: { - info: temp.map(r => ({ - param: K.ARRAY('u32', [ - r.mid, - r.type, - r.score, - r.clear, - r.grade, - 0, - 0, - r.buttonRate, - r.longRate, - r.volRate, - 0, - 0, - 0, - 0, - 0, - 0, - ]), - }) - ), - }, - }); - } - - - return send.object({ - music: { - info: records.map(r => ({ - param: K.ARRAY('u32', [ - r.mid, - r.type, - r.score, - r.clear, - r.grade, - 0, - 0, - r.buttonRate, - r.longRate, - r.volRate, - 0, - 0, - 0, - 0, - 0, - 0, - ]), - })), - }, - }); -}; - -export const saveScore: EPR = async (info, data, send) => { - const refid = $(data).str('refid', $(data).attr().dataid); - if (!refid) return send.deny(); - - const version = getVersion(info); - - // Booth - Save score - if (version === 1) { - try { - const mid = parseInt($(data).attr().music_id); - const type = parseInt($(data).attr().music_type); - - if (_.isNil(mid) || _.isNil(type)) return send.deny(); - - const record = (await DB.FindOne(refid, { - collection: 'music', - mid, - type, - })) || { - collection: 'music', - mid, - type, - score: 0, - clear: 0, - grade: 0, - buttonRate: 0, - longRate: 0, - volRate: 0, - }; - - const score = $(data).attr().score ? parseInt($(data).attr().score) : 0; - const clear = $(data).attr().clear_type ? parseInt($(data).attr().clear_type) : 0; - const grade = $(data).attr().score_grade ? parseInt($(data).attr().score_grade) : 0; - if (score > record.score) { - record.score = score; - } - - record.clear = Math.max(clear, record.clear); - record.grade = Math.max(grade, record.grade); - - await DB.Upsert( - refid, - { collection: 'music', mid, type }, - record - ); - - return send.success(); - } catch { - return send.deny(); - } - } - - - if (version === -6) { // Using alternate scoring system after 20210831 - const tracks = $(data).elements('track'); - for (const i of tracks) { - const mid = i.number('music_id'); - const type = i.number('music_type'); - if (_.isNil(mid) || _.isNil(type)) return send.deny(); - - const record = (await DB.FindOne(refid, { - collection: 'music', - mid, - type, - })) || { - collection: 'music', - mid, - type, - score: 0, - exscore: 0, - clear: 0, - grade: 0, - buttonRate: 0, - longRate: 0, - volRate: 0, - }; - - const score = i.number('score', 0); - const exscore = i.number('exscore', 0); - if (score > record.score) { - record.score = score; - record.buttonRate = i.number('btn_rate', 0); - record.longRate = i.number('long_rate', 0); - record.volRate = i.number('vol_rate', 0); - } - if (exscore > record.exscore) { - record.exscore = exscore; - } - - record.clear = Math.max(i.number('clear_type', 0), record.clear); - record.grade = Math.max(i.number('score_grade', 0), record.grade); - - - - await DB.Upsert( - refid, - { collection: 'music', mid, type }, - record - ); - } - return send.success(); - } - - - - const mid = $(data).number('music_id'); - const type = $(data).number('music_type'); - console.log("Saving score for version later than HH(include), ID:" + mid + " type:" + type); - if (_.isNil(mid) || _.isNil(type)) return send.deny(); - - const record = (await DB.FindOne(refid, { - collection: 'music', - mid, - type, - })) || { - collection: 'music', - mid, - type, - score: 0, - exscore: 0, - clear: 0, - grade: 0, - buttonRate: 0, - longRate: 0, - volRate: 0, - }; - - const score = $(data).number('score', 0); - const exscore = $(data).number('exscore', 0); - if (score > record.score) { - record.score = score; - record.buttonRate = $(data).number('btn_rate', 0); - record.longRate = $(data).number('long_rate', 0); - record.volRate = $(data).number('vol_rate', 0); - } - if (exscore > record.exscore) { - record.exscore = exscore; - } - - record.clear = Math.max($(data).number('clear_type', 0), record.clear); - record.grade = Math.max($(data).number('score_grade', 0), record.grade); - - - - await DB.Upsert( - refid, - { collection: 'music', mid, type }, - record - ); - - return send.success(); -}; - -export const saveCourse: EPR = async (info, data, send) => { - const refid = $(data).str('refid'); - if (!refid) return send.deny(); - - const version = Math.abs(getVersion(info)); - if (version == 0) return send.deny(); - - const sid = $(data).number('ssnid'); - const cid = $(data).number('crsid'); - - if (_.isNil(sid) || _.isNil(cid)) return send.deny(); - - await DB.Upsert( - refid, - { collection: 'course', sid, cid, version }, - { - $max: { - score: $(data).number('sc', 0), - clear: $(data).number('ct', 0), - grade: $(data).number('gr', 0), - rate: $(data).number('ar', 0), - }, - $inc: { - count: 1, - }, - } - ); - - return send.success(); -}; - -export const save: EPR = async (info, data, send) => { - const refid = $(data).str('refid', $(data).attr().refid); - if (!refid) return send.deny(); - - const version = Math.abs(getVersion(info)); - if (version == 0) return send.deny(); - - if (version === 1) { - try { - // Save Profile - await DB.Update( - refid, - { collection: 'profile' }, - { - $set: { - headphone: $(data).number('headphone'), - hiSpeed: $(data).number('hispeed'), - appeal: $(data).number('appeal_id'), - boothFrame: [$(data).number('frame0'), $(data).number('frame1'), $(data).number('frame2'), $(data).number('frame3'), $(data).number('frame4')], - musicID: parseInt($(data).attr("last").music_id), - musicType: parseInt($(data).attr("last").music_type), - sortType: parseInt($(data).attr("last").sort_type), - mUserCnt: $(data).number('m_user_cnt'), - }, - $inc: { - expPoint: $(data).number('gain_exp'), - packets: $(data).number('earned_gamecoin_packet'), - blocks: $(data).number('earned_gamecoin_block'), - }, - } - ); - - return send.success(); - } catch { - return send.deny(); - } - } - - // Save Profile - if (version === 6) { - await DB.Update( - refid, - { collection: 'profile' }, - { - $set: { - appeal: $(data).number('appeal_id'), - - musicID: $(data).number('music_id'), - musicType: $(data).number('music_type'), - sortType: $(data).number('sort_type'), - headphone: $(data).number('headphone'), - blasterCount: $(data).number('blaster_count'), - - hiSpeed: $(data).number('hispeed'), - laneSpeed: $(data).number('lanespeed'), - gaugeOption: $(data).number('gauge_option'), - arsOption: $(data).number('ars_option'), - notesOption: $(data).number('notes_option'), - earlyLateDisp: $(data).number('early_late_disp'), - drawAdjust: $(data).number('draw_adjust'), - effCLeft: $(data).number('eff_c_left'), - effCRight: $(data).number('eff_c_right'), - narrowDown: $(data).number('narrow_down'), - }, - $inc: { - packets: $(data).number('earned_gamecoin_packet'), - blocks: $(data).number('earned_gamecoin_block'), - blasterEnergy: $(data).number('earned_blaster_energy'), - extrackEnergy: $(data).number('earned_extrack_energy'), - playCount: 1, - dayCount: 1, - todayCount: 1, - playChain: 1, - maxPlayChain: 1, - weekCount: 1, - weekPlayCount: 1, - weekChain: 1, - maxWeekChain: 1 - }, - } - ); - } - if (version === 5 || version === 4) { - await DB.Update( - refid, - { collection: 'profile' }, - { - $set: { - appeal: $(data).number('appeal_id'), - - musicID: $(data).number('music_id'), - musicType: $(data).number('music_type'), - sortType: $(data).number('sort_type'), - headphone: $(data).number('headphone'), - blasterCount: $(data).number('blaster_count'), - - hiSpeed: $(data).number('hispeed'), - laneSpeed: $(data).number('lanespeed'), - gaugeOption: $(data).number('gauge_option'), - arsOption: $(data).number('ars_option'), - notesOption: $(data).number('notes_option'), - earlyLateDisp: $(data).number('early_late_disp'), - drawAdjust: $(data).number('draw_adjust'), - effCLeft: $(data).number('eff_c_left'), - effCRight: $(data).number('eff_c_right'), - narrowDown: $(data).number('narrow_down'), - }, - $inc: { - packets: $(data).number('earned_gamecoin_packet'), - blocks: $(data).number('earned_gamecoin_block'), - blasterEnergy: $(data).number('earned_blaster_energy'), - playCount: 1, - dayCount: 1, - todayCount: 1, - playChain: 1, - maxPlayChain: 1, - weekCount: 1, - weekPlayCount: 1, - weekChain: 1, - maxWeekChain: 1 - }, - } - ); - } - - // New course saving function found in sdvx 20220214 - const course = $(data).element('course'); - if(!_.isNil(course)){ - const sid = course.number('ssnid'); - const cid = course.number('crsid'); - - if (!(_.isNil(sid) || _.isNil(cid))){ - await DB.Upsert( - refid, - { collection: 'course', sid, cid, version }, - { - $max: { - score: course.number('sc', 0), - clear: course.number('ct', 0), - grade: course.number('gr', 0), - rate: course.number('ar', 0), - }, - $inc: { - count: 1, - }, - } - ); - } - } - - // Save Items - const items = $(data).elements('item.info'); - - for (const i of items) { - const type = i.number('type'); - const id = i.number('id'); - const param = i.number('param'); - - if (_.isNil(type) || _.isNil(id) || _.isNil(param)) continue; - - await DB.Upsert( - refid, - { collection: 'item', type, id }, - { $set: { param } } - ); - } - - // Save Param - const params = $(data).elements('param.info'); - for (const p of params) { - const type = p.number('type'); - const id = p.number('id'); - const param = p.numbers('param'); - - if (_.isNil(type) || _.isNil(id) || _.isNil(param)) continue; - - await DB.Upsert( - refid, - { collection: 'param', type, id }, - { $set: { param } } - ); - } - - // Save version specific data - await DB.Upsert( - refid, - { - collection: 'skill', - version, - }, - { - $set: { - base: $(data).number('skill_base_id'), - level: $(data).number('skill_level'), - name: $(data).number('skill_name_id'), - }, - } - ); - - // Save Arena Data - const arena_data = $(data).elements('arena'); - for (const are of arena_data) { - const earnedUR = are.number('earned_ultimate_rate'); - const earnedSP = are.number('earned_shop_point'); - const earnedRP = are.number('earned_rank_point'); - const earnedLE = are.number('earned_live_energy'); - const rankPlay = are.str('rank_play') == 'true' ? 1 : 0; - const ultimatePlay = are.str('ultimate_play') == 'true' ? 1 : 0; - await DB.Upsert( - refid, - { - collection: 'arena', - season: Object.keys(ARENA).findIndex(data => data == U.GetConfig('arena_szn')) + 1 - }, - { - $inc: { - ultimateRate: _.isNil(earnedUR) ? 0 : earnedUR, - shopPoint: _.isNil(earnedSP) ? 0 : earnedSP, - rankPoint: _.isNil(earnedRP) ? 0 : earnedRP, - liveEnergy: _.isNil(earnedLE) ? 0 : earnedLE, - rankCount: rankPlay, - ultimateCount: ultimatePlay - } - } - ); - } - - return send.success(); -}; - -export const load: EPR = async (info, data, send) => { - console.log("Loading savedata"); - const refid = $(data).str('refid', $(data).attr().dataid); - if (!refid) return send.deny(); - - const version = Math.abs(getVersion(info)); - console.log("Got version: " + version); - console.log("DataID: " + refid); - if (version == 0) return send.deny(); - - const profile = await DB.FindOne(refid, { - collection: 'profile', - }); - - if (!profile) { - if (version === 1) return send.object(K.ATTR({ none: "1" })); - return send.object({ result: K.ITEM('u8', 1) }); - } - - let skill = (await DB.FindOne(refid, { - collection: 'skill', - version, - })) || { base: 0, name: 0, level: 0 }; - - const items = await DB.Find(refid, { collection: 'item' }); - const courses = await DB.Find(refid, { collection: 'course', version }); - const params = await DB.Find(refid, { collection: 'param' }); - const arena = await DB.FindOne(refid, { collection: 'arena', season: Object.keys(ARENA).findIndex(data => data == U.GetConfig('arena_szn')) + 1 }); - let time = new Date(); - let tempHour = time.getHours(); - let tempDate = time.getDate(); - tempHour += 12; - tempDate += 1; - time.setDate(tempDate); - time.setHours(tempHour); - const currentTime = time.getTime(); - const mixes = version == 5 ? await getAutomationMixes(params) : []; - if (!profile.extrackEnergy) { - profile.extrackEnergy = 0; - } - - if (version === 1) { - return send.pugFile('templates/booth/load.pug', { code: IDToCode(profile.id), ...profile }); - } - - if (version === 2) { - let tempItem = U.GetConfig('unlock_all_appeal_cards') ? unlockAppealCards(items) : items - tempItem = Array.from(tempItem.values()).filter(r => (r.id <= 220)); - return send.pugFile('templates/infiniteinfection/load.pug', { - courses, - tempItem, - params, - skill, - ...profile - }); - } - const bgm = profile.bgm ? profile.bgm : 0; - const subbg = profile.subbg ? profile.subbg : 0; - const nemsys = profile.nemsys ? profile.nemsys : 0; - const stampA = profile.stampA ? profile.stampA : 0; - const stampB = profile.stampB ? profile.stampB : 0; - const stampC = profile.stampC ? profile.stampC : 0; - const stampD = profile.stampD ? profile.stampD : 0; - - - const customize = []; - customize.push(bgm, subbg, nemsys, stampA, stampB, stampC, stampD); - - var tempCustom = params.findIndex((e) => (e.type == 2 && e.id == 2)) - - if (tempCustom == -1) { - const tempParam: Param = { collection: 'param', type: 2, id: 2, param: [] }; - params.push(tempParam); - tempCustom = params.findIndex((e) => (e.type == 2 && e.id == 2)) - } - - if (params[tempCustom]) { - params[tempCustom].param = customize; - } - - - let blasterpass = U.GetConfig('use_blasterpass') ? 1 : 0; - - var tempItem = U.GetConfig('unlock_all_navigators') ? unlockNavigators(items) : items; - tempItem = U.GetConfig('unlock_all_appeal_cards') ? unlockAppealCards(items) : items; - tempItem = removeStampItems(tempItem) - - let eventData = JSON.parse(await IO.ReadFile('webui/asset/json/events.json')) - let eventConfig = JSON.parse(await IO.ReadFile('webui/asset/config/events.json')) - let presents = [] - for(const eventIter in eventData['events']) { - if(!eventData['events'][eventIter]['in_game_event']) { - if(typeof eventConfig[eventData['events'][eventIter]['id']]['toggle'] === "boolean") { - if(eventConfig[eventData['events'][eventIter]['id']]['toggle']) { - for(const itemIter in EVENT_SONGS6[eventData['events'][eventIter]['id']]) { - let itemId = parseInt(EVENT_SONGS6[eventData['events'][eventIter]['id']][itemIter]) - if(await DB.Count(refid, {collection:'item', id: itemId}) === 0) { - await DB.Upsert( - refid, - {collection: 'item', type: 0, id: itemId}, - {$set: { param: 23 }} - ) - - presents.push({ - id: itemId, - type: 0, - param: 23 - }) - - tempItem.push({ collection: 'item', type: 0, id: itemId, param: 23 }) - } - } - } - } else{ - // eventConfig[eventData['events'][eventIter]['id']]['toggle'] - for(const toggleKeys in Object.keys(eventConfig[eventData['events'][eventIter]['id']]['toggle'])) { - if(eventConfig[eventData['events'][eventIter]['id']]['toggle'][Object.keys(eventConfig[eventData['events'][eventIter]['id']]['toggle'])[toggleKeys]]) { - for(const itemIter in EVENT_SONGS6[Object.keys(eventConfig[eventData['events'][eventIter]['id']]['toggle'])[toggleKeys]]) { - let itemId = parseInt(EVENT_SONGS6[Object.keys(eventConfig[eventData['events'][eventIter]['id']]['toggle'])[toggleKeys]][itemIter]) - if(await DB.Count(refid, {collection:'item', id: itemId}) === 0) { - await DB.Upsert( - refid, - {collection: 'item', type: 0, id: itemId}, - {$set: { param: 23 }} - ) - - presents.push({ - id: itemId, - type: 0, - param: 23 - }) - - tempItem.push({ collection: 'item', type: 0, id: itemId, param: 23 }) - } - } - } - } - } - } - } - - // Make generator power always 100%, - for (let i = 0; i < 50; i++) { - const tempGene: Item = { collection: 'item', type: 7, id: i, param: 10 }; - tempItem.push(tempGene); - } - - return send.pugFile('templates/load.pug', { - courses, - items: tempItem, - present: presents, - params, - skill, - currentTime, - mixes, - version, - blasterpass, - automation: version == 5 ? SDVX_AUTOMATION_SONGS : [], - code: IDToCode(profile.id), - arena, - ...profile, - }); -}; - -export const create: EPR = async (info, data, send) => { - console.log("Creating profile"); - const refid = $(data).str('refid', $(data).attr().refid); - if (!refid) return send.deny(); - console.log("DataID" + refid); - const name = $(data).str('name', $(data).attr().name ? $(data).attr().name : 'GUEST'); - let id = _.random(0, 99999999); - while (await DB.FindOne(null, { collecttion: 'profile', id })) { - id = _.random(0, 99999999); - } - - const profile: Profile = { - pluginVer: 1, - - collection: 'profile', - id, - name, - appeal: 0, - akaname: 0, - blocks: 0, - packets: 0, - arsOption: 0, - drawAdjust: 0, - earlyLateDisp: 0, - effCLeft: 0, - effCRight: 1, - gaugeOption: 0, - hiSpeed: 0, - laneSpeed: 0, - narrowDown: 0, - notesOption: 0, - blasterCount: 0, - blasterEnergy: 0, - extrackEnergy: 0, - bgm: 0, - subbg: 0, - nemsys: 0, - stampA: 0, - stampB: 0, - stampC: 0, - stampD: 0, - - headphone: 0, - musicID: 0, - musicType: 0, - sortType: 0, - expPoint: 0, - mUserCnt: 0, - boothFrame: [0, 0, 0, 0, 0], - - playCount: 0 - }; - - await DB.Upsert(refid, { collection: 'profile' }, profile); - return send.object({ result: K.ITEM('u8', 0) }); -}; - -export const buy: EPR = async (info, data, send) => { - console.log("buying") - const refid = $(data).str('refid'); - if (!refid) return send.deny(); - - const growth = { - blocks: $(data).number('earned_gamecoin_block', 0), - packets: $(data).number('earned_gamecoin_packet', 0), - }; - - const currency = $(data).bool('currency_type') ? 'blocks' : 'packets'; - - const cost = _.sum($(data).numbers('item.price', [])); - const balanceChange = growth[currency] - cost; - - const updated = await DB.Update( - refid, - { collection: 'profile', [currency]: { $gte: -balanceChange } }, - { $inc: { [currency]: balanceChange } } - ); - - if (updated.updated) { - const items = _.zipWith( - $(data).numbers('item.item_type', []), - $(data).numbers('item.item_id', []), - $(data).numbers('item.param', []), - (type, id, param) => ({ type, id, param }) - ); - - for (const item of items) { - await DB.Upsert( - refid, - { collection: 'item', type: item.type, id: item.id }, - { $set: { param: item.param } } - ); - } - - return send.object({ - gamecoin_packet: K.ITEM('u32', updated.docs[0].packets), - gamecoin_block: K.ITEM('u32', updated.docs[0].blocks), - }); - } else { - return send.success(); - } -}; - -export const print: EPR = async (info, data, send) => { - const genesisCards = $(data).elements('genesis_card'); - var genesisCardsArray = []; - var generatorArray = []; - for (const g of genesisCards) { - let tempGeneratorID = g.number('generator_id'); - let exist = generatorArray.findIndex((e) => (e == tempGeneratorID)); - if (exist == -1) { - generatorArray.push(tempGeneratorID); - } - } - send.object({ - result: K.ITEM('s8', 0), - genesis_cards: genesisCards.map(r => ({ - index: K.ITEM('s32', r.number('index')), - print_id: K.ITEM('s32', r.number('print_id')) - })), - after_power: generatorArray.map(r => ({ - generator_id: K.ITEM('s32', r), - param: K.ITEM('s32', 10), - })) - }), { status: "0" }; -} - -export const saveValgene: EPR = async (info, data, send) => { - console.log("Saving Valkyrie Generator Item") - const refid = $(data).str('refid'); - const items = $(data).elements('item.info'); - let itemsToAdd = [] - for (const i of items) { - const type = i.number('type'); - const id = i.number('id'); - const param = i.number('param'); - if(type === 17) { - for (let stampId = ((id * 4) - 3); stampId <= (id * 4); stampId++) { - itemsToAdd.push({'type': type, 'id': stampId, 'param': param}) - } - } else { - itemsToAdd.push({'type': type, 'id': id, 'param': param}) - } - } - - for(let itemToAdd in itemsToAdd) { - let id = itemsToAdd[itemToAdd].id - let type = itemsToAdd[itemToAdd].type - let param = itemsToAdd[itemToAdd].param - console.log("Saving (" + type + " | " + id + " | " + param + ")") - if (_.isNil(type) || _.isNil(id) || _.isNil(param)) continue; - - await DB.Upsert( - refid, - { collection: 'item', type, id }, - { $set: { param } } - ); - } - - return send.object({ result: K.ITEM('u8', 0) }); -} +import { Skill } from '../models/skill'; +import { SDVX_AUTOMATION_SONGS } from '../data/vvw'; +import { Item } from '../models/item'; +import { Param } from '../models/param'; +import { Arena } from '../models/arena'; +import { MusicRecord } from '../models/music_record'; +import { CourseRecord } from '../models/course_record'; +import { Profile } from '../models/profile'; +import { getVersion, IDToCode } from '../utils'; +import { Mix } from '../models/mix'; +import { ARENA, EVENT_SONGS6, RESTRICTED_SONGS6 } from '../data/exg'; + +async function getAutomationMixes(params: Param[]) { + const mixids = params + .filter(p => p.id == 3) + .reduce((res, p) => _.union(res, p.param), []); + return await DB.Find({ collection: 'mix', id: { $in: mixids } }); +} + +function unlockNavigators(items: Partial[]) { + for (let i = 0; i < 300; ++i) items.push({ type: 11, id: i, param: 15 }); + console.log("Unlocking Navigators"); + // 10 genesis card for MITSURU's voice + items.push({ type: 4, id: 599, param: 10 }); + return items; +} + +function unlockAppealCards(items: Partial[]) { + for (let i = 0; i < 6000; ++i) items.push({ type: 1, id: i, param: 1 }); + console.log("Unlocking Appeal Cards"); + + return items; +} + +function removeStampItems(items: Partial[]) { + let itemsToRemove = [] + for (let index in items) { + if (items[index].type === 17 && items[index].id % 4 != 0) { + itemsToRemove.push(index) + } + } + + for (let itemIndex in itemsToRemove.reverse()) { + items.splice(itemsToRemove[itemIndex], 1) + } + + for (let x=0; x { + console.log("Now loading score"); + const version = Math.abs(getVersion(info)); + console.log("Got version: " + version); + let refid = $(data).str('refid', $(data).attr().dataid); + if (version === 2) refid = $(data).str('dataid', '0'); + //console.log('loading score'); + console.log("DataID:" + refid); + if (!refid) return send.deny(); + console.log('Finding record'); + const records = await DB.Find(refid, { collection: 'music' }); + + + //console.log(version); + if (version === 1) { + return send.object({ + music: records.map(r => (K.ATTR({ music_id: String(r.mid) }, { + type: (() => { + const records = []; + + for (let i = 1; i <= 3; i++) { + if (r.type != i) continue; + records.push(K.ATTR({ + type_id: String(i), + score: String(r.score), + clear_type: String(r.clear), + score_grade: String(r.grade), + cnt: "0" + })); + } + + return records; + })() + }))) + }); + } + + if (version === 2) { + let temp = Array.from(records.values()).filter(r => (r.mid <= 554)); + //console.log([...temp]); + //return send.pugFile('templates/infiniteinfection/score.pug', { + // temp}); + return send.object( + { + "new": { + music: temp.map(r => ({ + music_id: K.ITEM('u32', r.mid), + music_type: K.ITEM('u32', r.type), + score: K.ITEM('u32', r.score), + cnt: K.ITEM('u32', 1), + clear_type: K.ITEM('u32', r.clear), + score_grade: K.ITEM('u32', r.grade), + btn_rate: K.ITEM('u32', r.buttonRate), + long_rate: K.ITEM('u32', r.longRate), + vol_rate: K.ITEM('u32', r.volRate), + })) + }, old: {} + }, { rootName: "game" }); + } + + if (version === 6) { + return send.object({ + music: { + info: records.map(r => ({ + param: K.ARRAY('u32', [ + r.mid, + r.type, + r.score, + r.exscore, + r.clear, + r.grade, + 0, + 0, + r.buttonRate, + r.longRate, + r.volRate, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ]), + })), + }, + }); + } + + if (version === 4 || version === 3) { + let temp = Array.from(records.values()).filter(r => (r.mid <= 1368)); + + + return send.object({ + music: { + info: temp.map(r => ({ + param: K.ARRAY('u32', [ + r.mid, + r.type, + r.score, + r.clear, + r.grade, + 0, + 0, + r.buttonRate, + r.longRate, + r.volRate, + 0, + 0, + 0, + 0, + 0, + 0, + ]), + }) + ), + }, + }); + } + + + return send.object({ + music: { + info: records.map(r => ({ + param: K.ARRAY('u32', [ + r.mid, + r.type, + r.score, + r.clear, + r.grade, + 0, + 0, + r.buttonRate, + r.longRate, + r.volRate, + 0, + 0, + 0, + 0, + 0, + 0, + ]), + })), + }, + }); +}; + +export const saveScore: EPR = async (info, data, send) => { + const refid = $(data).str('refid', $(data).attr().dataid); + if (!refid) return send.deny(); + + const version = getVersion(info); + + // Booth - Save score + if (version === 1) { + try { + const mid = parseInt($(data).attr().music_id); + const type = parseInt($(data).attr().music_type); + + if (_.isNil(mid) || _.isNil(type)) return send.deny(); + + const record = (await DB.FindOne(refid, { + collection: 'music', + mid, + type, + })) || { + collection: 'music', + mid, + type, + score: 0, + clear: 0, + grade: 0, + buttonRate: 0, + longRate: 0, + volRate: 0, + }; + + const score = $(data).attr().score ? parseInt($(data).attr().score) : 0; + const clear = $(data).attr().clear_type ? parseInt($(data).attr().clear_type) : 0; + const grade = $(data).attr().score_grade ? parseInt($(data).attr().score_grade) : 0; + if (score > record.score) { + record.score = score; + } + + record.clear = Math.max(clear, record.clear); + record.grade = Math.max(grade, record.grade); + + await DB.Upsert( + refid, + { collection: 'music', mid, type }, + record + ); + + return send.success(); + } catch { + return send.deny(); + } + } + + + if (version === -6) { // Using alternate scoring system after 20210831 + const tracks = $(data).elements('track'); + for (const i of tracks) { + const mid = i.number('music_id'); + const type = i.number('music_type'); + if (_.isNil(mid) || _.isNil(type)) return send.deny(); + + const record = (await DB.FindOne(refid, { + collection: 'music', + mid, + type, + })) || { + collection: 'music', + mid, + type, + score: 0, + exscore: 0, + clear: 0, + grade: 0, + buttonRate: 0, + longRate: 0, + volRate: 0, + }; + + const score = i.number('score', 0); + const exscore = i.number('exscore', 0); + if (score > record.score) { + record.score = score; + record.buttonRate = i.number('btn_rate', 0); + record.longRate = i.number('long_rate', 0); + record.volRate = i.number('vol_rate', 0); + } + if (exscore > record.exscore) { + record.exscore = exscore; + } + + record.clear = Math.max(i.number('clear_type', 0), record.clear); + record.grade = Math.max(i.number('score_grade', 0), record.grade); + + + + await DB.Upsert( + refid, + { collection: 'music', mid, type }, + record + ); + } + return send.success(); + } + + + + const mid = $(data).number('music_id'); + const type = $(data).number('music_type'); + console.log("Saving score for version later than HH(include), ID:" + mid + " type:" + type); + if (_.isNil(mid) || _.isNil(type)) return send.deny(); + + const record = (await DB.FindOne(refid, { + collection: 'music', + mid, + type, + })) || { + collection: 'music', + mid, + type, + score: 0, + exscore: 0, + clear: 0, + grade: 0, + buttonRate: 0, + longRate: 0, + volRate: 0, + }; + + const score = $(data).number('score', 0); + const exscore = $(data).number('exscore', 0); + if (score > record.score) { + record.score = score; + record.buttonRate = $(data).number('btn_rate', 0); + record.longRate = $(data).number('long_rate', 0); + record.volRate = $(data).number('vol_rate', 0); + } + if (exscore > record.exscore) { + record.exscore = exscore; + } + + record.clear = Math.max($(data).number('clear_type', 0), record.clear); + record.grade = Math.max($(data).number('score_grade', 0), record.grade); + + + + await DB.Upsert( + refid, + { collection: 'music', mid, type }, + record + ); + + return send.success(); +}; + +export const saveCourse: EPR = async (info, data, send) => { + const refid = $(data).str('refid'); + if (!refid) return send.deny(); + + const version = Math.abs(getVersion(info)); + if (version == 0) return send.deny(); + + const sid = $(data).number('ssnid'); + const cid = $(data).number('crsid'); + + if (_.isNil(sid) || _.isNil(cid)) return send.deny(); + + await DB.Upsert( + refid, + { collection: 'course', sid, cid, version }, + { + $max: { + score: $(data).number('sc', 0), + clear: $(data).number('ct', 0), + grade: $(data).number('gr', 0), + rate: $(data).number('ar', 0), + }, + $inc: { + count: 1, + }, + } + ); + + return send.success(); +}; + +export const save: EPR = async (info, data, send) => { + const refid = $(data).str('refid', $(data).attr().refid); + if (!refid) return send.deny(); + + const version = Math.abs(getVersion(info)); + if (version == 0) return send.deny(); + + if (version === 1) { + try { + // Save Profile + await DB.Update( + refid, + { collection: 'profile' }, + { + $set: { + headphone: $(data).number('headphone'), + hiSpeed: $(data).number('hispeed'), + appeal: $(data).number('appeal_id'), + boothFrame: [$(data).number('frame0'), $(data).number('frame1'), $(data).number('frame2'), $(data).number('frame3'), $(data).number('frame4')], + musicID: parseInt($(data).attr("last").music_id), + musicType: parseInt($(data).attr("last").music_type), + sortType: parseInt($(data).attr("last").sort_type), + mUserCnt: $(data).number('m_user_cnt'), + }, + $inc: { + expPoint: $(data).number('gain_exp'), + packets: $(data).number('earned_gamecoin_packet'), + blocks: $(data).number('earned_gamecoin_block'), + }, + } + ); + + return send.success(); + } catch { + return send.deny(); + } + } + + // Save Profile + if (version === 6) { + await DB.Update( + refid, + { collection: 'profile' }, + { + $set: { + appeal: $(data).number('appeal_id'), + + musicID: $(data).number('music_id'), + musicType: $(data).number('music_type'), + sortType: $(data).number('sort_type'), + headphone: $(data).number('headphone'), + blasterCount: $(data).number('blaster_count'), + + hiSpeed: $(data).number('hispeed'), + laneSpeed: $(data).number('lanespeed'), + gaugeOption: $(data).number('gauge_option'), + arsOption: $(data).number('ars_option'), + notesOption: $(data).number('notes_option'), + earlyLateDisp: $(data).number('early_late_disp'), + drawAdjust: $(data).number('draw_adjust'), + effCLeft: $(data).number('eff_c_left'), + effCRight: $(data).number('eff_c_right'), + narrowDown: $(data).number('narrow_down'), + }, + $inc: { + packets: $(data).number('earned_gamecoin_packet'), + blocks: $(data).number('earned_gamecoin_block'), + blasterEnergy: $(data).number('earned_blaster_energy'), + extrackEnergy: $(data).number('earned_extrack_energy'), + playCount: 1, + dayCount: 1, + todayCount: 1, + playChain: 1, + maxPlayChain: 1, + weekCount: 1, + weekPlayCount: 1, + weekChain: 1, + maxWeekChain: 1 + }, + } + ); + } + if (version === 5 || version === 4) { + await DB.Update( + refid, + { collection: 'profile' }, + { + $set: { + appeal: $(data).number('appeal_id'), + + musicID: $(data).number('music_id'), + musicType: $(data).number('music_type'), + sortType: $(data).number('sort_type'), + headphone: $(data).number('headphone'), + blasterCount: $(data).number('blaster_count'), + + hiSpeed: $(data).number('hispeed'), + laneSpeed: $(data).number('lanespeed'), + gaugeOption: $(data).number('gauge_option'), + arsOption: $(data).number('ars_option'), + notesOption: $(data).number('notes_option'), + earlyLateDisp: $(data).number('early_late_disp'), + drawAdjust: $(data).number('draw_adjust'), + effCLeft: $(data).number('eff_c_left'), + effCRight: $(data).number('eff_c_right'), + narrowDown: $(data).number('narrow_down'), + }, + $inc: { + packets: $(data).number('earned_gamecoin_packet'), + blocks: $(data).number('earned_gamecoin_block'), + blasterEnergy: $(data).number('earned_blaster_energy'), + playCount: 1, + dayCount: 1, + todayCount: 1, + playChain: 1, + maxPlayChain: 1, + weekCount: 1, + weekPlayCount: 1, + weekChain: 1, + maxWeekChain: 1 + }, + } + ); + } + + // New course saving function found in sdvx 20220214 + const course = $(data).element('course'); + if(!_.isNil(course)){ + const sid = course.number('ssnid'); + const cid = course.number('crsid'); + + if (!(_.isNil(sid) || _.isNil(cid))){ + await DB.Upsert( + refid, + { collection: 'course', sid, cid, version }, + { + $max: { + score: course.number('sc', 0), + clear: course.number('ct', 0), + grade: course.number('gr', 0), + rate: course.number('ar', 0), + }, + $inc: { + count: 1, + }, + } + ); + } + } + + // Save Items + const items = $(data).elements('item.info'); + + for (const i of items) { + const type = i.number('type'); + const id = i.number('id'); + const param = i.number('param'); + + if (_.isNil(type) || _.isNil(id) || _.isNil(param)) continue; + + await DB.Upsert( + refid, + { collection: 'item', type, id }, + { $set: { param } } + ); + } + + // Save Param + const params = $(data).elements('param.info'); + for (const p of params) { + const type = p.number('type'); + const id = p.number('id'); + const param = p.numbers('param'); + + if (_.isNil(type) || _.isNil(id) || _.isNil(param)) continue; + + await DB.Upsert( + refid, + { collection: 'param', type, id }, + { $set: { param } } + ); + } + + // Save version specific data + await DB.Upsert( + refid, + { + collection: 'skill', + version, + }, + { + $set: { + base: $(data).number('skill_base_id'), + level: $(data).number('skill_level'), + name: $(data).number('skill_name_id'), + }, + } + ); + + // Save Arena Data + const arena_data = $(data).elements('arena'); + for (const are of arena_data) { + const earnedUR = are.number('earned_ultimate_rate'); + const earnedSP = are.number('earned_shop_point'); + const earnedRP = are.number('earned_rank_point'); + const earnedLE = are.number('earned_live_energy'); + const rankPlay = are.str('rank_play') == 'true' ? 1 : 0; + const ultimatePlay = are.str('ultimate_play') == 'true' ? 1 : 0; + await DB.Upsert( + refid, + { + collection: 'arena', + season: Object.keys(ARENA).findIndex(data => data == U.GetConfig('arena_szn')) + 1 + }, + { + $inc: { + ultimateRate: _.isNil(earnedUR) ? 0 : earnedUR, + shopPoint: _.isNil(earnedSP) ? 0 : earnedSP, + rankPoint: _.isNil(earnedRP) ? 0 : earnedRP, + liveEnergy: _.isNil(earnedLE) ? 0 : earnedLE, + rankCount: rankPlay, + ultimateCount: ultimatePlay + } + } + ); + } + + return send.success(); +}; + +export const load: EPR = async (info, data, send) => { + console.log("Loading savedata"); + const refid = $(data).str('refid', $(data).attr().dataid); + if (!refid) return send.deny(); + + const version = Math.abs(getVersion(info)); + console.log("Got version: " + version); + console.log("DataID: " + refid); + if (version == 0) return send.deny(); + + const profile = await DB.FindOne(refid, { + collection: 'profile', + }); + + if (!profile) { + if (version === 1) return send.object(K.ATTR({ none: "1" })); + return send.object({ result: K.ITEM('u8', 1) }); + } + + let skill = (await DB.FindOne(refid, { + collection: 'skill', + version, + })) || { base: 0, name: 0, level: 0 }; + + const items = await DB.Find(refid, { collection: 'item' }); + const courses = await DB.Find(refid, { collection: 'course', version }); + const params = await DB.Find(refid, { collection: 'param' }); + const arena = await DB.FindOne(refid, { collection: 'arena', season: Object.keys(ARENA).findIndex(data => data == U.GetConfig('arena_szn')) + 1 }); + let time = new Date(); + let tempHour = time.getHours(); + let tempDate = time.getDate(); + tempHour += 12; + tempDate += 1; + time.setDate(tempDate); + time.setHours(tempHour); + const currentTime = time.getTime(); + const mixes = version == 5 ? await getAutomationMixes(params) : []; + if (!profile.extrackEnergy) { + profile.extrackEnergy = 0; + } + + if (version === 1) { + return send.pugFile('templates/booth/load.pug', { code: IDToCode(profile.id), ...profile }); + } + + if (version === 2) { + let tempItem = U.GetConfig('unlock_all_appeal_cards') ? unlockAppealCards(items) : items + tempItem = Array.from(tempItem.values()).filter(r => (r.id <= 220)); + return send.pugFile('templates/infiniteinfection/load.pug', { + courses, + tempItem, + params, + skill, + ...profile + }); + } + const bgm = profile.bgm ? profile.bgm : 0; + const subbg = profile.subbg ? profile.subbg : 0; + const nemsys = profile.nemsys ? profile.nemsys : 0; + const stampA = profile.stampA ? profile.stampA : 0; + const stampB = profile.stampB ? profile.stampB : 0; + const stampC = profile.stampC ? profile.stampC : 0; + const stampD = profile.stampD ? profile.stampD : 0; + + + const customize = []; + customize.push(bgm, subbg, nemsys, stampA, stampB, stampC, stampD); + + var tempCustom = params.findIndex((e) => (e.type == 2 && e.id == 2)) + + if (tempCustom == -1) { + const tempParam: Param = { collection: 'param', type: 2, id: 2, param: [] }; + params.push(tempParam); + tempCustom = params.findIndex((e) => (e.type == 2 && e.id == 2)) + } + + if (params[tempCustom]) { + params[tempCustom].param = customize; + } + + + let blasterpass = U.GetConfig('use_blasterpass') ? 1 : 0; + + var tempItem = U.GetConfig('unlock_all_navigators') ? unlockNavigators(items) : items; + tempItem = U.GetConfig('unlock_all_appeal_cards') ? unlockAppealCards(items) : items; + tempItem = removeStampItems(tempItem) + + let eventData = JSON.parse(await IO.ReadFile('webui/asset/json/events.json')) + let eventConfig = JSON.parse(await IO.ReadFile('webui/asset/config/events.json')) + let presents = [] + for(const eventIter in eventData['events']) { + if(!eventData['events'][eventIter]['in_game_event']) { + if(typeof eventConfig[eventData['events'][eventIter]['id']]['toggle'] === "boolean") { + if(eventConfig[eventData['events'][eventIter]['id']]['toggle']) { + for(const itemIter in EVENT_SONGS6[eventData['events'][eventIter]['id']]) { + let itemId = parseInt(EVENT_SONGS6[eventData['events'][eventIter]['id']][itemIter]) + if(await DB.Count(refid, {collection:'item', id: itemId}) === 0) { + await DB.Upsert( + refid, + {collection: 'item', type: 0, id: itemId}, + {$set: { param: 23 }} + ) + + presents.push({ + id: itemId, + type: 0, + param: 23 + }) + + tempItem.push({ collection: 'item', type: 0, id: itemId, param: 23 }) + } + } + } + } else{ + // eventConfig[eventData['events'][eventIter]['id']]['toggle'] + for(const toggleKeys in Object.keys(eventConfig[eventData['events'][eventIter]['id']]['toggle'])) { + if(eventConfig[eventData['events'][eventIter]['id']]['toggle'][Object.keys(eventConfig[eventData['events'][eventIter]['id']]['toggle'])[toggleKeys]]) { + for(const itemIter in EVENT_SONGS6[Object.keys(eventConfig[eventData['events'][eventIter]['id']]['toggle'])[toggleKeys]]) { + let itemId = parseInt(EVENT_SONGS6[Object.keys(eventConfig[eventData['events'][eventIter]['id']]['toggle'])[toggleKeys]][itemIter]) + if(await DB.Count(refid, {collection:'item', id: itemId}) === 0) { + await DB.Upsert( + refid, + {collection: 'item', type: 0, id: itemId}, + {$set: { param: 23 }} + ) + + presents.push({ + id: itemId, + type: 0, + param: 23 + }) + + tempItem.push({ collection: 'item', type: 0, id: itemId, param: 23 }) + } + } + } + } + } + } + } + + // Make generator power always 100%, + for (let i = 0; i < 50; i++) { + const tempGene: Item = { collection: 'item', type: 7, id: i, param: 10 }; + tempItem.push(tempGene); + } + + return send.pugFile('templates/load.pug', { + courses, + items: tempItem, + present: presents, + params, + skill, + currentTime, + mixes, + version, + blasterpass, + automation: version == 5 ? SDVX_AUTOMATION_SONGS : [], + code: IDToCode(profile.id), + arena, + ...profile, + }); +}; + +export const create: EPR = async (info, data, send) => { + console.log("Creating profile"); + const refid = $(data).str('refid', $(data).attr().refid); + if (!refid) return send.deny(); + console.log("DataID" + refid); + const name = $(data).str('name', $(data).attr().name ? $(data).attr().name : 'GUEST'); + let id = _.random(0, 99999999); + while (await DB.FindOne(null, { collecttion: 'profile', id })) { + id = _.random(0, 99999999); + } + + const profile: Profile = { + pluginVer: 1, + + collection: 'profile', + id, + name, + appeal: 0, + akaname: 0, + blocks: 0, + packets: 0, + arsOption: 0, + drawAdjust: 0, + earlyLateDisp: 0, + effCLeft: 0, + effCRight: 1, + gaugeOption: 0, + hiSpeed: 0, + laneSpeed: 0, + narrowDown: 0, + notesOption: 0, + blasterCount: 0, + blasterEnergy: 0, + extrackEnergy: 0, + bgm: 0, + subbg: 0, + nemsys: 0, + stampA: 0, + stampB: 0, + stampC: 0, + stampD: 0, + + headphone: 0, + musicID: 0, + musicType: 0, + sortType: 0, + expPoint: 0, + mUserCnt: 0, + boothFrame: [0, 0, 0, 0, 0], + + playCount: 0 + }; + + await DB.Upsert(refid, { collection: 'profile' }, profile); + return send.object({ result: K.ITEM('u8', 0) }); +}; + +export const buy: EPR = async (info, data, send) => { + console.log("buying") + const refid = $(data).str('refid'); + if (!refid) return send.deny(); + + const growth = { + blocks: $(data).number('earned_gamecoin_block', 0), + packets: $(data).number('earned_gamecoin_packet', 0), + }; + + const currency = $(data).bool('currency_type') ? 'blocks' : 'packets'; + + const cost = _.sum($(data).numbers('item.price', [])); + const balanceChange = growth[currency] - cost; + + const updated = await DB.Update( + refid, + { collection: 'profile', [currency]: { $gte: -balanceChange } }, + { $inc: { [currency]: balanceChange } } + ); + + if (updated.updated) { + const items = _.zipWith( + $(data).numbers('item.item_type', []), + $(data).numbers('item.item_id', []), + $(data).numbers('item.param', []), + (type, id, param) => ({ type, id, param }) + ); + + for (const item of items) { + await DB.Upsert( + refid, + { collection: 'item', type: item.type, id: item.id }, + { $set: { param: item.param } } + ); + } + + return send.object({ + gamecoin_packet: K.ITEM('u32', updated.docs[0].packets), + gamecoin_block: K.ITEM('u32', updated.docs[0].blocks), + }); + } else { + return send.success(); + } +}; + +export const print: EPR = async (info, data, send) => { + const genesisCards = $(data).elements('genesis_card'); + var genesisCardsArray = []; + var generatorArray = []; + for (const g of genesisCards) { + let tempGeneratorID = g.number('generator_id'); + let exist = generatorArray.findIndex((e) => (e == tempGeneratorID)); + if (exist == -1) { + generatorArray.push(tempGeneratorID); + } + } + send.object({ + result: K.ITEM('s8', 0), + genesis_cards: genesisCards.map(r => ({ + index: K.ITEM('s32', r.number('index')), + print_id: K.ITEM('s32', r.number('print_id')) + })), + after_power: generatorArray.map(r => ({ + generator_id: K.ITEM('s32', r), + param: K.ITEM('s32', 10), + })) + }), { status: "0" }; +} + +export const saveValgene: EPR = async (info, data, send) => { + console.log("Saving Valkyrie Generator Item") + const refid = $(data).str('refid'); + const items = $(data).elements('item.info'); + let itemsToAdd = [] + for (const i of items) { + const type = i.number('type'); + const id = i.number('id'); + const param = i.number('param'); + if(type === 17) { + for (let stampId = ((id * 4) - 3); stampId <= (id * 4); stampId++) { + itemsToAdd.push({'type': type, 'id': stampId, 'param': param}) + } + } else { + itemsToAdd.push({'type': type, 'id': id, 'param': param}) + } + } + + for(let itemToAdd in itemsToAdd) { + let id = itemsToAdd[itemToAdd].id + let type = itemsToAdd[itemToAdd].type + let param = itemsToAdd[itemToAdd].param + console.log("Saving (" + type + " | " + id + " | " + param + ")") + if (_.isNil(type) || _.isNil(id) || _.isNil(param)) continue; + + await DB.Upsert( + refid, + { collection: 'item', type, id }, + { $set: { param } } + ); + } + + return send.object({ result: K.ITEM('u8', 0) }); +} + +export const saveE: EPR = async (info, data, send) => { + console.log("save_e") + + return send.object({ result: K.ITEM('u8', 0) }); +} diff --git a/sdvx@asphyxia/index.ts b/sdvx@asphyxia/index.ts index 5cb6069..740ad0d 100644 --- a/sdvx@asphyxia/index.ts +++ b/sdvx@asphyxia/index.ts @@ -1,133 +1,134 @@ -import {common,log,unhandledt} from './handlers/common'; -import {hiscore, rival, saveMix, loadMix, globalMatch} from './handlers/features'; -import { - updateProfile, - updateMix, - importMix, - deleteMix, - copyResourcesFromGame, - preGeneRoll, - manageEvents -} from './handlers/webui'; -import { - load, - create, - loadScore, - save, - saveScore, - saveCourse, - buy, - print, - saveValgene, -} from './handlers/profiles'; -import { - ARENA -} from './data/exg'; - -export function register() { - - R.Contributor("LatoWolf#1170"); - R.Contributor("ovv (this fork)"); - R.GameCode('KFC'); - - R.Config('sdvx_eg_root_dir', { type: 'string', needRestart: true, default: '', name: 'Exceed Gear Data Directory', desc: 'The root directory of your SDVX Exceed Gear game files (for asset copying)'}); - R.Config('unlock_all_valk_items', { type: 'boolean', default: false, name:'Unlock All Valkyrie and Premium Items', desc: 'Unlock Nemsys, BGM, Submonitor BG and Stamp Items (Valk crews not included; check \'unlock all navigators\' option)'}); - R.Config('enable_valk_songs' ,{ type: 'boolean', default: false, name:'Enable Valkyrie Model Songs', desc:'Unlock the valkyrie model songs on non-valkyrie mode.'}); - R.Config('arena_szn',{ type: 'string', options: Object.keys(ARENA), default: 'Set 1 (04/25/22)', name: 'Arena Station Item Set', desc: 'Choose which season set of items in the arena station you want to show up in arena station'}); - R.Config('x_record', {type: 'boolean', default: false, name: 'X-Record', desc: 'Activates X-record. 10 VM and 1 LM points per play.'}) - R.Config('unlock_all_songs', { type: 'boolean', default: false, name:'Unlock All Songs'}); - R.Config('unlock_all_navigators', { type: 'boolean', default: false, name:'Unlock All Navigators'} ); - R.Config('unlock_all_appeal_cards', { type: 'boolean', default: false, name:'Unlock All Appeal Cards'}); - R.Config('use_blasterpass',{ type: 'boolean', default: true, name:'Use Blaster Pass', desc:'Enable Blaster Pass for VW and EG'}); - R.Config('new_year_special',{ type: 'boolean', default: false, name:'Use New Year Special', desc:'Enable New Year Special BGM for login (doesn\'t work right now)'}); - R.Config('april_fools',{ type: 'boolean', default: false, name:'April Fools', desc:'Enable April Fools Event (doesn\'t work properly right now)'}); - R.Config('use_information' ,{ type: 'boolean', default: true, name:'Use Information', desc:'Enable the information section after entry.'}); - R.Config('use_asphyxia_gameover',{ type: 'boolean', default: true, name:'Use Asphyxia Gameover', desc:'Enable the Asphyxia gameover message after ending the game.'}) - - R.WebUIEvent('copyResourcesFromGame', copyResourcesFromGame); - R.WebUIEvent('preGeneRoll', preGeneRoll); - R.WebUIEvent('manageEvents', manageEvents); - R.WebUIEvent('updateProfile', updateProfile); - R.WebUIEvent('updateMix', updateMix); - R.WebUIEvent('importMix', importMix); - R.WebUIEvent('deleteMix', deleteMix); - - const MultiRoute = (method: string, handler: EPR | boolean) => { - // Helper for register multiple versions. - R.Route(`game.${method}`, handler); - R.Route(`game_2.${method}`, handler); - //R.Route(`game_3.${method}`, handler); - R.Route(`game.sv4_${method}`, handler); - R.Route(`game.sv5_${method}`, handler); - R.Route(`game.sv6_${method}`, handler); - }; - - // Common - MultiRoute('common', common); - - // Profile - MultiRoute('new', create); - MultiRoute('load', load); - MultiRoute('load_m', loadScore); - MultiRoute('save', save); - MultiRoute('save_m', saveScore); - MultiRoute('save_c', saveCourse); - MultiRoute('save_valgene', saveValgene); - MultiRoute('frozen', true); - MultiRoute('buy', buy); - MultiRoute('print',print); - - // Features - MultiRoute('hiscore', hiscore); - MultiRoute('load_r', rival); - MultiRoute('save_ap', saveMix); - MultiRoute('load_ap', loadMix); - - // Lazy - MultiRoute('lounge', (_, __, send) => send.object({ - interval: K.ITEM('u32', 30) - })); - MultiRoute('shop', (_, __, send) => send.object({ - nxt_time: K.ITEM('u32', 1000 * 5 * 60) - })); - MultiRoute('save_e', true); - MultiRoute('save_mega',true); - MultiRoute('play_e', true); - MultiRoute('play_s', true); - MultiRoute('entry_s', globalMatch); - MultiRoute('entry_e', true); - MultiRoute('exception', true); - MultiRoute('log',log); - - /* - print_h - sample - save_campaign - save_fi - save_pb - save_valgene - DONE - serial - */ - - R.Route('eventlog.write', (_, __, send) => send.object({ - gamesession: K.ITEM('s64', BigInt(1)), - logsendflg: K.ITEM('s32', 0), - logerrlevel: K.ITEM('s32', 0), - evtidnosendflg: K.ITEM('s32', 0) - })); - - R.Route('package.list',(_,__,send)=>send.object({ - package:K.ATTR({expire:"1200"},{status:"1"}) - })); - - R.Route('ins.netlog', (_, __, send) => send.object({ - //gamesession: K.ITEM('s64', BigInt(1)), - //logsendflg: K.ITEM('s32', 0), - //logerrlevel: K.ITEM('s32', 0), - //evtidnosendflg: K.ITEM('s32', 0) - })); - - - // R.Unhandled(); - R.Unhandled(unhandledt); -} +import {common,log,unhandledt} from './handlers/common'; +import {hiscore, rival, saveMix, loadMix, globalMatch} from './handlers/features'; +import { + updateProfile, + updateMix, + importMix, + deleteMix, + copyResourcesFromGame, + preGeneRoll, + manageEvents +} from './handlers/webui'; +import { + load, + create, + loadScore, + save, + saveScore, + saveCourse, + buy, + print, + saveValgene, + saveE +} from './handlers/profiles'; +import { + ARENA +} from './data/exg'; + +export function register() { + + R.Contributor("LatoWolf#1170"); + R.Contributor("ovv (this fork)"); + R.GameCode('KFC'); + + R.Config('sdvx_eg_root_dir', { type: 'string', needRestart: true, default: '', name: 'Exceed Gear Data Directory', desc: 'The root directory of your SDVX Exceed Gear game files (for asset copying)'}); + R.Config('unlock_all_valk_items', { type: 'boolean', default: false, name:'Unlock All Valkyrie and Premium Items', desc: 'Unlock Nemsys, BGM, Submonitor BG and Stamp Items (Valk crews not included; check \'unlock all navigators\' option)'}); + R.Config('enable_valk_songs' ,{ type: 'boolean', default: false, name:'Enable Valkyrie Model Songs', desc:'Unlock the valkyrie model songs on non-valkyrie mode.'}); + R.Config('arena_szn',{ type: 'string', options: Object.keys(ARENA), default: 'Set 1 (04/25/22)', name: 'Arena Station Item Set', desc: 'Choose which season set of items in the arena station you want to show up in arena station'}); + R.Config('x_record', {type: 'boolean', default: false, name: 'X-Record', desc: 'Activates X-record. 10 VM and 1 LM points per play.'}) + R.Config('unlock_all_songs', { type: 'boolean', default: false, name:'Unlock All Songs'}); + R.Config('unlock_all_navigators', { type: 'boolean', default: false, name:'Unlock All Navigators'} ); + R.Config('unlock_all_appeal_cards', { type: 'boolean', default: false, name:'Unlock All Appeal Cards'}); + R.Config('use_blasterpass',{ type: 'boolean', default: true, name:'Use Blaster Pass', desc:'Enable Blaster Pass for VW and EG'}); + R.Config('new_year_special',{ type: 'boolean', default: false, name:'Use New Year Special', desc:'Enable New Year Special BGM for login (doesn\'t work right now)'}); + R.Config('april_fools',{ type: 'boolean', default: false, name:'April Fools', desc:'Enable April Fools Event (doesn\'t work properly right now)'}); + R.Config('use_information' ,{ type: 'boolean', default: true, name:'Use Information', desc:'Enable the information section after entry.'}); + R.Config('use_asphyxia_gameover',{ type: 'boolean', default: true, name:'Use Asphyxia Gameover', desc:'Enable the Asphyxia gameover message after ending the game.'}) + + R.WebUIEvent('copyResourcesFromGame', copyResourcesFromGame); + R.WebUIEvent('preGeneRoll', preGeneRoll); + R.WebUIEvent('manageEvents', manageEvents); + R.WebUIEvent('updateProfile', updateProfile); + R.WebUIEvent('updateMix', updateMix); + R.WebUIEvent('importMix', importMix); + R.WebUIEvent('deleteMix', deleteMix); + + const MultiRoute = (method: string, handler: EPR | boolean) => { + // Helper for register multiple versions. + R.Route(`game.${method}`, handler); + R.Route(`game_2.${method}`, handler); + //R.Route(`game_3.${method}`, handler); + R.Route(`game.sv4_${method}`, handler); + R.Route(`game.sv5_${method}`, handler); + R.Route(`game.sv6_${method}`, handler); + }; + + // Common + MultiRoute('common', common); + + // Profile + MultiRoute('new', create); + MultiRoute('load', load); + MultiRoute('load_m', loadScore); + MultiRoute('save', save); + MultiRoute('save_m', saveScore); + MultiRoute('save_c', saveCourse); + MultiRoute('save_valgene', saveValgene); + MultiRoute('frozen', true); + MultiRoute('buy', buy); + MultiRoute('print',print); + + // Features + MultiRoute('hiscore', hiscore); + MultiRoute('load_r', rival); + MultiRoute('save_ap', saveMix); + MultiRoute('load_ap', loadMix); + + // Lazy + MultiRoute('lounge', (_, __, send) => send.object({ + interval: K.ITEM('u32', 30) + })); + MultiRoute('shop', (_, __, send) => send.object({ + nxt_time: K.ITEM('u32', 1000 * 5 * 60) + })); + MultiRoute('save_e', saveE); + MultiRoute('save_mega',true); + MultiRoute('play_e', true); + MultiRoute('play_s', true); + MultiRoute('entry_s', globalMatch); + MultiRoute('entry_e', true); + MultiRoute('exception', true); + MultiRoute('log',log); + + /* + print_h + sample + save_campaign + save_fi + save_pb + save_valgene - DONE + serial + */ + + R.Route('eventlog.write', (_, __, send) => send.object({ + gamesession: K.ITEM('s64', BigInt(1)), + logsendflg: K.ITEM('s32', 0), + logerrlevel: K.ITEM('s32', 0), + evtidnosendflg: K.ITEM('s32', 0) + })); + + R.Route('package.list',(_,__,send)=>send.object({ + package:K.ATTR({expire:"1200"},{status:"1"}) + })); + + R.Route('ins.netlog', (_, __, send) => send.object({ + //gamesession: K.ITEM('s64', BigInt(1)), + //logsendflg: K.ITEM('s32', 0), + //logerrlevel: K.ITEM('s32', 0), + //evtidnosendflg: K.ITEM('s32', 0) + })); + + + // R.Unhandled(); + R.Unhandled(unhandledt); +}