mirror of
https://github.com/asphyxia-core/plugins.git
synced 2026-03-21 17:34:46 -05:00
Merge branch 'stable' of github.com:dannylin0711/plugins into stable
This commit is contained in:
commit
3dcc69bbba
21
_shared/lib/adm-zip/LICENSE
Normal file
21
_shared/lib/adm-zip/LICENSE
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2012 Another-D-Mention Software and other contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
65
_shared/lib/adm-zip/README.md
Normal file
65
_shared/lib/adm-zip/README.md
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
# ADM-ZIP for NodeJS with added support for electron original-fs
|
||||
|
||||
ADM-ZIP is a pure JavaScript implementation for zip data compression for [NodeJS](https://nodejs.org/).
|
||||
|
||||
# Installation
|
||||
|
||||
With [npm](https://www.npmjs.com/) do:
|
||||
|
||||
$ npm install adm-zip
|
||||
|
||||
## What is it good for?
|
||||
|
||||
The library allows you to:
|
||||
|
||||
- decompress zip files directly to disk or in memory buffers
|
||||
- compress files and store them to disk in .zip format or in compressed buffers
|
||||
- update content of/add new/delete files from an existing .zip
|
||||
|
||||
# Dependencies
|
||||
|
||||
There are no other nodeJS libraries that ADM-ZIP is dependent of
|
||||
|
||||
# Examples
|
||||
|
||||
## Basic usage
|
||||
|
||||
```javascript
|
||||
var AdmZip = require("adm-zip");
|
||||
|
||||
// reading archives
|
||||
var zip = new AdmZip("./my_file.zip");
|
||||
var zipEntries = zip.getEntries(); // an array of ZipEntry records
|
||||
|
||||
zipEntries.forEach(function (zipEntry) {
|
||||
console.log(zipEntry.toString()); // outputs zip entries information
|
||||
if (zipEntry.entryName == "my_file.txt") {
|
||||
console.log(zipEntry.getData().toString("utf8"));
|
||||
}
|
||||
});
|
||||
// outputs the content of some_folder/my_file.txt
|
||||
console.log(zip.readAsText("some_folder/my_file.txt"));
|
||||
// extracts the specified file to the specified location
|
||||
zip.extractEntryTo(/*entry name*/ "some_folder/my_file.txt", /*target path*/ "/home/me/tempfolder", /*maintainEntryPath*/ false, /*overwrite*/ true);
|
||||
// extracts everything
|
||||
zip.extractAllTo(/*target path*/ "/home/me/zipcontent/", /*overwrite*/ true);
|
||||
|
||||
// creating archives
|
||||
var zip = new AdmZip();
|
||||
|
||||
// add file directly
|
||||
var content = "inner content of the file";
|
||||
zip.addFile("test.txt", Buffer.from(content, "utf8"), "entry comment goes here");
|
||||
// add local file
|
||||
zip.addLocalFile("/home/me/some_picture.png");
|
||||
// get everything as a buffer
|
||||
var willSendthis = zip.toBuffer();
|
||||
// or write everything to disk
|
||||
zip.writeZip(/*target file name*/ "/home/me/files.zip");
|
||||
|
||||
// ... more examples in the wiki
|
||||
```
|
||||
|
||||
For more detailed information please check out the [wiki](https://github.com/cthackers/adm-zip/wiki).
|
||||
|
||||
[](https://travis-ci.org/cthackers/adm-zip)
|
||||
786
_shared/lib/adm-zip/adm-zip.js
Normal file
786
_shared/lib/adm-zip/adm-zip.js
Normal file
|
|
@ -0,0 +1,786 @@
|
|||
const Utils = require("./util");
|
||||
const pth = require("path");
|
||||
const ZipEntry = require("./zipEntry");
|
||||
const ZipFile = require("./zipFile");
|
||||
|
||||
const get_Bool = (val, def) => (typeof val === "boolean" ? val : def);
|
||||
const get_Str = (val, def) => (typeof val === "string" ? val : def);
|
||||
|
||||
const defaultOptions = {
|
||||
// option "noSort" : if true it disables files sorting
|
||||
noSort: false,
|
||||
// read entries during load (initial loading may be slower)
|
||||
readEntries: false,
|
||||
// default method is none
|
||||
method: Utils.Constants.NONE,
|
||||
// file system
|
||||
fs: null
|
||||
};
|
||||
|
||||
module.exports = function (/**String*/ input, /** object */ options) {
|
||||
let inBuffer = null;
|
||||
|
||||
// create object based default options, allowing them to be overwritten
|
||||
const opts = Object.assign(Object.create(null), defaultOptions);
|
||||
|
||||
// test input variable
|
||||
if (input && "object" === typeof input) {
|
||||
// if value is not buffer we accept it to be object with options
|
||||
if (!(input instanceof Uint8Array)) {
|
||||
Object.assign(opts, input);
|
||||
input = opts.input ? opts.input : undefined;
|
||||
if (opts.input) delete opts.input;
|
||||
}
|
||||
|
||||
// if input is buffer
|
||||
if (Buffer.isBuffer(input)) {
|
||||
inBuffer = input;
|
||||
opts.method = Utils.Constants.BUFFER;
|
||||
input = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
// assign options
|
||||
Object.assign(opts, options);
|
||||
|
||||
// instanciate utils filesystem
|
||||
const filetools = new Utils(opts);
|
||||
|
||||
// if input is file name we retrieve its content
|
||||
if (input && "string" === typeof input) {
|
||||
// load zip file
|
||||
if (filetools.fs.existsSync(input)) {
|
||||
opts.method = Utils.Constants.FILE;
|
||||
opts.filename = input;
|
||||
inBuffer = filetools.fs.readFileSync(input);
|
||||
} else {
|
||||
throw new Error(Utils.Errors.INVALID_FILENAME);
|
||||
}
|
||||
}
|
||||
|
||||
// create variable
|
||||
const _zip = new ZipFile(inBuffer, opts);
|
||||
|
||||
const { canonical, sanitize } = Utils;
|
||||
|
||||
function getEntry(/**Object*/ entry) {
|
||||
if (entry && _zip) {
|
||||
var item;
|
||||
// If entry was given as a file name
|
||||
if (typeof entry === "string") item = _zip.getEntry(entry);
|
||||
// if entry was given as a ZipEntry object
|
||||
if (typeof entry === "object" && typeof entry.entryName !== "undefined" && typeof entry.header !== "undefined") item = _zip.getEntry(entry.entryName);
|
||||
|
||||
if (item) {
|
||||
return item;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function fixPath(zipPath) {
|
||||
const { join, normalize, sep } = pth.posix;
|
||||
// convert windows file separators and normalize
|
||||
return join(".", normalize(sep + zipPath.split("\\").join(sep) + sep));
|
||||
}
|
||||
|
||||
return {
|
||||
/**
|
||||
* Extracts the given entry from the archive and returns the content as a Buffer object
|
||||
* @param entry ZipEntry object or String with the full path of the entry
|
||||
*
|
||||
* @return Buffer or Null in case of error
|
||||
*/
|
||||
readFile: function (/**Object*/ entry, /*String, Buffer*/ pass) {
|
||||
var item = getEntry(entry);
|
||||
return (item && item.getData(pass)) || null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Asynchronous readFile
|
||||
* @param entry ZipEntry object or String with the full path of the entry
|
||||
* @param callback
|
||||
*
|
||||
* @return Buffer or Null in case of error
|
||||
*/
|
||||
readFileAsync: function (/**Object*/ entry, /**Function*/ callback) {
|
||||
var item = getEntry(entry);
|
||||
if (item) {
|
||||
item.getDataAsync(callback);
|
||||
} else {
|
||||
callback(null, "getEntry failed for:" + entry);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Extracts the given entry from the archive and returns the content as plain text in the given encoding
|
||||
* @param entry ZipEntry object or String with the full path of the entry
|
||||
* @param encoding Optional. If no encoding is specified utf8 is used
|
||||
*
|
||||
* @return String
|
||||
*/
|
||||
readAsText: function (/**Object*/ entry, /**String=*/ encoding) {
|
||||
var item = getEntry(entry);
|
||||
if (item) {
|
||||
var data = item.getData();
|
||||
if (data && data.length) {
|
||||
return data.toString(encoding || "utf8");
|
||||
}
|
||||
}
|
||||
return "";
|
||||
},
|
||||
|
||||
/**
|
||||
* Asynchronous readAsText
|
||||
* @param entry ZipEntry object or String with the full path of the entry
|
||||
* @param callback
|
||||
* @param encoding Optional. If no encoding is specified utf8 is used
|
||||
*
|
||||
* @return String
|
||||
*/
|
||||
readAsTextAsync: function (/**Object*/ entry, /**Function*/ callback, /**String=*/ encoding) {
|
||||
var item = getEntry(entry);
|
||||
if (item) {
|
||||
item.getDataAsync(function (data, err) {
|
||||
if (err) {
|
||||
callback(data, err);
|
||||
return;
|
||||
}
|
||||
|
||||
if (data && data.length) {
|
||||
callback(data.toString(encoding || "utf8"));
|
||||
} else {
|
||||
callback("");
|
||||
}
|
||||
});
|
||||
} else {
|
||||
callback("");
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Remove the entry from the file or the entry and all it's nested directories and files if the given entry is a directory
|
||||
*
|
||||
* @param entry
|
||||
*/
|
||||
deleteFile: function (/**Object*/ entry) {
|
||||
// @TODO: test deleteFile
|
||||
var item = getEntry(entry);
|
||||
if (item) {
|
||||
_zip.deleteEntry(item.entryName);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Adds a comment to the zip. The zip must be rewritten after adding the comment.
|
||||
*
|
||||
* @param comment
|
||||
*/
|
||||
addZipComment: function (/**String*/ comment) {
|
||||
// @TODO: test addZipComment
|
||||
_zip.comment = comment;
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the zip comment
|
||||
*
|
||||
* @return String
|
||||
*/
|
||||
getZipComment: function () {
|
||||
return _zip.comment || "";
|
||||
},
|
||||
|
||||
/**
|
||||
* Adds a comment to a specified zipEntry. The zip must be rewritten after adding the comment
|
||||
* The comment cannot exceed 65535 characters in length
|
||||
*
|
||||
* @param entry
|
||||
* @param comment
|
||||
*/
|
||||
addZipEntryComment: function (/**Object*/ entry, /**String*/ comment) {
|
||||
var item = getEntry(entry);
|
||||
if (item) {
|
||||
item.comment = comment;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the comment of the specified entry
|
||||
*
|
||||
* @param entry
|
||||
* @return String
|
||||
*/
|
||||
getZipEntryComment: function (/**Object*/ entry) {
|
||||
var item = getEntry(entry);
|
||||
if (item) {
|
||||
return item.comment || "";
|
||||
}
|
||||
return "";
|
||||
},
|
||||
|
||||
/**
|
||||
* Updates the content of an existing entry inside the archive. The zip must be rewritten after updating the content
|
||||
*
|
||||
* @param entry
|
||||
* @param content
|
||||
*/
|
||||
updateFile: function (/**Object*/ entry, /**Buffer*/ content) {
|
||||
var item = getEntry(entry);
|
||||
if (item) {
|
||||
item.setData(content);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Adds a file from the disk to the archive
|
||||
*
|
||||
* @param localPath File to add to zip
|
||||
* @param zipPath Optional path inside the zip
|
||||
* @param zipName Optional name for the file
|
||||
*/
|
||||
addLocalFile: function (/**String*/ localPath, /**String=*/ zipPath, /**String=*/ zipName, /**String*/ comment) {
|
||||
if (filetools.fs.existsSync(localPath)) {
|
||||
// fix ZipPath
|
||||
zipPath = zipPath ? fixPath(zipPath) : "";
|
||||
|
||||
// p - local file name
|
||||
var p = localPath.split("\\").join("/").split("/").pop();
|
||||
|
||||
// add file name into zippath
|
||||
zipPath += zipName ? zipName : p;
|
||||
|
||||
// read file attributes
|
||||
const _attr = filetools.fs.statSync(localPath);
|
||||
|
||||
// add file into zip file
|
||||
this.addFile(zipPath, filetools.fs.readFileSync(localPath), comment, _attr);
|
||||
} else {
|
||||
throw new Error(Utils.Errors.FILE_NOT_FOUND.replace("%s", localPath));
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Adds a local directory and all its nested files and directories to the archive
|
||||
*
|
||||
* @param localPath
|
||||
* @param zipPath optional path inside zip
|
||||
* @param filter optional RegExp or Function if files match will
|
||||
* be included.
|
||||
* @param {number | object} attr - number as unix file permissions, object as filesystem Stats object
|
||||
*/
|
||||
addLocalFolder: function (/**String*/ localPath, /**String=*/ zipPath, /**=RegExp|Function*/ filter, /**=number|object*/ attr) {
|
||||
// Prepare filter
|
||||
if (filter instanceof RegExp) {
|
||||
// if filter is RegExp wrap it
|
||||
filter = (function (rx) {
|
||||
return function (filename) {
|
||||
return rx.test(filename);
|
||||
};
|
||||
})(filter);
|
||||
} else if ("function" !== typeof filter) {
|
||||
// if filter is not function we will replace it
|
||||
filter = function () {
|
||||
return true;
|
||||
};
|
||||
}
|
||||
|
||||
// fix ZipPath
|
||||
zipPath = zipPath ? fixPath(zipPath) : "";
|
||||
|
||||
// normalize the path first
|
||||
localPath = pth.normalize(localPath);
|
||||
|
||||
if (filetools.fs.existsSync(localPath)) {
|
||||
const items = filetools.findFiles(localPath);
|
||||
const self = this;
|
||||
|
||||
if (items.length) {
|
||||
items.forEach(function (filepath) {
|
||||
var p = pth.relative(localPath, filepath).split("\\").join("/"); //windows fix
|
||||
if (filter(p)) {
|
||||
var stats = filetools.fs.statSync(filepath);
|
||||
if (stats.isFile()) {
|
||||
self.addFile(zipPath + p, filetools.fs.readFileSync(filepath), "", attr ? attr : stats);
|
||||
} else {
|
||||
self.addFile(zipPath + p + "/", Buffer.alloc(0), "", attr ? attr : stats);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
} else {
|
||||
throw new Error(Utils.Errors.FILE_NOT_FOUND.replace("%s", localPath));
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Asynchronous addLocalFile
|
||||
* @param localPath
|
||||
* @param callback
|
||||
* @param zipPath optional path inside zip
|
||||
* @param filter optional RegExp or Function if files match will
|
||||
* be included.
|
||||
*/
|
||||
addLocalFolderAsync: function (/*String*/ localPath, /*Function*/ callback, /*String*/ zipPath, /*RegExp|Function*/ filter) {
|
||||
if (filter instanceof RegExp) {
|
||||
filter = (function (rx) {
|
||||
return function (filename) {
|
||||
return rx.test(filename);
|
||||
};
|
||||
})(filter);
|
||||
} else if ("function" !== typeof filter) {
|
||||
filter = function () {
|
||||
return true;
|
||||
};
|
||||
}
|
||||
|
||||
// fix ZipPath
|
||||
zipPath = zipPath ? fixPath(zipPath) : "";
|
||||
|
||||
// normalize the path first
|
||||
localPath = pth.normalize(localPath);
|
||||
|
||||
var self = this;
|
||||
filetools.fs.open(localPath, "r", function (err) {
|
||||
if (err && err.code === "ENOENT") {
|
||||
callback(undefined, Utils.Errors.FILE_NOT_FOUND.replace("%s", localPath));
|
||||
} else if (err) {
|
||||
callback(undefined, err);
|
||||
} else {
|
||||
var items = filetools.findFiles(localPath);
|
||||
var i = -1;
|
||||
|
||||
var next = function () {
|
||||
i += 1;
|
||||
if (i < items.length) {
|
||||
var filepath = items[i];
|
||||
var p = pth.relative(localPath, filepath).split("\\").join("/"); //windows fix
|
||||
p = p
|
||||
.normalize("NFD")
|
||||
.replace(/[\u0300-\u036f]/g, "")
|
||||
.replace(/[^\x20-\x7E]/g, ""); // accent fix
|
||||
if (filter(p)) {
|
||||
filetools.fs.stat(filepath, function (er0, stats) {
|
||||
if (er0) callback(undefined, er0);
|
||||
if (stats.isFile()) {
|
||||
filetools.fs.readFile(filepath, function (er1, data) {
|
||||
if (er1) {
|
||||
callback(undefined, er1);
|
||||
} else {
|
||||
self.addFile(zipPath + p, data, "", stats);
|
||||
next();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
self.addFile(zipPath + p + "/", Buffer.alloc(0), "", stats);
|
||||
next();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
process.nextTick(() => {
|
||||
next();
|
||||
});
|
||||
}
|
||||
} else {
|
||||
callback(true, undefined);
|
||||
}
|
||||
};
|
||||
|
||||
next();
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {string} localPath - path where files will be extracted
|
||||
* @param {object} props - optional properties
|
||||
* @param {string} props.zipPath - optional path inside zip
|
||||
* @param {regexp, function} props.filter - RegExp or Function if files match will be included.
|
||||
*/
|
||||
addLocalFolderPromise: function (/*String*/ localPath, /* object */ props) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const { filter, zipPath } = Object.assign({}, props);
|
||||
this.addLocalFolderAsync(
|
||||
localPath,
|
||||
(done, err) => {
|
||||
if (err) reject(err);
|
||||
if (done) resolve(this);
|
||||
},
|
||||
zipPath,
|
||||
filter
|
||||
);
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Allows you to create a entry (file or directory) in the zip file.
|
||||
* If you want to create a directory the entryName must end in / and a null buffer should be provided.
|
||||
* Comment and attributes are optional
|
||||
*
|
||||
* @param {string} entryName
|
||||
* @param {Buffer | string} content - file content as buffer or utf8 coded string
|
||||
* @param {string} comment - file comment
|
||||
* @param {number | object} attr - number as unix file permissions, object as filesystem Stats object
|
||||
*/
|
||||
addFile: function (/**String*/ entryName, /**Buffer*/ content, /**String*/ comment, /**Number*/ attr) {
|
||||
let entry = getEntry(entryName);
|
||||
const update = entry != null;
|
||||
|
||||
// prepare new entry
|
||||
if (!update) {
|
||||
entry = new ZipEntry();
|
||||
entry.entryName = entryName;
|
||||
}
|
||||
entry.comment = comment || "";
|
||||
|
||||
const isStat = "object" === typeof attr && attr instanceof filetools.fs.Stats;
|
||||
|
||||
// last modification time from file stats
|
||||
if (isStat) {
|
||||
entry.header.time = attr.mtime;
|
||||
}
|
||||
|
||||
// Set file attribute
|
||||
var fileattr = entry.isDirectory ? 0x10 : 0; // (MS-DOS directory flag)
|
||||
|
||||
// extended attributes field for Unix
|
||||
// set file type either S_IFDIR / S_IFREG
|
||||
let unix = entry.isDirectory ? 0x4000 : 0x8000;
|
||||
|
||||
if (isStat) {
|
||||
// File attributes from file stats
|
||||
unix |= 0xfff & attr.mode;
|
||||
} else if ("number" === typeof attr) {
|
||||
// attr from given attr values
|
||||
unix |= 0xfff & attr;
|
||||
} else {
|
||||
// Default values:
|
||||
unix |= entry.isDirectory ? 0o755 : 0o644; // permissions (drwxr-xr-x) or (-r-wr--r--)
|
||||
}
|
||||
|
||||
fileattr = (fileattr | (unix << 16)) >>> 0; // add attributes
|
||||
|
||||
entry.attr = fileattr;
|
||||
|
||||
entry.setData(content);
|
||||
if (!update) _zip.setEntry(entry);
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns an array of ZipEntry objects representing the files and folders inside the archive
|
||||
*
|
||||
* @return Array
|
||||
*/
|
||||
getEntries: function () {
|
||||
return _zip ? _zip.entries : [];
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns a ZipEntry object representing the file or folder specified by ``name``.
|
||||
*
|
||||
* @param name
|
||||
* @return ZipEntry
|
||||
*/
|
||||
getEntry: function (/**String*/ name) {
|
||||
return getEntry(name);
|
||||
},
|
||||
|
||||
getEntryCount: function () {
|
||||
return _zip.getEntryCount();
|
||||
},
|
||||
|
||||
forEach: function (callback) {
|
||||
return _zip.forEach(callback);
|
||||
},
|
||||
|
||||
/**
|
||||
* Extracts the given entry to the given targetPath
|
||||
* If the entry is a directory inside the archive, the entire directory and it's subdirectories will be extracted
|
||||
*
|
||||
* @param entry ZipEntry object or String with the full path of the entry
|
||||
* @param targetPath Target folder where to write the file
|
||||
* @param maintainEntryPath If maintainEntryPath is true and the entry is inside a folder, the entry folder
|
||||
* will be created in targetPath as well. Default is TRUE
|
||||
* @param overwrite If the file already exists at the target path, the file will be overwriten if this is true.
|
||||
* Default is FALSE
|
||||
* @param keepOriginalPermission The file will be set as the permission from the entry if this is true.
|
||||
* Default is FALSE
|
||||
* @param outFileName String If set will override the filename of the extracted file (Only works if the entry is a file)
|
||||
*
|
||||
* @return Boolean
|
||||
*/
|
||||
extractEntryTo: function (
|
||||
/**Object*/ entry,
|
||||
/**String*/ targetPath,
|
||||
/**Boolean*/ maintainEntryPath,
|
||||
/**Boolean*/ overwrite,
|
||||
/**Boolean*/ keepOriginalPermission,
|
||||
/**String**/ outFileName
|
||||
) {
|
||||
overwrite = get_Bool(overwrite, false);
|
||||
keepOriginalPermission = get_Bool(keepOriginalPermission, false);
|
||||
maintainEntryPath = get_Bool(maintainEntryPath, true);
|
||||
outFileName = get_Str(outFileName, get_Str(keepOriginalPermission, undefined));
|
||||
|
||||
var item = getEntry(entry);
|
||||
if (!item) {
|
||||
throw new Error(Utils.Errors.NO_ENTRY);
|
||||
}
|
||||
|
||||
var entryName = canonical(item.entryName);
|
||||
|
||||
var target = sanitize(targetPath, outFileName && !item.isDirectory ? outFileName : maintainEntryPath ? entryName : pth.basename(entryName));
|
||||
|
||||
if (item.isDirectory) {
|
||||
var children = _zip.getEntryChildren(item);
|
||||
children.forEach(function (child) {
|
||||
if (child.isDirectory) return;
|
||||
var content = child.getData();
|
||||
if (!content) {
|
||||
throw new Error(Utils.Errors.CANT_EXTRACT_FILE);
|
||||
}
|
||||
var name = canonical(child.entryName);
|
||||
var childName = sanitize(targetPath, maintainEntryPath ? name : pth.basename(name));
|
||||
// The reverse operation for attr depend on method addFile()
|
||||
const fileAttr = keepOriginalPermission ? child.header.fileAttr : undefined;
|
||||
filetools.writeFileTo(childName, content, overwrite, fileAttr);
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
var content = item.getData();
|
||||
if (!content) throw new Error(Utils.Errors.CANT_EXTRACT_FILE);
|
||||
|
||||
if (filetools.fs.existsSync(target) && !overwrite) {
|
||||
throw new Error(Utils.Errors.CANT_OVERRIDE);
|
||||
}
|
||||
// The reverse operation for attr depend on method addFile()
|
||||
const fileAttr = keepOriginalPermission ? entry.header.fileAttr : undefined;
|
||||
filetools.writeFileTo(target, content, overwrite, fileAttr);
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
/**
|
||||
* Test the archive
|
||||
*
|
||||
*/
|
||||
test: function (pass) {
|
||||
if (!_zip) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (var entry in _zip.entries) {
|
||||
try {
|
||||
if (entry.isDirectory) {
|
||||
continue;
|
||||
}
|
||||
var content = _zip.entries[entry].getData(pass);
|
||||
if (!content) {
|
||||
return false;
|
||||
}
|
||||
} catch (err) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
},
|
||||
|
||||
/**
|
||||
* Extracts the entire archive to the given location
|
||||
*
|
||||
* @param targetPath Target location
|
||||
* @param overwrite If the file already exists at the target path, the file will be overwriten if this is true.
|
||||
* Default is FALSE
|
||||
* @param keepOriginalPermission The file will be set as the permission from the entry if this is true.
|
||||
* Default is FALSE
|
||||
*/
|
||||
extractAllTo: function (/**String*/ targetPath, /**Boolean*/ overwrite, /**Boolean*/ keepOriginalPermission, /*String, Buffer*/ pass) {
|
||||
overwrite = get_Bool(overwrite, false);
|
||||
pass = get_Str(keepOriginalPermission, pass);
|
||||
keepOriginalPermission = get_Bool(keepOriginalPermission, false);
|
||||
if (!_zip) {
|
||||
throw new Error(Utils.Errors.NO_ZIP);
|
||||
}
|
||||
_zip.entries.forEach(function (entry) {
|
||||
var entryName = sanitize(targetPath, canonical(entry.entryName.toString()));
|
||||
if (entry.isDirectory) {
|
||||
filetools.makeDir(entryName);
|
||||
return;
|
||||
}
|
||||
var content = entry.getData(pass);
|
||||
if (!content) {
|
||||
throw new Error(Utils.Errors.CANT_EXTRACT_FILE);
|
||||
}
|
||||
// The reverse operation for attr depend on method addFile()
|
||||
const fileAttr = keepOriginalPermission ? entry.header.fileAttr : undefined;
|
||||
filetools.writeFileTo(entryName, content, overwrite, fileAttr);
|
||||
try {
|
||||
filetools.fs.utimesSync(entryName, entry.header.time, entry.header.time);
|
||||
} catch (err) {
|
||||
throw new Error(Utils.Errors.CANT_EXTRACT_FILE);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Asynchronous extractAllTo
|
||||
*
|
||||
* @param targetPath Target location
|
||||
* @param overwrite If the file already exists at the target path, the file will be overwriten if this is true.
|
||||
* Default is FALSE
|
||||
* @param keepOriginalPermission The file will be set as the permission from the entry if this is true.
|
||||
* Default is FALSE
|
||||
* @param callback The callback will be executed when all entries are extracted successfully or any error is thrown.
|
||||
*/
|
||||
extractAllToAsync: function (/**String*/ targetPath, /**Boolean*/ overwrite, /**Boolean*/ keepOriginalPermission, /**Function*/ callback) {
|
||||
overwrite = get_Bool(overwrite, false);
|
||||
if (typeof keepOriginalPermission === "function" && !callback) callback = keepOriginalPermission;
|
||||
keepOriginalPermission = get_Bool(keepOriginalPermission, false);
|
||||
if (!callback) {
|
||||
callback = function (err) {
|
||||
throw new Error(err);
|
||||
};
|
||||
}
|
||||
if (!_zip) {
|
||||
callback(new Error(Utils.Errors.NO_ZIP));
|
||||
return;
|
||||
}
|
||||
|
||||
targetPath = pth.resolve(targetPath);
|
||||
// convert entryName to
|
||||
const getPath = (entry) => sanitize(targetPath, pth.normalize(canonical(entry.entryName.toString())));
|
||||
const getError = (msg, file) => new Error(msg + ': "' + file + '"');
|
||||
|
||||
// separate directories from files
|
||||
const dirEntries = [];
|
||||
const fileEntries = new Set();
|
||||
_zip.entries.forEach((e) => {
|
||||
if (e.isDirectory) {
|
||||
dirEntries.push(e);
|
||||
} else {
|
||||
fileEntries.add(e);
|
||||
}
|
||||
});
|
||||
|
||||
// Create directory entries first synchronously
|
||||
// this prevents race condition and assures folders are there before writing files
|
||||
for (const entry of dirEntries) {
|
||||
const dirPath = getPath(entry);
|
||||
// The reverse operation for attr depend on method addFile()
|
||||
const dirAttr = keepOriginalPermission ? entry.header.fileAttr : undefined;
|
||||
try {
|
||||
filetools.makeDir(dirPath);
|
||||
if (dirAttr) filetools.fs.chmodSync(dirPath, dirAttr);
|
||||
// in unix timestamp will change if files are later added to folder, but still
|
||||
filetools.fs.utimesSync(dirPath, entry.header.time, entry.header.time);
|
||||
} catch (er) {
|
||||
callback(getError("Unable to create folder", dirPath));
|
||||
}
|
||||
}
|
||||
|
||||
// callback wrapper, for some house keeping
|
||||
const done = () => {
|
||||
if (fileEntries.size === 0) {
|
||||
callback();
|
||||
}
|
||||
};
|
||||
|
||||
// Extract file entries asynchronously
|
||||
for (const entry of fileEntries.values()) {
|
||||
const entryName = pth.normalize(canonical(entry.entryName.toString()));
|
||||
const filePath = sanitize(targetPath, entryName);
|
||||
entry.getDataAsync(function (content, err_1) {
|
||||
if (err_1) {
|
||||
callback(new Error(err_1));
|
||||
return;
|
||||
}
|
||||
if (!content) {
|
||||
callback(new Error(Utils.Errors.CANT_EXTRACT_FILE));
|
||||
} else {
|
||||
// The reverse operation for attr depend on method addFile()
|
||||
const fileAttr = keepOriginalPermission ? entry.header.fileAttr : undefined;
|
||||
filetools.writeFileToAsync(filePath, content, overwrite, fileAttr, function (succ) {
|
||||
if (!succ) {
|
||||
callback(getError("Unable to write file", filePath));
|
||||
return;
|
||||
}
|
||||
filetools.fs.utimes(filePath, entry.header.time, entry.header.time, function (err_2) {
|
||||
if (err_2) {
|
||||
callback(getError("Unable to set times", filePath));
|
||||
return;
|
||||
}
|
||||
fileEntries.delete(entry);
|
||||
// call the callback if it was last entry
|
||||
done();
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
// call the callback if fileEntries was empty
|
||||
done();
|
||||
},
|
||||
|
||||
/**
|
||||
* Writes the newly created zip file to disk at the specified location or if a zip was opened and no ``targetFileName`` is provided, it will overwrite the opened zip
|
||||
*
|
||||
* @param targetFileName
|
||||
* @param callback
|
||||
*/
|
||||
writeZip: function (/**String*/ targetFileName, /**Function*/ callback) {
|
||||
if (arguments.length === 1) {
|
||||
if (typeof targetFileName === "function") {
|
||||
callback = targetFileName;
|
||||
targetFileName = "";
|
||||
}
|
||||
}
|
||||
|
||||
if (!targetFileName && opts.filename) {
|
||||
targetFileName = opts.filename;
|
||||
}
|
||||
if (!targetFileName) return;
|
||||
|
||||
var zipData = _zip.compressToBuffer();
|
||||
if (zipData) {
|
||||
var ok = filetools.writeFileTo(targetFileName, zipData, true);
|
||||
if (typeof callback === "function") callback(!ok ? new Error("failed") : null, "");
|
||||
}
|
||||
},
|
||||
|
||||
writeZipPromise: function (/**String*/ targetFileName, /* object */ props) {
|
||||
const { overwrite, perm } = Object.assign({ overwrite: true }, props);
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
// find file name
|
||||
if (!targetFileName && opts.filename) targetFileName = opts.filename;
|
||||
if (!targetFileName) reject("ADM-ZIP: ZIP File Name Missing");
|
||||
|
||||
this.toBufferPromise().then((zipData) => {
|
||||
const ret = (done) => (done ? resolve(done) : reject("ADM-ZIP: Wasn't able to write zip file"));
|
||||
filetools.writeFileToAsync(targetFileName, zipData, overwrite, perm, ret);
|
||||
}, reject);
|
||||
});
|
||||
},
|
||||
|
||||
toBufferPromise: function () {
|
||||
return new Promise((resolve, reject) => {
|
||||
_zip.toAsyncBuffer(resolve, reject);
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the content of the entire zip file as a Buffer object
|
||||
*
|
||||
* @return Buffer
|
||||
*/
|
||||
toBuffer: function (/**Function=*/ onSuccess, /**Function=*/ onFail, /**Function=*/ onItemStart, /**Function=*/ onItemEnd) {
|
||||
this.valueOf = 2;
|
||||
if (typeof onSuccess === "function") {
|
||||
_zip.toAsyncBuffer(onSuccess, onFail, onItemStart, onItemEnd);
|
||||
return null;
|
||||
}
|
||||
return _zip.compressToBuffer();
|
||||
}
|
||||
};
|
||||
};
|
||||
338
_shared/lib/adm-zip/headers/entryHeader.js
Normal file
338
_shared/lib/adm-zip/headers/entryHeader.js
Normal file
|
|
@ -0,0 +1,338 @@
|
|||
var Utils = require("../util"),
|
||||
Constants = Utils.Constants;
|
||||
|
||||
/* The central directory file header */
|
||||
module.exports = function () {
|
||||
var _verMade = 20, // v2.0
|
||||
_version = 10, // v1.0
|
||||
_flags = 0,
|
||||
_method = 0,
|
||||
_time = 0,
|
||||
_crc = 0,
|
||||
_compressedSize = 0,
|
||||
_size = 0,
|
||||
_fnameLen = 0,
|
||||
_extraLen = 0,
|
||||
_comLen = 0,
|
||||
_diskStart = 0,
|
||||
_inattr = 0,
|
||||
_attr = 0,
|
||||
_offset = 0;
|
||||
|
||||
_verMade |= Utils.isWin ? 0x0a00 : 0x0300;
|
||||
|
||||
// Set EFS flag since filename and comment fields are all by default encoded using UTF-8.
|
||||
// Without it file names may be corrupted for other apps when file names use unicode chars
|
||||
_flags |= Constants.FLG_EFS;
|
||||
|
||||
var _dataHeader = {};
|
||||
|
||||
function setTime(val) {
|
||||
val = new Date(val);
|
||||
_time =
|
||||
(((val.getFullYear() - 1980) & 0x7f) << 25) | // b09-16 years from 1980
|
||||
((val.getMonth() + 1) << 21) | // b05-08 month
|
||||
(val.getDate() << 16) | // b00-04 hour
|
||||
// 2 bytes time
|
||||
(val.getHours() << 11) | // b11-15 hour
|
||||
(val.getMinutes() << 5) | // b05-10 minute
|
||||
(val.getSeconds() >> 1); // b00-04 seconds divided by 2
|
||||
}
|
||||
|
||||
setTime(+new Date());
|
||||
|
||||
return {
|
||||
get made() {
|
||||
return _verMade;
|
||||
},
|
||||
set made(val) {
|
||||
_verMade = val;
|
||||
},
|
||||
|
||||
get version() {
|
||||
return _version;
|
||||
},
|
||||
set version(val) {
|
||||
_version = val;
|
||||
},
|
||||
|
||||
get flags() {
|
||||
return _flags;
|
||||
},
|
||||
set flags(val) {
|
||||
_flags = val;
|
||||
},
|
||||
|
||||
get method() {
|
||||
return _method;
|
||||
},
|
||||
set method(val) {
|
||||
switch (val) {
|
||||
case Constants.STORED:
|
||||
this.version = 10;
|
||||
case Constants.DEFLATED:
|
||||
default:
|
||||
this.version = 20;
|
||||
}
|
||||
_method = val;
|
||||
},
|
||||
|
||||
get time() {
|
||||
return new Date(((_time >> 25) & 0x7f) + 1980, ((_time >> 21) & 0x0f) - 1, (_time >> 16) & 0x1f, (_time >> 11) & 0x1f, (_time >> 5) & 0x3f, (_time & 0x1f) << 1);
|
||||
},
|
||||
set time(val) {
|
||||
setTime(val);
|
||||
},
|
||||
|
||||
get crc() {
|
||||
return _crc;
|
||||
},
|
||||
set crc(val) {
|
||||
_crc = Math.max(0, val) >>> 0;
|
||||
},
|
||||
|
||||
get compressedSize() {
|
||||
return _compressedSize;
|
||||
},
|
||||
set compressedSize(val) {
|
||||
_compressedSize = Math.max(0, val) >>> 0;
|
||||
},
|
||||
|
||||
get size() {
|
||||
return _size;
|
||||
},
|
||||
set size(val) {
|
||||
_size = Math.max(0, val) >>> 0;
|
||||
},
|
||||
|
||||
get fileNameLength() {
|
||||
return _fnameLen;
|
||||
},
|
||||
set fileNameLength(val) {
|
||||
_fnameLen = val;
|
||||
},
|
||||
|
||||
get extraLength() {
|
||||
return _extraLen;
|
||||
},
|
||||
set extraLength(val) {
|
||||
_extraLen = val;
|
||||
},
|
||||
|
||||
get commentLength() {
|
||||
return _comLen;
|
||||
},
|
||||
set commentLength(val) {
|
||||
_comLen = val;
|
||||
},
|
||||
|
||||
get diskNumStart() {
|
||||
return _diskStart;
|
||||
},
|
||||
set diskNumStart(val) {
|
||||
_diskStart = Math.max(0, val) >>> 0;
|
||||
},
|
||||
|
||||
get inAttr() {
|
||||
return _inattr;
|
||||
},
|
||||
set inAttr(val) {
|
||||
_inattr = Math.max(0, val) >>> 0;
|
||||
},
|
||||
|
||||
get attr() {
|
||||
return _attr;
|
||||
},
|
||||
set attr(val) {
|
||||
_attr = Math.max(0, val) >>> 0;
|
||||
},
|
||||
|
||||
// get Unix file permissions
|
||||
get fileAttr() {
|
||||
return _attr ? (((_attr >>> 0) | 0) >> 16) & 0xfff : 0;
|
||||
},
|
||||
|
||||
get offset() {
|
||||
return _offset;
|
||||
},
|
||||
set offset(val) {
|
||||
_offset = Math.max(0, val) >>> 0;
|
||||
},
|
||||
|
||||
get encripted() {
|
||||
return (_flags & 1) === 1;
|
||||
},
|
||||
|
||||
get entryHeaderSize() {
|
||||
return Constants.CENHDR + _fnameLen + _extraLen + _comLen;
|
||||
},
|
||||
|
||||
get realDataOffset() {
|
||||
return _offset + Constants.LOCHDR + _dataHeader.fnameLen + _dataHeader.extraLen;
|
||||
},
|
||||
|
||||
get dataHeader() {
|
||||
return _dataHeader;
|
||||
},
|
||||
|
||||
loadDataHeaderFromBinary: function (/*Buffer*/ input) {
|
||||
var data = input.slice(_offset, _offset + Constants.LOCHDR);
|
||||
// 30 bytes and should start with "PK\003\004"
|
||||
if (data.readUInt32LE(0) !== Constants.LOCSIG) {
|
||||
throw new Error(Utils.Errors.INVALID_LOC);
|
||||
}
|
||||
_dataHeader = {
|
||||
// version needed to extract
|
||||
version: data.readUInt16LE(Constants.LOCVER),
|
||||
// general purpose bit flag
|
||||
flags: data.readUInt16LE(Constants.LOCFLG),
|
||||
// compression method
|
||||
method: data.readUInt16LE(Constants.LOCHOW),
|
||||
// modification time (2 bytes time, 2 bytes date)
|
||||
time: data.readUInt32LE(Constants.LOCTIM),
|
||||
// uncompressed file crc-32 value
|
||||
crc: data.readUInt32LE(Constants.LOCCRC),
|
||||
// compressed size
|
||||
compressedSize: data.readUInt32LE(Constants.LOCSIZ),
|
||||
// uncompressed size
|
||||
size: data.readUInt32LE(Constants.LOCLEN),
|
||||
// filename length
|
||||
fnameLen: data.readUInt16LE(Constants.LOCNAM),
|
||||
// extra field length
|
||||
extraLen: data.readUInt16LE(Constants.LOCEXT)
|
||||
};
|
||||
},
|
||||
|
||||
loadFromBinary: function (/*Buffer*/ data) {
|
||||
// data should be 46 bytes and start with "PK 01 02"
|
||||
if (data.length !== Constants.CENHDR || data.readUInt32LE(0) !== Constants.CENSIG) {
|
||||
throw new Error(Utils.Errors.INVALID_CEN);
|
||||
}
|
||||
// version made by
|
||||
_verMade = data.readUInt16LE(Constants.CENVEM);
|
||||
// version needed to extract
|
||||
_version = data.readUInt16LE(Constants.CENVER);
|
||||
// encrypt, decrypt flags
|
||||
_flags = data.readUInt16LE(Constants.CENFLG);
|
||||
// compression method
|
||||
_method = data.readUInt16LE(Constants.CENHOW);
|
||||
// modification time (2 bytes time, 2 bytes date)
|
||||
_time = data.readUInt32LE(Constants.CENTIM);
|
||||
// uncompressed file crc-32 value
|
||||
_crc = data.readUInt32LE(Constants.CENCRC);
|
||||
// compressed size
|
||||
_compressedSize = data.readUInt32LE(Constants.CENSIZ);
|
||||
// uncompressed size
|
||||
_size = data.readUInt32LE(Constants.CENLEN);
|
||||
// filename length
|
||||
_fnameLen = data.readUInt16LE(Constants.CENNAM);
|
||||
// extra field length
|
||||
_extraLen = data.readUInt16LE(Constants.CENEXT);
|
||||
// file comment length
|
||||
_comLen = data.readUInt16LE(Constants.CENCOM);
|
||||
// volume number start
|
||||
_diskStart = data.readUInt16LE(Constants.CENDSK);
|
||||
// internal file attributes
|
||||
_inattr = data.readUInt16LE(Constants.CENATT);
|
||||
// external file attributes
|
||||
_attr = data.readUInt32LE(Constants.CENATX);
|
||||
// LOC header offset
|
||||
_offset = data.readUInt32LE(Constants.CENOFF);
|
||||
},
|
||||
|
||||
dataHeaderToBinary: function () {
|
||||
// LOC header size (30 bytes)
|
||||
var data = Buffer.alloc(Constants.LOCHDR);
|
||||
// "PK\003\004"
|
||||
data.writeUInt32LE(Constants.LOCSIG, 0);
|
||||
// version needed to extract
|
||||
data.writeUInt16LE(_version, Constants.LOCVER);
|
||||
// general purpose bit flag
|
||||
data.writeUInt16LE(_flags, Constants.LOCFLG);
|
||||
// compression method
|
||||
data.writeUInt16LE(_method, Constants.LOCHOW);
|
||||
// modification time (2 bytes time, 2 bytes date)
|
||||
data.writeUInt32LE(_time, Constants.LOCTIM);
|
||||
// uncompressed file crc-32 value
|
||||
data.writeUInt32LE(_crc, Constants.LOCCRC);
|
||||
// compressed size
|
||||
data.writeUInt32LE(_compressedSize, Constants.LOCSIZ);
|
||||
// uncompressed size
|
||||
data.writeUInt32LE(_size, Constants.LOCLEN);
|
||||
// filename length
|
||||
data.writeUInt16LE(_fnameLen, Constants.LOCNAM);
|
||||
// extra field length
|
||||
data.writeUInt16LE(_extraLen, Constants.LOCEXT);
|
||||
return data;
|
||||
},
|
||||
|
||||
entryHeaderToBinary: function () {
|
||||
// CEN header size (46 bytes)
|
||||
var data = Buffer.alloc(Constants.CENHDR + _fnameLen + _extraLen + _comLen);
|
||||
// "PK\001\002"
|
||||
data.writeUInt32LE(Constants.CENSIG, 0);
|
||||
// version made by
|
||||
data.writeUInt16LE(_verMade, Constants.CENVEM);
|
||||
// version needed to extract
|
||||
data.writeUInt16LE(_version, Constants.CENVER);
|
||||
// encrypt, decrypt flags
|
||||
data.writeUInt16LE(_flags, Constants.CENFLG);
|
||||
// compression method
|
||||
data.writeUInt16LE(_method, Constants.CENHOW);
|
||||
// modification time (2 bytes time, 2 bytes date)
|
||||
data.writeUInt32LE(_time, Constants.CENTIM);
|
||||
// uncompressed file crc-32 value
|
||||
data.writeUInt32LE(_crc, Constants.CENCRC);
|
||||
// compressed size
|
||||
data.writeUInt32LE(_compressedSize, Constants.CENSIZ);
|
||||
// uncompressed size
|
||||
data.writeUInt32LE(_size, Constants.CENLEN);
|
||||
// filename length
|
||||
data.writeUInt16LE(_fnameLen, Constants.CENNAM);
|
||||
// extra field length
|
||||
data.writeUInt16LE(_extraLen, Constants.CENEXT);
|
||||
// file comment length
|
||||
data.writeUInt16LE(_comLen, Constants.CENCOM);
|
||||
// volume number start
|
||||
data.writeUInt16LE(_diskStart, Constants.CENDSK);
|
||||
// internal file attributes
|
||||
data.writeUInt16LE(_inattr, Constants.CENATT);
|
||||
// external file attributes
|
||||
data.writeUInt32LE(_attr, Constants.CENATX);
|
||||
// LOC header offset
|
||||
data.writeUInt32LE(_offset, Constants.CENOFF);
|
||||
// fill all with
|
||||
data.fill(0x00, Constants.CENHDR);
|
||||
return data;
|
||||
},
|
||||
|
||||
toJSON: function () {
|
||||
const bytes = function (nr) {
|
||||
return nr + " bytes";
|
||||
};
|
||||
|
||||
return {
|
||||
made: _verMade,
|
||||
version: _version,
|
||||
flags: _flags,
|
||||
method: Utils.methodToString(_method),
|
||||
time: this.time,
|
||||
crc: "0x" + _crc.toString(16).toUpperCase(),
|
||||
compressedSize: bytes(_compressedSize),
|
||||
size: bytes(_size),
|
||||
fileNameLength: bytes(_fnameLen),
|
||||
extraLength: bytes(_extraLen),
|
||||
commentLength: bytes(_comLen),
|
||||
diskNumStart: _diskStart,
|
||||
inAttr: _inattr,
|
||||
attr: _attr,
|
||||
offset: _offset,
|
||||
entryHeaderSize: bytes(Constants.CENHDR + _fnameLen + _extraLen + _comLen)
|
||||
};
|
||||
},
|
||||
|
||||
toString: function () {
|
||||
return JSON.stringify(this.toJSON(), null, "\t");
|
||||
}
|
||||
};
|
||||
};
|
||||
2
_shared/lib/adm-zip/headers/index.js
Normal file
2
_shared/lib/adm-zip/headers/index.js
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
exports.EntryHeader = require("./entryHeader");
|
||||
exports.MainHeader = require("./mainHeader");
|
||||
130
_shared/lib/adm-zip/headers/mainHeader.js
Normal file
130
_shared/lib/adm-zip/headers/mainHeader.js
Normal file
|
|
@ -0,0 +1,130 @@
|
|||
var Utils = require("../util"),
|
||||
Constants = Utils.Constants;
|
||||
|
||||
/* The entries in the end of central directory */
|
||||
module.exports = function () {
|
||||
var _volumeEntries = 0,
|
||||
_totalEntries = 0,
|
||||
_size = 0,
|
||||
_offset = 0,
|
||||
_commentLength = 0;
|
||||
|
||||
return {
|
||||
get diskEntries() {
|
||||
return _volumeEntries;
|
||||
},
|
||||
set diskEntries(/*Number*/ val) {
|
||||
_volumeEntries = _totalEntries = val;
|
||||
},
|
||||
|
||||
get totalEntries() {
|
||||
return _totalEntries;
|
||||
},
|
||||
set totalEntries(/*Number*/ val) {
|
||||
_totalEntries = _volumeEntries = val;
|
||||
},
|
||||
|
||||
get size() {
|
||||
return _size;
|
||||
},
|
||||
set size(/*Number*/ val) {
|
||||
_size = val;
|
||||
},
|
||||
|
||||
get offset() {
|
||||
return _offset;
|
||||
},
|
||||
set offset(/*Number*/ val) {
|
||||
_offset = val;
|
||||
},
|
||||
|
||||
get commentLength() {
|
||||
return _commentLength;
|
||||
},
|
||||
set commentLength(/*Number*/ val) {
|
||||
_commentLength = val;
|
||||
},
|
||||
|
||||
get mainHeaderSize() {
|
||||
return Constants.ENDHDR + _commentLength;
|
||||
},
|
||||
|
||||
loadFromBinary: function (/*Buffer*/ data) {
|
||||
// data should be 22 bytes and start with "PK 05 06"
|
||||
// or be 56+ bytes and start with "PK 06 06" for Zip64
|
||||
if (
|
||||
(data.length !== Constants.ENDHDR || data.readUInt32LE(0) !== Constants.ENDSIG) &&
|
||||
(data.length < Constants.ZIP64HDR || data.readUInt32LE(0) !== Constants.ZIP64SIG)
|
||||
) {
|
||||
throw new Error(Utils.Errors.INVALID_END);
|
||||
}
|
||||
|
||||
if (data.readUInt32LE(0) === Constants.ENDSIG) {
|
||||
// number of entries on this volume
|
||||
_volumeEntries = data.readUInt16LE(Constants.ENDSUB);
|
||||
// total number of entries
|
||||
_totalEntries = data.readUInt16LE(Constants.ENDTOT);
|
||||
// central directory size in bytes
|
||||
_size = data.readUInt32LE(Constants.ENDSIZ);
|
||||
// offset of first CEN header
|
||||
_offset = data.readUInt32LE(Constants.ENDOFF);
|
||||
// zip file comment length
|
||||
_commentLength = data.readUInt16LE(Constants.ENDCOM);
|
||||
} else {
|
||||
// number of entries on this volume
|
||||
_volumeEntries = Utils.readBigUInt64LE(data, Constants.ZIP64SUB);
|
||||
// total number of entries
|
||||
_totalEntries = Utils.readBigUInt64LE(data, Constants.ZIP64TOT);
|
||||
// central directory size in bytes
|
||||
_size = Utils.readBigUInt64LE(data, Constants.ZIP64SIZE);
|
||||
// offset of first CEN header
|
||||
_offset = Utils.readBigUInt64LE(data, Constants.ZIP64OFF);
|
||||
|
||||
_commentLength = 0;
|
||||
}
|
||||
},
|
||||
|
||||
toBinary: function () {
|
||||
var b = Buffer.alloc(Constants.ENDHDR + _commentLength);
|
||||
// "PK 05 06" signature
|
||||
b.writeUInt32LE(Constants.ENDSIG, 0);
|
||||
b.writeUInt32LE(0, 4);
|
||||
// number of entries on this volume
|
||||
b.writeUInt16LE(_volumeEntries, Constants.ENDSUB);
|
||||
// total number of entries
|
||||
b.writeUInt16LE(_totalEntries, Constants.ENDTOT);
|
||||
// central directory size in bytes
|
||||
b.writeUInt32LE(_size, Constants.ENDSIZ);
|
||||
// offset of first CEN header
|
||||
b.writeUInt32LE(_offset, Constants.ENDOFF);
|
||||
// zip file comment length
|
||||
b.writeUInt16LE(_commentLength, Constants.ENDCOM);
|
||||
// fill comment memory with spaces so no garbage is left there
|
||||
b.fill(" ", Constants.ENDHDR);
|
||||
|
||||
return b;
|
||||
},
|
||||
|
||||
toJSON: function () {
|
||||
// creates 0x0000 style output
|
||||
const offset = function (nr, len) {
|
||||
let offs = nr.toString(16).toUpperCase();
|
||||
while (offs.length < len) offs = "0" + offs;
|
||||
return "0x" + offs;
|
||||
};
|
||||
|
||||
return {
|
||||
diskEntries: _volumeEntries,
|
||||
totalEntries: _totalEntries,
|
||||
size: _size + " bytes",
|
||||
offset: offset(_offset, 4),
|
||||
commentLength: _commentLength
|
||||
};
|
||||
},
|
||||
|
||||
toString: function () {
|
||||
return JSON.stringify(this.toJSON(), null, "\t");
|
||||
}
|
||||
};
|
||||
};
|
||||
// Misspelled
|
||||
33
_shared/lib/adm-zip/methods/deflater.js
Normal file
33
_shared/lib/adm-zip/methods/deflater.js
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
module.exports = function (/*Buffer*/ inbuf) {
|
||||
var zlib = require("zlib");
|
||||
|
||||
var opts = { chunkSize: (parseInt(inbuf.length / 1024) + 1) * 1024 };
|
||||
|
||||
return {
|
||||
deflate: function () {
|
||||
return zlib.deflateRawSync(inbuf, opts);
|
||||
},
|
||||
|
||||
deflateAsync: function (/*Function*/ callback) {
|
||||
var tmp = zlib.createDeflateRaw(opts),
|
||||
parts = [],
|
||||
total = 0;
|
||||
tmp.on("data", function (data) {
|
||||
parts.push(data);
|
||||
total += data.length;
|
||||
});
|
||||
tmp.on("end", function () {
|
||||
var buf = Buffer.alloc(total),
|
||||
written = 0;
|
||||
buf.fill(0);
|
||||
for (var i = 0; i < parts.length; i++) {
|
||||
var part = parts[i];
|
||||
part.copy(buf, written);
|
||||
written += part.length;
|
||||
}
|
||||
callback && callback(buf);
|
||||
});
|
||||
tmp.end(inbuf);
|
||||
}
|
||||
};
|
||||
};
|
||||
3
_shared/lib/adm-zip/methods/index.js
Normal file
3
_shared/lib/adm-zip/methods/index.js
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
exports.Deflater = require("./deflater");
|
||||
exports.Inflater = require("./inflater");
|
||||
exports.ZipCrypto = require("./zipcrypto");
|
||||
31
_shared/lib/adm-zip/methods/inflater.js
Normal file
31
_shared/lib/adm-zip/methods/inflater.js
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
module.exports = function (/*Buffer*/ inbuf) {
|
||||
var zlib = require("zlib");
|
||||
|
||||
return {
|
||||
inflate: function () {
|
||||
return zlib.inflateRawSync(inbuf);
|
||||
},
|
||||
|
||||
inflateAsync: function (/*Function*/ callback) {
|
||||
var tmp = zlib.createInflateRaw(),
|
||||
parts = [],
|
||||
total = 0;
|
||||
tmp.on("data", function (data) {
|
||||
parts.push(data);
|
||||
total += data.length;
|
||||
});
|
||||
tmp.on("end", function () {
|
||||
var buf = Buffer.alloc(total),
|
||||
written = 0;
|
||||
buf.fill(0);
|
||||
for (var i = 0; i < parts.length; i++) {
|
||||
var part = parts[i];
|
||||
part.copy(buf, written);
|
||||
written += part.length;
|
||||
}
|
||||
callback && callback(buf);
|
||||
});
|
||||
tmp.end(inbuf);
|
||||
}
|
||||
};
|
||||
};
|
||||
170
_shared/lib/adm-zip/methods/zipcrypto.js
Normal file
170
_shared/lib/adm-zip/methods/zipcrypto.js
Normal file
|
|
@ -0,0 +1,170 @@
|
|||
"use strict";
|
||||
|
||||
// node crypt, we use it for generate salt
|
||||
// eslint-disable-next-line node/no-unsupported-features/node-builtins
|
||||
const { randomFillSync } = require("crypto");
|
||||
|
||||
// generate CRC32 lookup table
|
||||
const crctable = new Uint32Array(256).map((t, crc) => {
|
||||
for (let j = 0; j < 8; j++) {
|
||||
if (0 !== (crc & 1)) {
|
||||
crc = (crc >>> 1) ^ 0xedb88320;
|
||||
} else {
|
||||
crc >>>= 1;
|
||||
}
|
||||
}
|
||||
return crc >>> 0;
|
||||
});
|
||||
|
||||
// C-style uInt32 Multiply (discards higher bits, when JS multiply discards lower bits)
|
||||
const uMul = (a, b) => Math.imul(a, b) >>> 0;
|
||||
|
||||
// crc32 byte single update (actually same function is part of utils.crc32 function :) )
|
||||
const crc32update = (pCrc32, bval) => {
|
||||
return crctable[(pCrc32 ^ bval) & 0xff] ^ (pCrc32 >>> 8);
|
||||
};
|
||||
|
||||
// function for generating salt for encrytion header
|
||||
const genSalt = () => {
|
||||
if ("function" === typeof randomFillSync) {
|
||||
return randomFillSync(Buffer.alloc(12));
|
||||
} else {
|
||||
// fallback if function is not defined
|
||||
return genSalt.node();
|
||||
}
|
||||
};
|
||||
|
||||
// salt generation with node random function (mainly as fallback)
|
||||
genSalt.node = () => {
|
||||
const salt = Buffer.alloc(12);
|
||||
const len = salt.length;
|
||||
for (let i = 0; i < len; i++) salt[i] = (Math.random() * 256) & 0xff;
|
||||
return salt;
|
||||
};
|
||||
|
||||
// general config
|
||||
const config = {
|
||||
genSalt
|
||||
};
|
||||
|
||||
// Class Initkeys handles same basic ops with keys
|
||||
function Initkeys(pw) {
|
||||
const pass = Buffer.isBuffer(pw) ? pw : Buffer.from(pw);
|
||||
this.keys = new Uint32Array([0x12345678, 0x23456789, 0x34567890]);
|
||||
for (let i = 0; i < pass.length; i++) {
|
||||
this.updateKeys(pass[i]);
|
||||
}
|
||||
}
|
||||
|
||||
Initkeys.prototype.updateKeys = function (byteValue) {
|
||||
const keys = this.keys;
|
||||
keys[0] = crc32update(keys[0], byteValue);
|
||||
keys[1] += keys[0] & 0xff;
|
||||
keys[1] = uMul(keys[1], 134775813) + 1;
|
||||
keys[2] = crc32update(keys[2], keys[1] >>> 24);
|
||||
return byteValue;
|
||||
};
|
||||
|
||||
Initkeys.prototype.next = function () {
|
||||
const k = (this.keys[2] | 2) >>> 0; // key
|
||||
return (uMul(k, k ^ 1) >> 8) & 0xff; // decode
|
||||
};
|
||||
|
||||
function make_decrypter(/*Buffer*/ pwd) {
|
||||
// 1. Stage initialize key
|
||||
const keys = new Initkeys(pwd);
|
||||
|
||||
// return decrypter function
|
||||
return function (/*Buffer*/ data) {
|
||||
// result - we create new Buffer for results
|
||||
const result = Buffer.alloc(data.length);
|
||||
let pos = 0;
|
||||
// process input data
|
||||
for (let c of data) {
|
||||
//c ^= keys.next();
|
||||
//result[pos++] = c; // decode & Save Value
|
||||
result[pos++] = keys.updateKeys(c ^ keys.next()); // update keys with decoded byte
|
||||
}
|
||||
return result;
|
||||
};
|
||||
}
|
||||
|
||||
function make_encrypter(/*Buffer*/ pwd) {
|
||||
// 1. Stage initialize key
|
||||
const keys = new Initkeys(pwd);
|
||||
|
||||
// return encrypting function, result and pos is here so we dont have to merge buffers later
|
||||
return function (/*Buffer*/ data, /*Buffer*/ result, /* Number */ pos = 0) {
|
||||
// result - we create new Buffer for results
|
||||
if (!result) result = Buffer.alloc(data.length);
|
||||
// process input data
|
||||
for (let c of data) {
|
||||
const k = keys.next(); // save key byte
|
||||
result[pos++] = c ^ k; // save val
|
||||
keys.updateKeys(c); // update keys with decoded byte
|
||||
}
|
||||
return result;
|
||||
};
|
||||
}
|
||||
|
||||
function decrypt(/*Buffer*/ data, /*Object*/ header, /*String, Buffer*/ pwd) {
|
||||
if (!data || !Buffer.isBuffer(data) || data.length < 12) {
|
||||
return Buffer.alloc(0);
|
||||
}
|
||||
|
||||
// 1. We Initialize and generate decrypting function
|
||||
const decrypter = make_decrypter(pwd);
|
||||
|
||||
// 2. decrypt salt what is always 12 bytes and is a part of file content
|
||||
const salt = decrypter(data.slice(0, 12));
|
||||
|
||||
// 3. does password meet expectations
|
||||
if (salt[11] !== header.crc >>> 24) {
|
||||
throw "ADM-ZIP: Wrong Password";
|
||||
}
|
||||
|
||||
// 4. decode content
|
||||
return decrypter(data.slice(12));
|
||||
}
|
||||
|
||||
// lets add way to populate salt, NOT RECOMMENDED for production but maybe useful for testing general functionality
|
||||
function _salter(data) {
|
||||
if (Buffer.isBuffer(data) && data.length >= 12) {
|
||||
// be aware - currently salting buffer data is modified
|
||||
config.genSalt = function () {
|
||||
return data.slice(0, 12);
|
||||
};
|
||||
} else if (data === "node") {
|
||||
// test salt generation with node random function
|
||||
config.genSalt = genSalt.node;
|
||||
} else {
|
||||
// if value is not acceptable config gets reset.
|
||||
config.genSalt = genSalt;
|
||||
}
|
||||
}
|
||||
|
||||
function encrypt(/*Buffer*/ data, /*Object*/ header, /*String, Buffer*/ pwd, /*Boolean*/ oldlike = false) {
|
||||
// 1. test data if data is not Buffer we make buffer from it
|
||||
if (data == null) data = Buffer.alloc(0);
|
||||
// if data is not buffer be make buffer from it
|
||||
if (!Buffer.isBuffer(data)) data = Buffer.from(data.toString());
|
||||
|
||||
// 2. We Initialize and generate encrypting function
|
||||
const encrypter = make_encrypter(pwd);
|
||||
|
||||
// 3. generate salt (12-bytes of random data)
|
||||
const salt = config.genSalt();
|
||||
salt[11] = (header.crc >>> 24) & 0xff;
|
||||
|
||||
// old implementations (before PKZip 2.04g) used two byte check
|
||||
if (oldlike) salt[10] = (header.crc >>> 16) & 0xff;
|
||||
|
||||
// 4. create output
|
||||
const result = Buffer.alloc(data.length + 12);
|
||||
encrypter(salt, result);
|
||||
|
||||
// finally encode content
|
||||
return encrypter(data, result, 12);
|
||||
}
|
||||
|
||||
module.exports = { decrypt, encrypt, _salter };
|
||||
142
_shared/lib/adm-zip/util/constants.js
Normal file
142
_shared/lib/adm-zip/util/constants.js
Normal file
|
|
@ -0,0 +1,142 @@
|
|||
module.exports = {
|
||||
/* The local file header */
|
||||
LOCHDR : 30, // LOC header size
|
||||
LOCSIG : 0x04034b50, // "PK\003\004"
|
||||
LOCVER : 4, // version needed to extract
|
||||
LOCFLG : 6, // general purpose bit flag
|
||||
LOCHOW : 8, // compression method
|
||||
LOCTIM : 10, // modification time (2 bytes time, 2 bytes date)
|
||||
LOCCRC : 14, // uncompressed file crc-32 value
|
||||
LOCSIZ : 18, // compressed size
|
||||
LOCLEN : 22, // uncompressed size
|
||||
LOCNAM : 26, // filename length
|
||||
LOCEXT : 28, // extra field length
|
||||
|
||||
/* The Data descriptor */
|
||||
EXTSIG : 0x08074b50, // "PK\007\008"
|
||||
EXTHDR : 16, // EXT header size
|
||||
EXTCRC : 4, // uncompressed file crc-32 value
|
||||
EXTSIZ : 8, // compressed size
|
||||
EXTLEN : 12, // uncompressed size
|
||||
|
||||
/* The central directory file header */
|
||||
CENHDR : 46, // CEN header size
|
||||
CENSIG : 0x02014b50, // "PK\001\002"
|
||||
CENVEM : 4, // version made by
|
||||
CENVER : 6, // version needed to extract
|
||||
CENFLG : 8, // encrypt, decrypt flags
|
||||
CENHOW : 10, // compression method
|
||||
CENTIM : 12, // modification time (2 bytes time, 2 bytes date)
|
||||
CENCRC : 16, // uncompressed file crc-32 value
|
||||
CENSIZ : 20, // compressed size
|
||||
CENLEN : 24, // uncompressed size
|
||||
CENNAM : 28, // filename length
|
||||
CENEXT : 30, // extra field length
|
||||
CENCOM : 32, // file comment length
|
||||
CENDSK : 34, // volume number start
|
||||
CENATT : 36, // internal file attributes
|
||||
CENATX : 38, // external file attributes (host system dependent)
|
||||
CENOFF : 42, // LOC header offset
|
||||
|
||||
/* The entries in the end of central directory */
|
||||
ENDHDR : 22, // END header size
|
||||
ENDSIG : 0x06054b50, // "PK\005\006"
|
||||
ENDSUB : 8, // number of entries on this disk
|
||||
ENDTOT : 10, // total number of entries
|
||||
ENDSIZ : 12, // central directory size in bytes
|
||||
ENDOFF : 16, // offset of first CEN header
|
||||
ENDCOM : 20, // zip file comment length
|
||||
|
||||
END64HDR : 20, // zip64 END header size
|
||||
END64SIG : 0x07064b50, // zip64 Locator signature, "PK\006\007"
|
||||
END64START : 4, // number of the disk with the start of the zip64
|
||||
END64OFF : 8, // relative offset of the zip64 end of central directory
|
||||
END64NUMDISKS : 16, // total number of disks
|
||||
|
||||
ZIP64SIG : 0x06064b50, // zip64 signature, "PK\006\006"
|
||||
ZIP64HDR : 56, // zip64 record minimum size
|
||||
ZIP64LEAD : 12, // leading bytes at the start of the record, not counted by the value stored in ZIP64SIZE
|
||||
ZIP64SIZE : 4, // zip64 size of the central directory record
|
||||
ZIP64VEM : 12, // zip64 version made by
|
||||
ZIP64VER : 14, // zip64 version needed to extract
|
||||
ZIP64DSK : 16, // zip64 number of this disk
|
||||
ZIP64DSKDIR : 20, // number of the disk with the start of the record directory
|
||||
ZIP64SUB : 24, // number of entries on this disk
|
||||
ZIP64TOT : 32, // total number of entries
|
||||
ZIP64SIZB : 40, // zip64 central directory size in bytes
|
||||
ZIP64OFF : 48, // offset of start of central directory with respect to the starting disk number
|
||||
ZIP64EXTRA : 56, // extensible data sector
|
||||
|
||||
/* Compression methods */
|
||||
STORED : 0, // no compression
|
||||
SHRUNK : 1, // shrunk
|
||||
REDUCED1 : 2, // reduced with compression factor 1
|
||||
REDUCED2 : 3, // reduced with compression factor 2
|
||||
REDUCED3 : 4, // reduced with compression factor 3
|
||||
REDUCED4 : 5, // reduced with compression factor 4
|
||||
IMPLODED : 6, // imploded
|
||||
// 7 reserved for Tokenizing compression algorithm
|
||||
DEFLATED : 8, // deflated
|
||||
ENHANCED_DEFLATED: 9, // enhanced deflated
|
||||
PKWARE : 10,// PKWare DCL imploded
|
||||
// 11 reserved by PKWARE
|
||||
BZIP2 : 12, // compressed using BZIP2
|
||||
// 13 reserved by PKWARE
|
||||
LZMA : 14, // LZMA
|
||||
// 15-17 reserved by PKWARE
|
||||
IBM_TERSE : 18, // compressed using IBM TERSE
|
||||
IBM_LZ77 : 19, // IBM LZ77 z
|
||||
AES_ENCRYPT : 99, // WinZIP AES encryption method
|
||||
|
||||
/* General purpose bit flag */
|
||||
// values can obtained with expression 2**bitnr
|
||||
FLG_ENC : 1, // Bit 0: encrypted file
|
||||
FLG_COMP1 : 2, // Bit 1, compression option
|
||||
FLG_COMP2 : 4, // Bit 2, compression option
|
||||
FLG_DESC : 8, // Bit 3, data descriptor
|
||||
FLG_ENH : 16, // Bit 4, enhanced deflating
|
||||
FLG_PATCH : 32, // Bit 5, indicates that the file is compressed patched data.
|
||||
FLG_STR : 64, // Bit 6, strong encryption (patented)
|
||||
// Bits 7-10: Currently unused.
|
||||
FLG_EFS : 2048, // Bit 11: Language encoding flag (EFS)
|
||||
// Bit 12: Reserved by PKWARE for enhanced compression.
|
||||
// Bit 13: encrypted the Central Directory (patented).
|
||||
// Bits 14-15: Reserved by PKWARE.
|
||||
FLG_MSK : 4096, // mask header values
|
||||
|
||||
/* Load type */
|
||||
FILE : 2,
|
||||
BUFFER : 1,
|
||||
NONE : 0,
|
||||
|
||||
/* 4.5 Extensible data fields */
|
||||
EF_ID : 0,
|
||||
EF_SIZE : 2,
|
||||
|
||||
/* Header IDs */
|
||||
ID_ZIP64 : 0x0001,
|
||||
ID_AVINFO : 0x0007,
|
||||
ID_PFS : 0x0008,
|
||||
ID_OS2 : 0x0009,
|
||||
ID_NTFS : 0x000a,
|
||||
ID_OPENVMS : 0x000c,
|
||||
ID_UNIX : 0x000d,
|
||||
ID_FORK : 0x000e,
|
||||
ID_PATCH : 0x000f,
|
||||
ID_X509_PKCS7 : 0x0014,
|
||||
ID_X509_CERTID_F : 0x0015,
|
||||
ID_X509_CERTID_C : 0x0016,
|
||||
ID_STRONGENC : 0x0017,
|
||||
ID_RECORD_MGT : 0x0018,
|
||||
ID_X509_PKCS7_RL : 0x0019,
|
||||
ID_IBM1 : 0x0065,
|
||||
ID_IBM2 : 0x0066,
|
||||
ID_POSZIP : 0x4690,
|
||||
|
||||
EF_ZIP64_OR_32 : 0xffffffff,
|
||||
EF_ZIP64_OR_16 : 0xffff,
|
||||
EF_ZIP64_SUNCOMP : 0,
|
||||
EF_ZIP64_SCOMP : 8,
|
||||
EF_ZIP64_RHO : 16,
|
||||
EF_ZIP64_DSN : 24
|
||||
};
|
||||
35
_shared/lib/adm-zip/util/errors.js
Normal file
35
_shared/lib/adm-zip/util/errors.js
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
module.exports = {
|
||||
/* Header error messages */
|
||||
INVALID_LOC: "Invalid LOC header (bad signature)",
|
||||
INVALID_CEN: "Invalid CEN header (bad signature)",
|
||||
INVALID_END: "Invalid END header (bad signature)",
|
||||
|
||||
/* ZipEntry error messages*/
|
||||
NO_DATA: "Nothing to decompress",
|
||||
BAD_CRC: "CRC32 checksum failed",
|
||||
FILE_IN_THE_WAY: "There is a file in the way: %s",
|
||||
UNKNOWN_METHOD: "Invalid/unsupported compression method",
|
||||
|
||||
/* Inflater error messages */
|
||||
AVAIL_DATA: "inflate::Available inflate data did not terminate",
|
||||
INVALID_DISTANCE: "inflate::Invalid literal/length or distance code in fixed or dynamic block",
|
||||
TO_MANY_CODES: "inflate::Dynamic block code description: too many length or distance codes",
|
||||
INVALID_REPEAT_LEN: "inflate::Dynamic block code description: repeat more than specified lengths",
|
||||
INVALID_REPEAT_FIRST: "inflate::Dynamic block code description: repeat lengths with no first length",
|
||||
INCOMPLETE_CODES: "inflate::Dynamic block code description: code lengths codes incomplete",
|
||||
INVALID_DYN_DISTANCE: "inflate::Dynamic block code description: invalid distance code lengths",
|
||||
INVALID_CODES_LEN: "inflate::Dynamic block code description: invalid literal/length code lengths",
|
||||
INVALID_STORE_BLOCK: "inflate::Stored block length did not match one's complement",
|
||||
INVALID_BLOCK_TYPE: "inflate::Invalid block type (type == 3)",
|
||||
|
||||
/* ADM-ZIP error messages */
|
||||
CANT_EXTRACT_FILE: "Could not extract the file",
|
||||
CANT_OVERRIDE: "Target file already exists",
|
||||
NO_ZIP: "No zip file was loaded",
|
||||
NO_ENTRY: "Entry doesn't exist",
|
||||
DIRECTORY_CONTENT_ERROR: "A directory cannot have content",
|
||||
FILE_NOT_FOUND: "File not found: %s",
|
||||
NOT_IMPLEMENTED: "Not implemented",
|
||||
INVALID_FILENAME: "Invalid filename",
|
||||
INVALID_FORMAT: "Invalid or unsupported zip format. No END header found"
|
||||
};
|
||||
79
_shared/lib/adm-zip/util/fattr.js
Normal file
79
_shared/lib/adm-zip/util/fattr.js
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
const fs = require("./fileSystem").require();
|
||||
const pth = require("path");
|
||||
|
||||
fs.existsSync = fs.existsSync || pth.existsSync;
|
||||
|
||||
module.exports = function (/*String*/ path) {
|
||||
var _path = path || "",
|
||||
_obj = newAttr(),
|
||||
_stat = null;
|
||||
|
||||
function newAttr() {
|
||||
return {
|
||||
directory: false,
|
||||
readonly: false,
|
||||
hidden: false,
|
||||
executable: false,
|
||||
mtime: 0,
|
||||
atime: 0
|
||||
};
|
||||
}
|
||||
|
||||
if (_path && fs.existsSync(_path)) {
|
||||
_stat = fs.statSync(_path);
|
||||
_obj.directory = _stat.isDirectory();
|
||||
_obj.mtime = _stat.mtime;
|
||||
_obj.atime = _stat.atime;
|
||||
_obj.executable = (0o111 & _stat.mode) !== 0; // file is executable who ever har right not just owner
|
||||
_obj.readonly = (0o200 & _stat.mode) === 0; // readonly if owner has no write right
|
||||
_obj.hidden = pth.basename(_path)[0] === ".";
|
||||
} else {
|
||||
console.warn("Invalid path: " + _path);
|
||||
}
|
||||
|
||||
return {
|
||||
get directory() {
|
||||
return _obj.directory;
|
||||
},
|
||||
|
||||
get readOnly() {
|
||||
return _obj.readonly;
|
||||
},
|
||||
|
||||
get hidden() {
|
||||
return _obj.hidden;
|
||||
},
|
||||
|
||||
get mtime() {
|
||||
return _obj.mtime;
|
||||
},
|
||||
|
||||
get atime() {
|
||||
return _obj.atime;
|
||||
},
|
||||
|
||||
get executable() {
|
||||
return _obj.executable;
|
||||
},
|
||||
|
||||
decodeAttributes: function () {},
|
||||
|
||||
encodeAttributes: function () {},
|
||||
|
||||
toJSON: function () {
|
||||
return {
|
||||
path: _path,
|
||||
isDirectory: _obj.directory,
|
||||
isReadOnly: _obj.readonly,
|
||||
isHidden: _obj.hidden,
|
||||
isExecutable: _obj.executable,
|
||||
mTime: _obj.mtime,
|
||||
aTime: _obj.atime
|
||||
};
|
||||
},
|
||||
|
||||
toString: function () {
|
||||
return JSON.stringify(this.toJSON(), null, "\t");
|
||||
}
|
||||
};
|
||||
};
|
||||
11
_shared/lib/adm-zip/util/fileSystem.js
Normal file
11
_shared/lib/adm-zip/util/fileSystem.js
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
exports.require = function () {
|
||||
if (typeof process === "object" && process.versions && process.versions["electron"]) {
|
||||
try {
|
||||
const originalFs = require("original-fs");
|
||||
if (Object.keys(originalFs).length > 0) {
|
||||
return originalFs;
|
||||
}
|
||||
} catch (e) {}
|
||||
}
|
||||
return require("fs");
|
||||
};
|
||||
4
_shared/lib/adm-zip/util/index.js
Normal file
4
_shared/lib/adm-zip/util/index.js
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
module.exports = require("./utils");
|
||||
module.exports.Constants = require("./constants");
|
||||
module.exports.Errors = require("./errors");
|
||||
module.exports.FileAttr = require("./fattr");
|
||||
247
_shared/lib/adm-zip/util/utils.js
Normal file
247
_shared/lib/adm-zip/util/utils.js
Normal file
|
|
@ -0,0 +1,247 @@
|
|||
const fsystem = require("./fileSystem").require();
|
||||
const pth = require("path");
|
||||
const Constants = require("./constants");
|
||||
const Errors = require("./errors");
|
||||
const isWin = typeof process === "object" && "win32" === process.platform;
|
||||
|
||||
const is_Obj = (obj) => obj && typeof obj === "object";
|
||||
|
||||
// generate CRC32 lookup table
|
||||
const crcTable = new Uint32Array(256).map((t, c) => {
|
||||
for (let k = 0; k < 8; k++) {
|
||||
if ((c & 1) !== 0) {
|
||||
c = 0xedb88320 ^ (c >>> 1);
|
||||
} else {
|
||||
c >>>= 1;
|
||||
}
|
||||
}
|
||||
return c >>> 0;
|
||||
});
|
||||
|
||||
// UTILS functions
|
||||
|
||||
function Utils(opts) {
|
||||
this.sep = pth.sep;
|
||||
this.fs = fsystem;
|
||||
|
||||
if (is_Obj(opts)) {
|
||||
// custom filesystem
|
||||
if (is_Obj(opts.fs) && typeof opts.fs.statSync === "function") {
|
||||
this.fs = opts.fs;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Utils;
|
||||
|
||||
// INSTANCED functions
|
||||
|
||||
Utils.prototype.makeDir = function (/*String*/ folder) {
|
||||
const self = this;
|
||||
|
||||
// Sync - make directories tree
|
||||
function mkdirSync(/*String*/ fpath) {
|
||||
let resolvedPath = fpath.split(self.sep)[0];
|
||||
fpath.split(self.sep).forEach(function (name) {
|
||||
if (!name || name.substr(-1, 1) === ":") return;
|
||||
resolvedPath += self.sep + name;
|
||||
var stat;
|
||||
try {
|
||||
stat = self.fs.statSync(resolvedPath);
|
||||
} catch (e) {
|
||||
self.fs.mkdirSync(resolvedPath);
|
||||
}
|
||||
if (stat && stat.isFile()) throw Errors.FILE_IN_THE_WAY.replace("%s", resolvedPath);
|
||||
});
|
||||
}
|
||||
|
||||
mkdirSync(folder);
|
||||
};
|
||||
|
||||
Utils.prototype.writeFileTo = function (/*String*/ path, /*Buffer*/ content, /*Boolean*/ overwrite, /*Number*/ attr) {
|
||||
const self = this;
|
||||
if (self.fs.existsSync(path)) {
|
||||
if (!overwrite) return false; // cannot overwrite
|
||||
|
||||
var stat = self.fs.statSync(path);
|
||||
if (stat.isDirectory()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
var folder = pth.dirname(path);
|
||||
if (!self.fs.existsSync(folder)) {
|
||||
self.makeDir(folder);
|
||||
}
|
||||
|
||||
var fd;
|
||||
try {
|
||||
fd = self.fs.openSync(path, "w", 438); // 0666
|
||||
} catch (e) {
|
||||
self.fs.chmodSync(path, 438);
|
||||
fd = self.fs.openSync(path, "w", 438);
|
||||
}
|
||||
if (fd) {
|
||||
try {
|
||||
self.fs.writeSync(fd, content, 0, content.length, 0);
|
||||
} finally {
|
||||
self.fs.closeSync(fd);
|
||||
}
|
||||
}
|
||||
self.fs.chmodSync(path, attr || 438);
|
||||
return true;
|
||||
};
|
||||
|
||||
Utils.prototype.writeFileToAsync = function (/*String*/ path, /*Buffer*/ content, /*Boolean*/ overwrite, /*Number*/ attr, /*Function*/ callback) {
|
||||
if (typeof attr === "function") {
|
||||
callback = attr;
|
||||
attr = undefined;
|
||||
}
|
||||
|
||||
const self = this;
|
||||
|
||||
self.fs.exists(path, function (exist) {
|
||||
if (exist && !overwrite) return callback(false);
|
||||
|
||||
self.fs.stat(path, function (err, stat) {
|
||||
if (exist && stat.isDirectory()) {
|
||||
return callback(false);
|
||||
}
|
||||
|
||||
var folder = pth.dirname(path);
|
||||
self.fs.exists(folder, function (exists) {
|
||||
if (!exists) self.makeDir(folder);
|
||||
|
||||
self.fs.open(path, "w", 438, function (err, fd) {
|
||||
if (err) {
|
||||
self.fs.chmod(path, 438, function () {
|
||||
self.fs.open(path, "w", 438, function (err, fd) {
|
||||
self.fs.write(fd, content, 0, content.length, 0, function () {
|
||||
self.fs.close(fd, function () {
|
||||
self.fs.chmod(path, attr || 438, function () {
|
||||
callback(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
} else if (fd) {
|
||||
self.fs.write(fd, content, 0, content.length, 0, function () {
|
||||
self.fs.close(fd, function () {
|
||||
self.fs.chmod(path, attr || 438, function () {
|
||||
callback(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
} else {
|
||||
self.fs.chmod(path, attr || 438, function () {
|
||||
callback(true);
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
Utils.prototype.findFiles = function (/*String*/ path) {
|
||||
const self = this;
|
||||
|
||||
function findSync(/*String*/ dir, /*RegExp*/ pattern, /*Boolean*/ recursive) {
|
||||
if (typeof pattern === "boolean") {
|
||||
recursive = pattern;
|
||||
pattern = undefined;
|
||||
}
|
||||
let files = [];
|
||||
self.fs.readdirSync(dir).forEach(function (file) {
|
||||
var path = pth.join(dir, file);
|
||||
|
||||
if (self.fs.statSync(path).isDirectory() && recursive) files = files.concat(findSync(path, pattern, recursive));
|
||||
|
||||
if (!pattern || pattern.test(path)) {
|
||||
files.push(pth.normalize(path) + (self.fs.statSync(path).isDirectory() ? self.sep : ""));
|
||||
}
|
||||
});
|
||||
return files;
|
||||
}
|
||||
|
||||
return findSync(path, undefined, true);
|
||||
};
|
||||
|
||||
Utils.prototype.getAttributes = function () {};
|
||||
|
||||
Utils.prototype.setAttributes = function () {};
|
||||
|
||||
// STATIC functions
|
||||
|
||||
// crc32 single update (it is part of crc32)
|
||||
Utils.crc32update = function (crc, byte) {
|
||||
return crcTable[(crc ^ byte) & 0xff] ^ (crc >>> 8);
|
||||
};
|
||||
|
||||
Utils.crc32 = function (buf) {
|
||||
if (typeof buf === "string") {
|
||||
buf = Buffer.from(buf, "utf8");
|
||||
}
|
||||
// Generate crcTable
|
||||
if (!crcTable.length) genCRCTable();
|
||||
|
||||
let len = buf.length;
|
||||
let crc = ~0;
|
||||
for (let off = 0; off < len; ) crc = Utils.crc32update(crc, buf[off++]);
|
||||
// xor and cast as uint32 number
|
||||
return ~crc >>> 0;
|
||||
};
|
||||
|
||||
Utils.methodToString = function (/*Number*/ method) {
|
||||
switch (method) {
|
||||
case Constants.STORED:
|
||||
return "STORED (" + method + ")";
|
||||
case Constants.DEFLATED:
|
||||
return "DEFLATED (" + method + ")";
|
||||
default:
|
||||
return "UNSUPPORTED (" + method + ")";
|
||||
}
|
||||
};
|
||||
|
||||
// removes ".." style path elements
|
||||
Utils.canonical = function (/*string*/ path) {
|
||||
if (!path) return "";
|
||||
// trick normalize think path is absolute
|
||||
var safeSuffix = pth.posix.normalize("/" + path.split("\\").join("/"));
|
||||
return pth.join(".", safeSuffix);
|
||||
};
|
||||
|
||||
// make abolute paths taking prefix as root folder
|
||||
Utils.sanitize = function (/*string*/ prefix, /*string*/ name) {
|
||||
prefix = pth.resolve(pth.normalize(prefix));
|
||||
var parts = name.split("/");
|
||||
for (var i = 0, l = parts.length; i < l; i++) {
|
||||
var path = pth.normalize(pth.join(prefix, parts.slice(i, l).join(pth.sep)));
|
||||
if (path.indexOf(prefix) === 0) {
|
||||
return path;
|
||||
}
|
||||
}
|
||||
return pth.normalize(pth.join(prefix, pth.basename(name)));
|
||||
};
|
||||
|
||||
// converts buffer, Uint8Array, string types to buffer
|
||||
Utils.toBuffer = function toBuffer(/*buffer, Uint8Array, string*/ input) {
|
||||
if (Buffer.isBuffer(input)) {
|
||||
return input;
|
||||
} else if (input instanceof Uint8Array) {
|
||||
return Buffer.from(input);
|
||||
} else {
|
||||
// expect string all other values are invalid and return empty buffer
|
||||
return typeof input === "string" ? Buffer.from(input, "utf8") : Buffer.alloc(0);
|
||||
}
|
||||
};
|
||||
|
||||
Utils.readBigUInt64LE = function (/*Buffer*/ buffer, /*int*/ index) {
|
||||
var slice = Buffer.from(buffer.slice(index, index + 8));
|
||||
slice.swap64();
|
||||
|
||||
return parseInt(`0x${slice.toString("hex")}`);
|
||||
};
|
||||
|
||||
Utils.isWin = isWin; // Do we have windows system
|
||||
Utils.crcTable = crcTable;
|
||||
333
_shared/lib/adm-zip/zipEntry.js
Normal file
333
_shared/lib/adm-zip/zipEntry.js
Normal file
|
|
@ -0,0 +1,333 @@
|
|||
var Utils = require("./util"),
|
||||
Headers = require("./headers"),
|
||||
Constants = Utils.Constants,
|
||||
Methods = require("./methods");
|
||||
|
||||
module.exports = function (/*Buffer*/ input) {
|
||||
var _entryHeader = new Headers.EntryHeader(),
|
||||
_entryName = Buffer.alloc(0),
|
||||
_comment = Buffer.alloc(0),
|
||||
_isDirectory = false,
|
||||
uncompressedData = null,
|
||||
_extra = Buffer.alloc(0);
|
||||
|
||||
function getCompressedDataFromZip() {
|
||||
if (!input || !Buffer.isBuffer(input)) {
|
||||
return Buffer.alloc(0);
|
||||
}
|
||||
_entryHeader.loadDataHeaderFromBinary(input);
|
||||
return input.slice(_entryHeader.realDataOffset, _entryHeader.realDataOffset + _entryHeader.compressedSize);
|
||||
}
|
||||
|
||||
function crc32OK(data) {
|
||||
// if bit 3 (0x08) of the general-purpose flags field is set, then the CRC-32 and file sizes are not known when the header is written
|
||||
if ((_entryHeader.flags & 0x8) !== 0x8) {
|
||||
if (Utils.crc32(data) !== _entryHeader.dataHeader.crc) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
// @TODO: load and check data descriptor header
|
||||
// The fields in the local header are filled with zero, and the CRC-32 and size are appended in a 12-byte structure
|
||||
// (optionally preceded by a 4-byte signature) immediately after the compressed data:
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function decompress(/*Boolean*/ async, /*Function*/ callback, /*String, Buffer*/ pass) {
|
||||
if (typeof callback === "undefined" && typeof async === "string") {
|
||||
pass = async;
|
||||
async = void 0;
|
||||
}
|
||||
if (_isDirectory) {
|
||||
if (async && callback) {
|
||||
callback(Buffer.alloc(0), Utils.Errors.DIRECTORY_CONTENT_ERROR); //si added error.
|
||||
}
|
||||
return Buffer.alloc(0);
|
||||
}
|
||||
|
||||
var compressedData = getCompressedDataFromZip();
|
||||
|
||||
if (compressedData.length === 0) {
|
||||
// File is empty, nothing to decompress.
|
||||
if (async && callback) callback(compressedData);
|
||||
return compressedData;
|
||||
}
|
||||
|
||||
if (_entryHeader.encripted) {
|
||||
if ("string" !== typeof pass && !Buffer.isBuffer(pass)) {
|
||||
throw new Error("ADM-ZIP: Incompatible password parameter");
|
||||
}
|
||||
compressedData = Methods.ZipCrypto.decrypt(compressedData, _entryHeader, pass);
|
||||
}
|
||||
|
||||
var data = Buffer.alloc(_entryHeader.size);
|
||||
|
||||
switch (_entryHeader.method) {
|
||||
case Utils.Constants.STORED:
|
||||
compressedData.copy(data);
|
||||
if (!crc32OK(data)) {
|
||||
if (async && callback) callback(data, Utils.Errors.BAD_CRC); //si added error
|
||||
throw new Error(Utils.Errors.BAD_CRC);
|
||||
} else {
|
||||
//si added otherwise did not seem to return data.
|
||||
if (async && callback) callback(data);
|
||||
return data;
|
||||
}
|
||||
case Utils.Constants.DEFLATED:
|
||||
var inflater = new Methods.Inflater(compressedData);
|
||||
if (!async) {
|
||||
const result = inflater.inflate(data);
|
||||
result.copy(data, 0);
|
||||
if (!crc32OK(data)) {
|
||||
throw new Error(Utils.Errors.BAD_CRC + " " + _entryName.toString());
|
||||
}
|
||||
return data;
|
||||
} else {
|
||||
inflater.inflateAsync(function (result) {
|
||||
result.copy(result, 0);
|
||||
if (callback) {
|
||||
if (!crc32OK(result)) {
|
||||
callback(result, Utils.Errors.BAD_CRC); //si added error
|
||||
} else {
|
||||
callback(result);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (async && callback) callback(Buffer.alloc(0), Utils.Errors.UNKNOWN_METHOD);
|
||||
throw new Error(Utils.Errors.UNKNOWN_METHOD);
|
||||
}
|
||||
}
|
||||
|
||||
function compress(/*Boolean*/ async, /*Function*/ callback) {
|
||||
if ((!uncompressedData || !uncompressedData.length) && Buffer.isBuffer(input)) {
|
||||
// no data set or the data wasn't changed to require recompression
|
||||
if (async && callback) callback(getCompressedDataFromZip());
|
||||
return getCompressedDataFromZip();
|
||||
}
|
||||
|
||||
if (uncompressedData.length && !_isDirectory) {
|
||||
var compressedData;
|
||||
// Local file header
|
||||
switch (_entryHeader.method) {
|
||||
case Utils.Constants.STORED:
|
||||
_entryHeader.compressedSize = _entryHeader.size;
|
||||
|
||||
compressedData = Buffer.alloc(uncompressedData.length);
|
||||
uncompressedData.copy(compressedData);
|
||||
|
||||
if (async && callback) callback(compressedData);
|
||||
return compressedData;
|
||||
default:
|
||||
case Utils.Constants.DEFLATED:
|
||||
var deflater = new Methods.Deflater(uncompressedData);
|
||||
if (!async) {
|
||||
var deflated = deflater.deflate();
|
||||
_entryHeader.compressedSize = deflated.length;
|
||||
return deflated;
|
||||
} else {
|
||||
deflater.deflateAsync(function (data) {
|
||||
compressedData = Buffer.alloc(data.length);
|
||||
_entryHeader.compressedSize = data.length;
|
||||
data.copy(compressedData);
|
||||
callback && callback(compressedData);
|
||||
});
|
||||
}
|
||||
deflater = null;
|
||||
break;
|
||||
}
|
||||
} else if (async && callback) {
|
||||
callback(Buffer.alloc(0));
|
||||
} else {
|
||||
return Buffer.alloc(0);
|
||||
}
|
||||
}
|
||||
|
||||
function readUInt64LE(buffer, offset) {
|
||||
return (buffer.readUInt32LE(offset + 4) << 4) + buffer.readUInt32LE(offset);
|
||||
}
|
||||
|
||||
function parseExtra(data) {
|
||||
var offset = 0;
|
||||
var signature, size, part;
|
||||
while (offset < data.length) {
|
||||
signature = data.readUInt16LE(offset);
|
||||
offset += 2;
|
||||
size = data.readUInt16LE(offset);
|
||||
offset += 2;
|
||||
part = data.slice(offset, offset + size);
|
||||
offset += size;
|
||||
if (Constants.ID_ZIP64 === signature) {
|
||||
parseZip64ExtendedInformation(part);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Override header field values with values from the ZIP64 extra field
|
||||
function parseZip64ExtendedInformation(data) {
|
||||
var size, compressedSize, offset, diskNumStart;
|
||||
|
||||
if (data.length >= Constants.EF_ZIP64_SCOMP) {
|
||||
size = readUInt64LE(data, Constants.EF_ZIP64_SUNCOMP);
|
||||
if (_entryHeader.size === Constants.EF_ZIP64_OR_32) {
|
||||
_entryHeader.size = size;
|
||||
}
|
||||
}
|
||||
if (data.length >= Constants.EF_ZIP64_RHO) {
|
||||
compressedSize = readUInt64LE(data, Constants.EF_ZIP64_SCOMP);
|
||||
if (_entryHeader.compressedSize === Constants.EF_ZIP64_OR_32) {
|
||||
_entryHeader.compressedSize = compressedSize;
|
||||
}
|
||||
}
|
||||
if (data.length >= Constants.EF_ZIP64_DSN) {
|
||||
offset = readUInt64LE(data, Constants.EF_ZIP64_RHO);
|
||||
if (_entryHeader.offset === Constants.EF_ZIP64_OR_32) {
|
||||
_entryHeader.offset = offset;
|
||||
}
|
||||
}
|
||||
if (data.length >= Constants.EF_ZIP64_DSN + 4) {
|
||||
diskNumStart = data.readUInt32LE(Constants.EF_ZIP64_DSN);
|
||||
if (_entryHeader.diskNumStart === Constants.EF_ZIP64_OR_16) {
|
||||
_entryHeader.diskNumStart = diskNumStart;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
get entryName() {
|
||||
return _entryName.toString();
|
||||
},
|
||||
get rawEntryName() {
|
||||
return _entryName;
|
||||
},
|
||||
set entryName(val) {
|
||||
_entryName = Utils.toBuffer(val);
|
||||
var lastChar = _entryName[_entryName.length - 1];
|
||||
_isDirectory = lastChar === 47 || lastChar === 92;
|
||||
_entryHeader.fileNameLength = _entryName.length;
|
||||
},
|
||||
|
||||
get extra() {
|
||||
return _extra;
|
||||
},
|
||||
set extra(val) {
|
||||
_extra = val;
|
||||
_entryHeader.extraLength = val.length;
|
||||
parseExtra(val);
|
||||
},
|
||||
|
||||
get comment() {
|
||||
return _comment.toString();
|
||||
},
|
||||
set comment(val) {
|
||||
_comment = Utils.toBuffer(val);
|
||||
_entryHeader.commentLength = _comment.length;
|
||||
},
|
||||
|
||||
get name() {
|
||||
var n = _entryName.toString();
|
||||
return _isDirectory
|
||||
? n
|
||||
.substr(n.length - 1)
|
||||
.split("/")
|
||||
.pop()
|
||||
: n.split("/").pop();
|
||||
},
|
||||
get isDirectory() {
|
||||
return _isDirectory;
|
||||
},
|
||||
|
||||
getCompressedData: function () {
|
||||
return compress(false, null);
|
||||
},
|
||||
|
||||
getCompressedDataAsync: function (/*Function*/ callback) {
|
||||
compress(true, callback);
|
||||
},
|
||||
|
||||
setData: function (value) {
|
||||
uncompressedData = Utils.toBuffer(value);
|
||||
if (!_isDirectory && uncompressedData.length) {
|
||||
_entryHeader.size = uncompressedData.length;
|
||||
_entryHeader.method = Utils.Constants.DEFLATED;
|
||||
_entryHeader.crc = Utils.crc32(value);
|
||||
_entryHeader.changed = true;
|
||||
} else {
|
||||
// folders and blank files should be stored
|
||||
_entryHeader.method = Utils.Constants.STORED;
|
||||
}
|
||||
},
|
||||
|
||||
getData: function (pass) {
|
||||
if (_entryHeader.changed) {
|
||||
return uncompressedData;
|
||||
} else {
|
||||
return decompress(false, null, pass);
|
||||
}
|
||||
},
|
||||
|
||||
getDataAsync: function (/*Function*/ callback, pass) {
|
||||
if (_entryHeader.changed) {
|
||||
callback(uncompressedData);
|
||||
} else {
|
||||
decompress(true, callback, pass);
|
||||
}
|
||||
},
|
||||
|
||||
set attr(attr) {
|
||||
_entryHeader.attr = attr;
|
||||
},
|
||||
get attr() {
|
||||
return _entryHeader.attr;
|
||||
},
|
||||
|
||||
set header(/*Buffer*/ data) {
|
||||
_entryHeader.loadFromBinary(data);
|
||||
},
|
||||
|
||||
get header() {
|
||||
return _entryHeader;
|
||||
},
|
||||
|
||||
packHeader: function () {
|
||||
// 1. create header (buffer)
|
||||
var header = _entryHeader.entryHeaderToBinary();
|
||||
var addpos = Utils.Constants.CENHDR;
|
||||
// 2. add file name
|
||||
_entryName.copy(header, addpos);
|
||||
addpos += _entryName.length;
|
||||
// 3. add extra data
|
||||
if (_entryHeader.extraLength) {
|
||||
_extra.copy(header, addpos);
|
||||
addpos += _entryHeader.extraLength;
|
||||
}
|
||||
// 4. add file comment
|
||||
if (_entryHeader.commentLength) {
|
||||
_comment.copy(header, addpos);
|
||||
}
|
||||
return header;
|
||||
},
|
||||
|
||||
toJSON: function () {
|
||||
const bytes = function (nr) {
|
||||
return "<" + ((nr && nr.length + " bytes buffer") || "null") + ">";
|
||||
};
|
||||
|
||||
return {
|
||||
entryName: this.entryName,
|
||||
name: this.name,
|
||||
comment: this.comment,
|
||||
isDirectory: this.isDirectory,
|
||||
header: _entryHeader.toJSON(),
|
||||
compressedData: bytes(input),
|
||||
data: bytes(uncompressedData)
|
||||
};
|
||||
},
|
||||
|
||||
toString: function () {
|
||||
return JSON.stringify(this.toJSON(), null, "\t");
|
||||
}
|
||||
};
|
||||
};
|
||||
384
_shared/lib/adm-zip/zipFile.js
Normal file
384
_shared/lib/adm-zip/zipFile.js
Normal file
|
|
@ -0,0 +1,384 @@
|
|||
const ZipEntry = require("./zipEntry");
|
||||
const Headers = require("./headers");
|
||||
const Utils = require("./util");
|
||||
|
||||
module.exports = function (/*Buffer|null*/ inBuffer, /** object */ options) {
|
||||
var entryList = [],
|
||||
entryTable = {},
|
||||
_comment = Buffer.alloc(0),
|
||||
mainHeader = new Headers.MainHeader(),
|
||||
loadedEntries = false;
|
||||
|
||||
// assign options
|
||||
const opts = Object.assign(Object.create(null), options);
|
||||
|
||||
const { noSort } = opts;
|
||||
|
||||
if (inBuffer) {
|
||||
// is a memory buffer
|
||||
readMainHeader(opts.readEntries);
|
||||
} else {
|
||||
// none. is a new file
|
||||
loadedEntries = true;
|
||||
}
|
||||
|
||||
function iterateEntries(callback) {
|
||||
const totalEntries = mainHeader.diskEntries; // total number of entries
|
||||
let index = mainHeader.offset; // offset of first CEN header
|
||||
|
||||
for (let i = 0; i < totalEntries; i++) {
|
||||
let tmp = index;
|
||||
const entry = new ZipEntry(inBuffer);
|
||||
|
||||
entry.header = inBuffer.slice(tmp, (tmp += Utils.Constants.CENHDR));
|
||||
entry.entryName = inBuffer.slice(tmp, (tmp += entry.header.fileNameLength));
|
||||
|
||||
index += entry.header.entryHeaderSize;
|
||||
|
||||
callback(entry);
|
||||
}
|
||||
}
|
||||
|
||||
function readEntries() {
|
||||
loadedEntries = true;
|
||||
entryTable = {};
|
||||
entryList = new Array(mainHeader.diskEntries); // total number of entries
|
||||
var index = mainHeader.offset; // offset of first CEN header
|
||||
for (var i = 0; i < entryList.length; i++) {
|
||||
var tmp = index,
|
||||
entry = new ZipEntry(inBuffer);
|
||||
entry.header = inBuffer.slice(tmp, (tmp += Utils.Constants.CENHDR));
|
||||
|
||||
entry.entryName = inBuffer.slice(tmp, (tmp += entry.header.fileNameLength));
|
||||
|
||||
if (entry.header.extraLength) {
|
||||
entry.extra = inBuffer.slice(tmp, (tmp += entry.header.extraLength));
|
||||
}
|
||||
|
||||
if (entry.header.commentLength) entry.comment = inBuffer.slice(tmp, tmp + entry.header.commentLength);
|
||||
|
||||
index += entry.header.entryHeaderSize;
|
||||
|
||||
entryList[i] = entry;
|
||||
entryTable[entry.entryName] = entry;
|
||||
}
|
||||
}
|
||||
|
||||
function readMainHeader(/*Boolean*/ readNow) {
|
||||
var i = inBuffer.length - Utils.Constants.ENDHDR, // END header size
|
||||
max = Math.max(0, i - 0xffff), // 0xFFFF is the max zip file comment length
|
||||
n = max,
|
||||
endStart = inBuffer.length,
|
||||
endOffset = -1, // Start offset of the END header
|
||||
commentEnd = 0;
|
||||
|
||||
for (i; i >= n; i--) {
|
||||
if (inBuffer[i] !== 0x50) continue; // quick check that the byte is 'P'
|
||||
if (inBuffer.readUInt32LE(i) === Utils.Constants.ENDSIG) {
|
||||
// "PK\005\006"
|
||||
endOffset = i;
|
||||
commentEnd = i;
|
||||
endStart = i + Utils.Constants.ENDHDR;
|
||||
// We already found a regular signature, let's look just a bit further to check if there's any zip64 signature
|
||||
n = i - Utils.Constants.END64HDR;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (inBuffer.readUInt32LE(i) === Utils.Constants.END64SIG) {
|
||||
// Found a zip64 signature, let's continue reading the whole zip64 record
|
||||
n = max;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (inBuffer.readUInt32LE(i) === Utils.Constants.ZIP64SIG) {
|
||||
// Found the zip64 record, let's determine it's size
|
||||
endOffset = i;
|
||||
endStart = i + Utils.readBigUInt64LE(inBuffer, i + Utils.Constants.ZIP64SIZE) + Utils.Constants.ZIP64LEAD;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!~endOffset) throw new Error(Utils.Errors.INVALID_FORMAT);
|
||||
|
||||
mainHeader.loadFromBinary(inBuffer.slice(endOffset, endStart));
|
||||
if (mainHeader.commentLength) {
|
||||
_comment = inBuffer.slice(commentEnd + Utils.Constants.ENDHDR);
|
||||
}
|
||||
if (readNow) readEntries();
|
||||
}
|
||||
|
||||
function sortEntries() {
|
||||
if (entryList.length > 1 && !noSort) {
|
||||
entryList.sort((a, b) => a.entryName.toLowerCase().localeCompare(b.entryName.toLowerCase()));
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
/**
|
||||
* Returns an array of ZipEntry objects existent in the current opened archive
|
||||
* @return Array
|
||||
*/
|
||||
get entries() {
|
||||
if (!loadedEntries) {
|
||||
readEntries();
|
||||
}
|
||||
return entryList;
|
||||
},
|
||||
|
||||
/**
|
||||
* Archive comment
|
||||
* @return {String}
|
||||
*/
|
||||
get comment() {
|
||||
return _comment.toString();
|
||||
},
|
||||
set comment(val) {
|
||||
_comment = Utils.toBuffer(val);
|
||||
mainHeader.commentLength = _comment.length;
|
||||
},
|
||||
|
||||
getEntryCount: function () {
|
||||
if (!loadedEntries) {
|
||||
return mainHeader.diskEntries;
|
||||
}
|
||||
|
||||
return entryList.length;
|
||||
},
|
||||
|
||||
forEach: function (callback) {
|
||||
if (!loadedEntries) {
|
||||
iterateEntries(callback);
|
||||
return;
|
||||
}
|
||||
|
||||
entryList.forEach(callback);
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns a reference to the entry with the given name or null if entry is inexistent
|
||||
*
|
||||
* @param entryName
|
||||
* @return ZipEntry
|
||||
*/
|
||||
getEntry: function (/*String*/ entryName) {
|
||||
if (!loadedEntries) {
|
||||
readEntries();
|
||||
}
|
||||
return entryTable[entryName] || null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Adds the given entry to the entry list
|
||||
*
|
||||
* @param entry
|
||||
*/
|
||||
setEntry: function (/*ZipEntry*/ entry) {
|
||||
if (!loadedEntries) {
|
||||
readEntries();
|
||||
}
|
||||
entryList.push(entry);
|
||||
entryTable[entry.entryName] = entry;
|
||||
mainHeader.totalEntries = entryList.length;
|
||||
},
|
||||
|
||||
/**
|
||||
* Removes the entry with the given name from the entry list.
|
||||
*
|
||||
* If the entry is a directory, then all nested files and directories will be removed
|
||||
* @param entryName
|
||||
*/
|
||||
deleteEntry: function (/*String*/ entryName) {
|
||||
if (!loadedEntries) {
|
||||
readEntries();
|
||||
}
|
||||
var entry = entryTable[entryName];
|
||||
if (entry && entry.isDirectory) {
|
||||
var _self = this;
|
||||
this.getEntryChildren(entry).forEach(function (child) {
|
||||
if (child.entryName !== entryName) {
|
||||
_self.deleteEntry(child.entryName);
|
||||
}
|
||||
});
|
||||
}
|
||||
entryList.splice(entryList.indexOf(entry), 1);
|
||||
delete entryTable[entryName];
|
||||
mainHeader.totalEntries = entryList.length;
|
||||
},
|
||||
|
||||
/**
|
||||
* Iterates and returns all nested files and directories of the given entry
|
||||
*
|
||||
* @param entry
|
||||
* @return Array
|
||||
*/
|
||||
getEntryChildren: function (/*ZipEntry*/ entry) {
|
||||
if (!loadedEntries) {
|
||||
readEntries();
|
||||
}
|
||||
if (entry && entry.isDirectory) {
|
||||
const list = [];
|
||||
const name = entry.entryName;
|
||||
const len = name.length;
|
||||
|
||||
entryList.forEach(function (zipEntry) {
|
||||
if (zipEntry.entryName.substr(0, len) === name) {
|
||||
list.push(zipEntry);
|
||||
}
|
||||
});
|
||||
return list;
|
||||
}
|
||||
return [];
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the zip file
|
||||
*
|
||||
* @return Buffer
|
||||
*/
|
||||
compressToBuffer: function () {
|
||||
if (!loadedEntries) {
|
||||
readEntries();
|
||||
}
|
||||
sortEntries();
|
||||
|
||||
const dataBlock = [];
|
||||
const entryHeaders = [];
|
||||
let totalSize = 0;
|
||||
let dindex = 0;
|
||||
|
||||
mainHeader.size = 0;
|
||||
mainHeader.offset = 0;
|
||||
|
||||
for (const entry of entryList) {
|
||||
// compress data and set local and entry header accordingly. Reason why is called first
|
||||
const compressedData = entry.getCompressedData();
|
||||
// 1. construct data header
|
||||
entry.header.offset = dindex;
|
||||
const dataHeader = entry.header.dataHeaderToBinary();
|
||||
const entryNameLen = entry.rawEntryName.length;
|
||||
// 1.2. postheader - data after data header
|
||||
const postHeader = Buffer.alloc(entryNameLen + entry.extra.length);
|
||||
entry.rawEntryName.copy(postHeader, 0);
|
||||
postHeader.copy(entry.extra, entryNameLen);
|
||||
|
||||
// 2. offsets
|
||||
const dataLength = dataHeader.length + postHeader.length + compressedData.length;
|
||||
dindex += dataLength;
|
||||
|
||||
// 3. store values in sequence
|
||||
dataBlock.push(dataHeader);
|
||||
dataBlock.push(postHeader);
|
||||
dataBlock.push(compressedData);
|
||||
|
||||
// 4. construct entry header
|
||||
const entryHeader = entry.packHeader();
|
||||
entryHeaders.push(entryHeader);
|
||||
// 5. update main header
|
||||
mainHeader.size += entryHeader.length;
|
||||
totalSize += dataLength + entryHeader.length;
|
||||
}
|
||||
|
||||
totalSize += mainHeader.mainHeaderSize; // also includes zip file comment length
|
||||
// point to end of data and beginning of central directory first record
|
||||
mainHeader.offset = dindex;
|
||||
|
||||
dindex = 0;
|
||||
const outBuffer = Buffer.alloc(totalSize);
|
||||
// write data blocks
|
||||
for (const content of dataBlock) {
|
||||
content.copy(outBuffer, dindex);
|
||||
dindex += content.length;
|
||||
}
|
||||
|
||||
// write central directory entries
|
||||
for (const content of entryHeaders) {
|
||||
content.copy(outBuffer, dindex);
|
||||
dindex += content.length;
|
||||
}
|
||||
|
||||
// write main header
|
||||
const mh = mainHeader.toBinary();
|
||||
if (_comment) {
|
||||
_comment.copy(mh, Utils.Constants.ENDHDR); // add zip file comment
|
||||
}
|
||||
mh.copy(outBuffer, dindex);
|
||||
|
||||
return outBuffer;
|
||||
},
|
||||
|
||||
toAsyncBuffer: function (/*Function*/ onSuccess, /*Function*/ onFail, /*Function*/ onItemStart, /*Function*/ onItemEnd) {
|
||||
try {
|
||||
if (!loadedEntries) {
|
||||
readEntries();
|
||||
}
|
||||
sortEntries();
|
||||
|
||||
const dataBlock = [];
|
||||
const entryHeaders = [];
|
||||
let totalSize = 0;
|
||||
let dindex = 0;
|
||||
|
||||
mainHeader.size = 0;
|
||||
mainHeader.offset = 0;
|
||||
|
||||
const compress2Buffer = function (entryLists) {
|
||||
if (entryLists.length) {
|
||||
const entry = entryLists.pop();
|
||||
const name = entry.entryName + entry.extra.toString();
|
||||
if (onItemStart) onItemStart(name);
|
||||
entry.getCompressedDataAsync(function (compressedData) {
|
||||
if (onItemEnd) onItemEnd(name);
|
||||
|
||||
entry.header.offset = dindex;
|
||||
// data header
|
||||
const dataHeader = entry.header.dataHeaderToBinary();
|
||||
const postHeader = Buffer.alloc(name.length, name);
|
||||
const dataLength = dataHeader.length + postHeader.length + compressedData.length;
|
||||
|
||||
dindex += dataLength;
|
||||
|
||||
dataBlock.push(dataHeader);
|
||||
dataBlock.push(postHeader);
|
||||
dataBlock.push(compressedData);
|
||||
|
||||
const entryHeader = entry.packHeader();
|
||||
entryHeaders.push(entryHeader);
|
||||
mainHeader.size += entryHeader.length;
|
||||
totalSize += dataLength + entryHeader.length;
|
||||
|
||||
compress2Buffer(entryLists);
|
||||
});
|
||||
} else {
|
||||
totalSize += mainHeader.mainHeaderSize; // also includes zip file comment length
|
||||
// point to end of data and beginning of central directory first record
|
||||
mainHeader.offset = dindex;
|
||||
|
||||
dindex = 0;
|
||||
const outBuffer = Buffer.alloc(totalSize);
|
||||
dataBlock.forEach(function (content) {
|
||||
content.copy(outBuffer, dindex); // write data blocks
|
||||
dindex += content.length;
|
||||
});
|
||||
entryHeaders.forEach(function (content) {
|
||||
content.copy(outBuffer, dindex); // write central directory entries
|
||||
dindex += content.length;
|
||||
});
|
||||
|
||||
const mh = mainHeader.toBinary();
|
||||
if (_comment) {
|
||||
_comment.copy(mh, Utils.Constants.ENDHDR); // add zip file comment
|
||||
}
|
||||
|
||||
mh.copy(outBuffer, dindex); // write main header
|
||||
|
||||
onSuccess(outBuffer);
|
||||
}
|
||||
};
|
||||
|
||||
compress2Buffer(entryList);
|
||||
} catch (e) {
|
||||
onFail(e);
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
219
_shared/lib/node-fetch/@types/index.d.ts
vendored
Normal file
219
_shared/lib/node-fetch/@types/index.d.ts
vendored
Normal file
|
|
@ -0,0 +1,219 @@
|
|||
/// <reference types="node" />
|
||||
|
||||
import {RequestOptions} from 'http';
|
||||
import {FormData} from 'formdata-polyfill/esm.min.js';
|
||||
import {
|
||||
Blob,
|
||||
blobFrom,
|
||||
blobFromSync,
|
||||
File,
|
||||
fileFrom,
|
||||
fileFromSync
|
||||
} from 'fetch-blob/from.js';
|
||||
|
||||
type AbortSignal = {
|
||||
readonly aborted: boolean;
|
||||
|
||||
addEventListener: (type: 'abort', listener: (this: AbortSignal) => void) => void;
|
||||
removeEventListener: (type: 'abort', listener: (this: AbortSignal) => void) => void;
|
||||
};
|
||||
|
||||
export type HeadersInit = Headers | Record<string, string> | Iterable<readonly [string, string]> | Iterable<Iterable<string>>;
|
||||
|
||||
export {
|
||||
FormData,
|
||||
Blob,
|
||||
blobFrom,
|
||||
blobFromSync,
|
||||
File,
|
||||
fileFrom,
|
||||
fileFromSync
|
||||
};
|
||||
|
||||
/**
|
||||
* This Fetch API interface allows you to perform various actions on HTTP request and response headers.
|
||||
* These actions include retrieving, setting, adding to, and removing.
|
||||
* A Headers object has an associated header list, which is initially empty and consists of zero or more name and value pairs.
|
||||
* You can add to this using methods like append() (see Examples.)
|
||||
* In all methods of this interface, header names are matched by case-insensitive byte sequence.
|
||||
* */
|
||||
export class Headers {
|
||||
constructor(init?: HeadersInit);
|
||||
|
||||
append(name: string, value: string): void;
|
||||
delete(name: string): void;
|
||||
get(name: string): string | null;
|
||||
has(name: string): boolean;
|
||||
set(name: string, value: string): void;
|
||||
forEach(
|
||||
callbackfn: (value: string, key: string, parent: Headers) => void,
|
||||
thisArg?: any
|
||||
): void;
|
||||
|
||||
[Symbol.iterator](): IterableIterator<[string, string]>;
|
||||
/**
|
||||
* Returns an iterator allowing to go through all key/value pairs contained in this object.
|
||||
*/
|
||||
entries(): IterableIterator<[string, string]>;
|
||||
/**
|
||||
* Returns an iterator allowing to go through all keys of the key/value pairs contained in this object.
|
||||
*/
|
||||
keys(): IterableIterator<string>;
|
||||
/**
|
||||
* Returns an iterator allowing to go through all values of the key/value pairs contained in this object.
|
||||
*/
|
||||
values(): IterableIterator<string>;
|
||||
|
||||
/** Node-fetch extension */
|
||||
raw(): Record<string, string[]>;
|
||||
}
|
||||
|
||||
export interface RequestInit {
|
||||
/**
|
||||
* A BodyInit object or null to set request's body.
|
||||
*/
|
||||
body?: BodyInit | null;
|
||||
/**
|
||||
* A Headers object, an object literal, or an array of two-item arrays to set request's headers.
|
||||
*/
|
||||
headers?: HeadersInit;
|
||||
/**
|
||||
* A string to set request's method.
|
||||
*/
|
||||
method?: string;
|
||||
/**
|
||||
* A string indicating whether request follows redirects, results in an error upon encountering a redirect, or returns the redirect (in an opaque fashion). Sets request's redirect.
|
||||
*/
|
||||
redirect?: RequestRedirect;
|
||||
/**
|
||||
* An AbortSignal to set request's signal.
|
||||
*/
|
||||
signal?: AbortSignal | null;
|
||||
/**
|
||||
* A string whose value is a same-origin URL, "about:client", or the empty string, to set request’s referrer.
|
||||
*/
|
||||
referrer?: string;
|
||||
/**
|
||||
* A referrer policy to set request’s referrerPolicy.
|
||||
*/
|
||||
referrerPolicy?: ReferrerPolicy;
|
||||
|
||||
// Node-fetch extensions to the whatwg/fetch spec
|
||||
agent?: RequestOptions['agent'] | ((parsedUrl: URL) => RequestOptions['agent']);
|
||||
compress?: boolean;
|
||||
counter?: number;
|
||||
follow?: number;
|
||||
hostname?: string;
|
||||
port?: number;
|
||||
protocol?: string;
|
||||
size?: number;
|
||||
highWaterMark?: number;
|
||||
insecureHTTPParser?: boolean;
|
||||
}
|
||||
|
||||
export interface ResponseInit {
|
||||
headers?: HeadersInit;
|
||||
status?: number;
|
||||
statusText?: string;
|
||||
}
|
||||
|
||||
export type BodyInit =
|
||||
| Blob
|
||||
| Buffer
|
||||
| URLSearchParams
|
||||
| FormData
|
||||
| NodeJS.ReadableStream
|
||||
| string;
|
||||
declare class BodyMixin {
|
||||
constructor(body?: BodyInit, options?: {size?: number});
|
||||
|
||||
readonly body: NodeJS.ReadableStream | null;
|
||||
readonly bodyUsed: boolean;
|
||||
readonly size: number;
|
||||
|
||||
/** @deprecated Use `body.arrayBuffer()` instead. */
|
||||
buffer(): Promise<Buffer>;
|
||||
arrayBuffer(): Promise<ArrayBuffer>;
|
||||
formData(): Promise<FormData>;
|
||||
blob(): Promise<Blob>;
|
||||
json(): Promise<unknown>;
|
||||
text(): Promise<string>;
|
||||
}
|
||||
|
||||
// `Body` must not be exported as a class since it's not exported from the JavaScript code.
|
||||
export interface Body extends Pick<BodyMixin, keyof BodyMixin> {}
|
||||
|
||||
export type RequestRedirect = 'error' | 'follow' | 'manual';
|
||||
export type ReferrerPolicy = '' | 'no-referrer' | 'no-referrer-when-downgrade' | 'same-origin' | 'origin' | 'strict-origin' | 'origin-when-cross-origin' | 'strict-origin-when-cross-origin' | 'unsafe-url';
|
||||
export type RequestInfo = string | Request;
|
||||
export class Request extends BodyMixin {
|
||||
constructor(input: URL | RequestInfo, init?: RequestInit);
|
||||
|
||||
/**
|
||||
* Returns a Headers object consisting of the headers associated with request. Note that headers added in the network layer by the user agent will not be accounted for in this object, e.g., the "Host" header.
|
||||
*/
|
||||
readonly headers: Headers;
|
||||
/**
|
||||
* Returns request's HTTP method, which is "GET" by default.
|
||||
*/
|
||||
readonly method: string;
|
||||
/**
|
||||
* Returns the redirect mode associated with request, which is a string indicating how redirects for the request will be handled during fetching. A request will follow redirects by default.
|
||||
*/
|
||||
readonly redirect: RequestRedirect;
|
||||
/**
|
||||
* Returns the signal associated with request, which is an AbortSignal object indicating whether or not request has been aborted, and its abort event handler.
|
||||
*/
|
||||
readonly signal: AbortSignal;
|
||||
/**
|
||||
* Returns the URL of request as a string.
|
||||
*/
|
||||
readonly url: string;
|
||||
/**
|
||||
* A string whose value is a same-origin URL, "about:client", or the empty string, to set request’s referrer.
|
||||
*/
|
||||
readonly referrer: string;
|
||||
/**
|
||||
* A referrer policy to set request’s referrerPolicy.
|
||||
*/
|
||||
readonly referrerPolicy: ReferrerPolicy;
|
||||
clone(): Request;
|
||||
}
|
||||
|
||||
type ResponseType = 'basic' | 'cors' | 'default' | 'error' | 'opaque' | 'opaqueredirect';
|
||||
|
||||
export class Response extends BodyMixin {
|
||||
constructor(body?: BodyInit | null, init?: ResponseInit);
|
||||
|
||||
readonly headers: Headers;
|
||||
readonly ok: boolean;
|
||||
readonly redirected: boolean;
|
||||
readonly status: number;
|
||||
readonly statusText: string;
|
||||
readonly type: ResponseType;
|
||||
readonly url: string;
|
||||
clone(): Response;
|
||||
|
||||
static error(): Response;
|
||||
static redirect(url: string, status?: number): Response;
|
||||
static json(data: any, init?: ResponseInit): Response;
|
||||
}
|
||||
|
||||
export class FetchError extends Error {
|
||||
constructor(message: string, type: string, systemError?: Record<string, unknown>);
|
||||
|
||||
name: 'FetchError';
|
||||
[Symbol.toStringTag]: 'FetchError';
|
||||
type: string;
|
||||
code?: string;
|
||||
errno?: string;
|
||||
}
|
||||
|
||||
export class AbortError extends Error {
|
||||
type: string;
|
||||
name: 'AbortError';
|
||||
[Symbol.toStringTag]: 'AbortError';
|
||||
}
|
||||
|
||||
export function isRedirect(code: number): boolean;
|
||||
export default function fetch(url: URL | RequestInfo, init?: RequestInit): Promise<Response>;
|
||||
22
_shared/lib/node-fetch/LICENSE.md
Normal file
22
_shared/lib/node-fetch/LICENSE.md
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2016 - 2020 Node Fetch Team
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
872
_shared/lib/node-fetch/README.md
Normal file
872
_shared/lib/node-fetch/README.md
Normal file
|
|
@ -0,0 +1,872 @@
|
|||
<div align="center">
|
||||
<img src="docs/media/Banner.svg" alt="Node Fetch"/>
|
||||
<br>
|
||||
<p>A light-weight module that brings <a href="https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API">Fetch API</a> to Node.js.</p>
|
||||
<a href="https://github.com/node-fetch/node-fetch/actions"><img src="https://github.com/node-fetch/node-fetch/workflows/CI/badge.svg?branch=master" alt="Build status"></a>
|
||||
<a href="https://coveralls.io/github/node-fetch/node-fetch"><img src="https://img.shields.io/coveralls/github/node-fetch/node-fetch" alt="Coverage status"></a>
|
||||
<a href="https://packagephobia.now.sh/result?p=node-fetch"><img src="https://badgen.net/packagephobia/install/node-fetch" alt="Current version"></a>
|
||||
<a href="https://www.npmjs.com/package/node-fetch"><img src="https://img.shields.io/npm/v/node-fetch" alt="Install size"></a>
|
||||
<a href="https://github.com/sindresorhus/awesome-nodejs"><img src="https://awesome.re/mentioned-badge.svg" alt="Mentioned in Awesome Node.js"></a>
|
||||
<a href="https://discord.gg/Zxbndcm"><img src="https://img.shields.io/discord/619915844268326952?color=%237289DA&label=Discord" alt="Discord"></a>
|
||||
<br>
|
||||
<br>
|
||||
<b>Consider supporting us on our Open Collective:</b>
|
||||
<br>
|
||||
<br>
|
||||
<a href="https://opencollective.com/node-fetch"><img src="https://opencollective.com/node-fetch/donate/button.png?color=blue" alt="Open Collective"></a>
|
||||
</div>
|
||||
|
||||
---
|
||||
|
||||
**You might be looking for the [v2 docs](https://github.com/node-fetch/node-fetch/tree/2.x#readme)**
|
||||
|
||||
<!-- TOC -->
|
||||
|
||||
- [Motivation](#motivation)
|
||||
- [Features](#features)
|
||||
- [Difference from client-side fetch](#difference-from-client-side-fetch)
|
||||
- [Installation](#installation)
|
||||
- [Loading and configuring the module](#loading-and-configuring-the-module)
|
||||
- [Upgrading](#upgrading)
|
||||
- [Common Usage](#common-usage)
|
||||
- [Plain text or HTML](#plain-text-or-html)
|
||||
- [JSON](#json)
|
||||
- [Simple Post](#simple-post)
|
||||
- [Post with JSON](#post-with-json)
|
||||
- [Post with form parameters](#post-with-form-parameters)
|
||||
- [Handling exceptions](#handling-exceptions)
|
||||
- [Handling client and server errors](#handling-client-and-server-errors)
|
||||
- [Handling cookies](#handling-cookies)
|
||||
- [Advanced Usage](#advanced-usage)
|
||||
- [Streams](#streams)
|
||||
- [Accessing Headers and other Metadata](#accessing-headers-and-other-metadata)
|
||||
- [Extract Set-Cookie Header](#extract-set-cookie-header)
|
||||
- [Post data using a file](#post-data-using-a-file)
|
||||
- [Request cancellation with AbortSignal](#request-cancellation-with-abortsignal)
|
||||
- [API](#api)
|
||||
- [fetch(url[, options])](#fetchurl-options)
|
||||
- [Options](#options)
|
||||
- [Default Headers](#default-headers)
|
||||
- [Custom Agent](#custom-agent)
|
||||
- [Custom highWaterMark](#custom-highwatermark)
|
||||
- [Insecure HTTP Parser](#insecure-http-parser)
|
||||
- [Class: Request](#class-request)
|
||||
- [new Request(input[, options])](#new-requestinput-options)
|
||||
- [Class: Response](#class-response)
|
||||
- [new Response([body[, options]])](#new-responsebody-options)
|
||||
- [response.ok](#responseok)
|
||||
- [response.redirected](#responseredirected)
|
||||
- [response.type](#responsetype)
|
||||
- [Class: Headers](#class-headers)
|
||||
- [new Headers([init])](#new-headersinit)
|
||||
- [Interface: Body](#interface-body)
|
||||
- [body.body](#bodybody)
|
||||
- [body.bodyUsed](#bodybodyused)
|
||||
- [body.arrayBuffer()](#bodyarraybuffer)
|
||||
- [body.blob()](#bodyblob)
|
||||
- [body.formData()](#formdata)
|
||||
- [body.json()](#bodyjson)
|
||||
- [body.text()](#bodytext)
|
||||
- [Class: FetchError](#class-fetcherror)
|
||||
- [Class: AbortError](#class-aborterror)
|
||||
- [TypeScript](#typescript)
|
||||
- [Acknowledgement](#acknowledgement)
|
||||
- [Team](#team)
|
||||
- [Former](#former)
|
||||
- [License](#license)
|
||||
|
||||
<!-- /TOC -->
|
||||
|
||||
## Motivation
|
||||
|
||||
Instead of implementing `XMLHttpRequest` in Node.js to run browser-specific [Fetch polyfill](https://github.com/github/fetch), why not go from native `http` to `fetch` API directly? Hence, `node-fetch`, minimal code for a `window.fetch` compatible API on Node.js runtime.
|
||||
|
||||
See Jason Miller's [isomorphic-unfetch](https://www.npmjs.com/package/isomorphic-unfetch) or Leonardo Quixada's [cross-fetch](https://github.com/lquixada/cross-fetch) for isomorphic usage (exports `node-fetch` for server-side, `whatwg-fetch` for client-side).
|
||||
|
||||
## Features
|
||||
|
||||
- Stay consistent with `window.fetch` API.
|
||||
- Make conscious trade-off when following [WHATWG fetch spec][whatwg-fetch] and [stream spec](https://streams.spec.whatwg.org/) implementation details, document known differences.
|
||||
- Use native promise and async functions.
|
||||
- Use native Node streams for body, on both request and response.
|
||||
- Decode content encoding (gzip/deflate/brotli) properly, and convert string output (such as `res.text()` and `res.json()`) to UTF-8 automatically.
|
||||
- Useful extensions such as redirect limit, response size limit, [explicit errors][error-handling.md] for troubleshooting.
|
||||
|
||||
## Difference from client-side fetch
|
||||
|
||||
- See known differences:
|
||||
- [As of v3.x](docs/v3-LIMITS.md)
|
||||
- [As of v2.x](docs/v2-LIMITS.md)
|
||||
- If you happen to use a missing feature that `window.fetch` offers, feel free to open an issue.
|
||||
- Pull requests are welcomed too!
|
||||
|
||||
## Installation
|
||||
|
||||
Current stable release (`3.x`) requires at least Node.js 12.20.0.
|
||||
|
||||
```sh
|
||||
npm install node-fetch
|
||||
```
|
||||
|
||||
## Loading and configuring the module
|
||||
|
||||
### ES Modules (ESM)
|
||||
|
||||
```js
|
||||
import fetch from 'node-fetch';
|
||||
```
|
||||
|
||||
### CommonJS
|
||||
|
||||
`node-fetch` from v3 is an ESM-only module - you are not able to import it with `require()`.
|
||||
|
||||
If you cannot switch to ESM, please use v2 which remains compatible with CommonJS. Critical bug fixes will continue to be published for v2.
|
||||
|
||||
```sh
|
||||
npm install node-fetch@2
|
||||
```
|
||||
|
||||
Alternatively, you can use the async `import()` function from CommonJS to load `node-fetch` asynchronously:
|
||||
|
||||
```js
|
||||
// mod.cjs
|
||||
const fetch = (...args) => import('node-fetch').then(({default: fetch}) => fetch(...args));
|
||||
```
|
||||
|
||||
### Providing global access
|
||||
|
||||
To use `fetch()` without importing it, you can patch the `global` object in node:
|
||||
|
||||
```js
|
||||
// fetch-polyfill.js
|
||||
import fetch, {
|
||||
Blob,
|
||||
blobFrom,
|
||||
blobFromSync,
|
||||
File,
|
||||
fileFrom,
|
||||
fileFromSync,
|
||||
FormData,
|
||||
Headers,
|
||||
Request,
|
||||
Response,
|
||||
} from 'node-fetch'
|
||||
|
||||
if (!globalThis.fetch) {
|
||||
globalThis.fetch = fetch
|
||||
globalThis.Headers = Headers
|
||||
globalThis.Request = Request
|
||||
globalThis.Response = Response
|
||||
}
|
||||
|
||||
// index.js
|
||||
import './fetch-polyfill'
|
||||
|
||||
// ...
|
||||
```
|
||||
|
||||
## Upgrading
|
||||
|
||||
Using an old version of node-fetch? Check out the following files:
|
||||
|
||||
- [2.x to 3.x upgrade guide](docs/v3-UPGRADE-GUIDE.md)
|
||||
- [1.x to 2.x upgrade guide](docs/v2-UPGRADE-GUIDE.md)
|
||||
- [Changelog](https://github.com/node-fetch/node-fetch/releases)
|
||||
|
||||
## Common Usage
|
||||
|
||||
NOTE: The documentation below is up-to-date with `3.x` releases, if you are using an older version, please check how to [upgrade](#upgrading).
|
||||
|
||||
### Plain text or HTML
|
||||
|
||||
```js
|
||||
import fetch from 'node-fetch';
|
||||
|
||||
const response = await fetch('https://github.com/');
|
||||
const body = await response.text();
|
||||
|
||||
console.log(body);
|
||||
```
|
||||
|
||||
### JSON
|
||||
|
||||
```js
|
||||
import fetch from 'node-fetch';
|
||||
|
||||
const response = await fetch('https://api.github.com/users/github');
|
||||
const data = await response.json();
|
||||
|
||||
console.log(data);
|
||||
```
|
||||
|
||||
### Simple Post
|
||||
|
||||
```js
|
||||
import fetch from 'node-fetch';
|
||||
|
||||
const response = await fetch('https://httpbin.org/post', {method: 'POST', body: 'a=1'});
|
||||
const data = await response.json();
|
||||
|
||||
console.log(data);
|
||||
```
|
||||
|
||||
### Post with JSON
|
||||
|
||||
```js
|
||||
import fetch from 'node-fetch';
|
||||
|
||||
const body = {a: 1};
|
||||
|
||||
const response = await fetch('https://httpbin.org/post', {
|
||||
method: 'post',
|
||||
body: JSON.stringify(body),
|
||||
headers: {'Content-Type': 'application/json'}
|
||||
});
|
||||
const data = await response.json();
|
||||
|
||||
console.log(data);
|
||||
```
|
||||
|
||||
### Post with form parameters
|
||||
|
||||
`URLSearchParams` is available on the global object in Node.js as of v10.0.0. See [official documentation](https://nodejs.org/api/url.html#url_class_urlsearchparams) for more usage methods.
|
||||
|
||||
NOTE: The `Content-Type` header is only set automatically to `x-www-form-urlencoded` when an instance of `URLSearchParams` is given as such:
|
||||
|
||||
```js
|
||||
import fetch from 'node-fetch';
|
||||
|
||||
const params = new URLSearchParams();
|
||||
params.append('a', 1);
|
||||
|
||||
const response = await fetch('https://httpbin.org/post', {method: 'POST', body: params});
|
||||
const data = await response.json();
|
||||
|
||||
console.log(data);
|
||||
```
|
||||
|
||||
### Handling exceptions
|
||||
|
||||
NOTE: 3xx-5xx responses are _NOT_ exceptions, and should be handled in `then()`, see the next section.
|
||||
|
||||
Wrapping the fetch function into a `try/catch` block will catch _all_ exceptions, such as errors originating from node core libraries, like network errors, and operational errors which are instances of FetchError. See the [error handling document][error-handling.md] for more details.
|
||||
|
||||
```js
|
||||
import fetch from 'node-fetch';
|
||||
|
||||
try {
|
||||
await fetch('https://domain.invalid/');
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
```
|
||||
|
||||
### Handling client and server errors
|
||||
|
||||
It is common to create a helper function to check that the response contains no client (4xx) or server (5xx) error responses:
|
||||
|
||||
```js
|
||||
import fetch from 'node-fetch';
|
||||
|
||||
class HTTPResponseError extends Error {
|
||||
constructor(response) {
|
||||
super(`HTTP Error Response: ${response.status} ${response.statusText}`);
|
||||
this.response = response;
|
||||
}
|
||||
}
|
||||
|
||||
const checkStatus = response => {
|
||||
if (response.ok) {
|
||||
// response.status >= 200 && response.status < 300
|
||||
return response;
|
||||
} else {
|
||||
throw new HTTPResponseError(response);
|
||||
}
|
||||
}
|
||||
|
||||
const response = await fetch('https://httpbin.org/status/400');
|
||||
|
||||
try {
|
||||
checkStatus(response);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
|
||||
const errorBody = await error.response.text();
|
||||
console.error(`Error body: ${errorBody}`);
|
||||
}
|
||||
```
|
||||
|
||||
### Handling cookies
|
||||
|
||||
Cookies are not stored by default. However, cookies can be extracted and passed by manipulating request and response headers. See [Extract Set-Cookie Header](#extract-set-cookie-header) for details.
|
||||
|
||||
## Advanced Usage
|
||||
|
||||
### Streams
|
||||
|
||||
The "Node.js way" is to use streams when possible. You can pipe `res.body` to another stream. This example uses [stream.pipeline](https://nodejs.org/api/stream.html#stream_stream_pipeline_streams_callback) to attach stream error handlers and wait for the download to complete.
|
||||
|
||||
```js
|
||||
import {createWriteStream} from 'node:fs';
|
||||
import {pipeline} from 'node:stream';
|
||||
import {promisify} from 'node:util'
|
||||
import fetch from 'node-fetch';
|
||||
|
||||
const streamPipeline = promisify(pipeline);
|
||||
|
||||
const response = await fetch('https://github.githubassets.com/images/modules/logos_page/Octocat.png');
|
||||
|
||||
if (!response.ok) throw new Error(`unexpected response ${response.statusText}`);
|
||||
|
||||
await streamPipeline(response.body, createWriteStream('./octocat.png'));
|
||||
```
|
||||
|
||||
In Node.js 14 you can also use async iterators to read `body`; however, be careful to catch
|
||||
errors -- the longer a response runs, the more likely it is to encounter an error.
|
||||
|
||||
```js
|
||||
import fetch from 'node-fetch';
|
||||
|
||||
const response = await fetch('https://httpbin.org/stream/3');
|
||||
|
||||
try {
|
||||
for await (const chunk of response.body) {
|
||||
console.dir(JSON.parse(chunk.toString()));
|
||||
}
|
||||
} catch (err) {
|
||||
console.error(err.stack);
|
||||
}
|
||||
```
|
||||
|
||||
In Node.js 12 you can also use async iterators to read `body`; however, async iterators with streams
|
||||
did not mature until Node.js 14, so you need to do some extra work to ensure you handle errors
|
||||
directly from the stream and wait on it response to fully close.
|
||||
|
||||
```js
|
||||
import fetch from 'node-fetch';
|
||||
|
||||
const read = async body => {
|
||||
let error;
|
||||
body.on('error', err => {
|
||||
error = err;
|
||||
});
|
||||
|
||||
for await (const chunk of body) {
|
||||
console.dir(JSON.parse(chunk.toString()));
|
||||
}
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
body.on('close', () => {
|
||||
error ? reject(error) : resolve();
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
try {
|
||||
const response = await fetch('https://httpbin.org/stream/3');
|
||||
await read(response.body);
|
||||
} catch (err) {
|
||||
console.error(err.stack);
|
||||
}
|
||||
```
|
||||
|
||||
### Accessing Headers and other Metadata
|
||||
|
||||
```js
|
||||
import fetch from 'node-fetch';
|
||||
|
||||
const response = await fetch('https://github.com/');
|
||||
|
||||
console.log(response.ok);
|
||||
console.log(response.status);
|
||||
console.log(response.statusText);
|
||||
console.log(response.headers.raw());
|
||||
console.log(response.headers.get('content-type'));
|
||||
```
|
||||
|
||||
### Extract Set-Cookie Header
|
||||
|
||||
Unlike browsers, you can access raw `Set-Cookie` headers manually using `Headers.raw()`. This is a `node-fetch` only API.
|
||||
|
||||
```js
|
||||
import fetch from 'node-fetch';
|
||||
|
||||
const response = await fetch('https://example.com');
|
||||
|
||||
// Returns an array of values, instead of a string of comma-separated values
|
||||
console.log(response.headers.raw()['set-cookie']);
|
||||
```
|
||||
|
||||
### Post data using a file
|
||||
|
||||
```js
|
||||
import fetch, {
|
||||
Blob,
|
||||
blobFrom,
|
||||
blobFromSync,
|
||||
File,
|
||||
fileFrom,
|
||||
fileFromSync,
|
||||
} from 'node-fetch'
|
||||
|
||||
const mimetype = 'text/plain'
|
||||
const blob = fileFromSync('./input.txt', mimetype)
|
||||
const url = 'https://httpbin.org/post'
|
||||
|
||||
const response = await fetch(url, { method: 'POST', body: blob })
|
||||
const data = await response.json()
|
||||
|
||||
console.log(data)
|
||||
```
|
||||
|
||||
node-fetch comes with a spec-compliant [FormData] implementations for posting
|
||||
multipart/form-data payloads
|
||||
|
||||
```js
|
||||
import fetch, { FormData, File, fileFrom } from 'node-fetch'
|
||||
|
||||
const httpbin = 'https://httpbin.org/post'
|
||||
const formData = new FormData()
|
||||
const binary = new Uint8Array([ 97, 98, 99 ])
|
||||
const abc = new File([binary], 'abc.txt', { type: 'text/plain' })
|
||||
|
||||
formData.set('greeting', 'Hello, world!')
|
||||
formData.set('file-upload', abc, 'new name.txt')
|
||||
|
||||
const response = await fetch(httpbin, { method: 'POST', body: formData })
|
||||
const data = await response.json()
|
||||
|
||||
console.log(data)
|
||||
```
|
||||
|
||||
If you for some reason need to post a stream coming from any arbitrary place,
|
||||
then you can append a [Blob] or a [File] look-a-like item.
|
||||
|
||||
The minimum requirement is that it has:
|
||||
1. A `Symbol.toStringTag` getter or property that is either `Blob` or `File`
|
||||
2. A known size.
|
||||
3. And either a `stream()` method or a `arrayBuffer()` method that returns a ArrayBuffer.
|
||||
|
||||
The `stream()` must return any async iterable object as long as it yields Uint8Array (or Buffer)
|
||||
so Node.Readable streams and whatwg streams works just fine.
|
||||
|
||||
```js
|
||||
formData.append('upload', {
|
||||
[Symbol.toStringTag]: 'Blob',
|
||||
size: 3,
|
||||
*stream() {
|
||||
yield new Uint8Array([97, 98, 99])
|
||||
},
|
||||
arrayBuffer() {
|
||||
return new Uint8Array([97, 98, 99]).buffer
|
||||
}
|
||||
}, 'abc.txt')
|
||||
```
|
||||
|
||||
### Request cancellation with AbortSignal
|
||||
|
||||
You may cancel requests with `AbortController`. A suggested implementation is [`abort-controller`](https://www.npmjs.com/package/abort-controller).
|
||||
|
||||
An example of timing out a request after 150ms could be achieved as the following:
|
||||
|
||||
```js
|
||||
import fetch, { AbortError } from 'node-fetch';
|
||||
|
||||
// AbortController was added in node v14.17.0 globally
|
||||
const AbortController = globalThis.AbortController || await import('abort-controller')
|
||||
|
||||
const controller = new AbortController();
|
||||
const timeout = setTimeout(() => {
|
||||
controller.abort();
|
||||
}, 150);
|
||||
|
||||
try {
|
||||
const response = await fetch('https://example.com', {signal: controller.signal});
|
||||
const data = await response.json();
|
||||
} catch (error) {
|
||||
if (error instanceof AbortError) {
|
||||
console.log('request was aborted');
|
||||
}
|
||||
} finally {
|
||||
clearTimeout(timeout);
|
||||
}
|
||||
```
|
||||
|
||||
See [test cases](https://github.com/node-fetch/node-fetch/blob/master/test/) for more examples.
|
||||
|
||||
## API
|
||||
|
||||
### fetch(url[, options])
|
||||
|
||||
- `url` A string representing the URL for fetching
|
||||
- `options` [Options](#fetch-options) for the HTTP(S) request
|
||||
- Returns: <code>Promise<[Response](#class-response)></code>
|
||||
|
||||
Perform an HTTP(S) fetch.
|
||||
|
||||
`url` should be an absolute URL, such as `https://example.com/`. A path-relative URL (`/file/under/root`) or protocol-relative URL (`//can-be-http-or-https.com/`) will result in a rejected `Promise`.
|
||||
|
||||
<a id="fetch-options"></a>
|
||||
|
||||
### Options
|
||||
|
||||
The default values are shown after each option key.
|
||||
|
||||
```js
|
||||
{
|
||||
// These properties are part of the Fetch Standard
|
||||
method: 'GET',
|
||||
headers: {}, // Request headers. format is the identical to that accepted by the Headers constructor (see below)
|
||||
body: null, // Request body. can be null, or a Node.js Readable stream
|
||||
redirect: 'follow', // Set to `manual` to extract redirect headers, `error` to reject redirect
|
||||
signal: null, // Pass an instance of AbortSignal to optionally abort requests
|
||||
|
||||
// The following properties are node-fetch extensions
|
||||
follow: 20, // maximum redirect count. 0 to not follow redirect
|
||||
compress: true, // support gzip/deflate content encoding. false to disable
|
||||
size: 0, // maximum response body size in bytes. 0 to disable
|
||||
agent: null, // http(s).Agent instance or function that returns an instance (see below)
|
||||
highWaterMark: 16384, // the maximum number of bytes to store in the internal buffer before ceasing to read from the underlying resource.
|
||||
insecureHTTPParser: false // Use an insecure HTTP parser that accepts invalid HTTP headers when `true`.
|
||||
}
|
||||
```
|
||||
|
||||
#### Default Headers
|
||||
|
||||
If no values are set, the following request headers will be sent automatically:
|
||||
|
||||
| Header | Value |
|
||||
| ------------------- | ------------------------------------------------------ |
|
||||
| `Accept-Encoding` | `gzip, deflate, br` (when `options.compress === true`) |
|
||||
| `Accept` | `*/*` |
|
||||
| `Content-Length` | _(automatically calculated, if possible)_ |
|
||||
| `Host` | _(host and port information from the target URI)_ |
|
||||
| `Transfer-Encoding` | `chunked` _(when `req.body` is a stream)_ |
|
||||
| `User-Agent` | `node-fetch` |
|
||||
|
||||
|
||||
Note: when `body` is a `Stream`, `Content-Length` is not set automatically.
|
||||
|
||||
#### Custom Agent
|
||||
|
||||
The `agent` option allows you to specify networking related options which are out of the scope of Fetch, including and not limited to the following:
|
||||
|
||||
- Support self-signed certificate
|
||||
- Use only IPv4 or IPv6
|
||||
- Custom DNS Lookup
|
||||
|
||||
See [`http.Agent`](https://nodejs.org/api/http.html#http_new_agent_options) for more information.
|
||||
|
||||
If no agent is specified, the default agent provided by Node.js is used. Note that [this changed in Node.js 19](https://github.com/nodejs/node/blob/4267b92604ad78584244488e7f7508a690cb80d0/lib/_http_agent.js#L564) to have `keepalive` true by default. If you wish to enable `keepalive` in an earlier version of Node.js, you can override the agent as per the following code sample.
|
||||
|
||||
In addition, the `agent` option accepts a function that returns `http`(s)`.Agent` instance given current [URL](https://nodejs.org/api/url.html), this is useful during a redirection chain across HTTP and HTTPS protocol.
|
||||
|
||||
```js
|
||||
import http from 'node:http';
|
||||
import https from 'node:https';
|
||||
|
||||
const httpAgent = new http.Agent({
|
||||
keepAlive: true
|
||||
});
|
||||
const httpsAgent = new https.Agent({
|
||||
keepAlive: true
|
||||
});
|
||||
|
||||
const options = {
|
||||
agent: function(_parsedURL) {
|
||||
if (_parsedURL.protocol == 'http:') {
|
||||
return httpAgent;
|
||||
} else {
|
||||
return httpsAgent;
|
||||
}
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
<a id="custom-highWaterMark"></a>
|
||||
|
||||
#### Custom highWaterMark
|
||||
|
||||
Stream on Node.js have a smaller internal buffer size (16kB, aka `highWaterMark`) from client-side browsers (>1MB, not consistent across browsers). Because of that, when you are writing an isomorphic app and using `res.clone()`, it will hang with large response in Node.
|
||||
|
||||
The recommended way to fix this problem is to resolve cloned response in parallel:
|
||||
|
||||
```js
|
||||
import fetch from 'node-fetch';
|
||||
|
||||
const response = await fetch('https://example.com');
|
||||
const r1 = response.clone();
|
||||
|
||||
const results = await Promise.all([response.json(), r1.text()]);
|
||||
|
||||
console.log(results[0]);
|
||||
console.log(results[1]);
|
||||
```
|
||||
|
||||
If for some reason you don't like the solution above, since `3.x` you are able to modify the `highWaterMark` option:
|
||||
|
||||
```js
|
||||
import fetch from 'node-fetch';
|
||||
|
||||
const response = await fetch('https://example.com', {
|
||||
// About 1MB
|
||||
highWaterMark: 1024 * 1024
|
||||
});
|
||||
|
||||
const result = await res.clone().arrayBuffer();
|
||||
console.dir(result);
|
||||
```
|
||||
|
||||
#### Insecure HTTP Parser
|
||||
|
||||
Passed through to the `insecureHTTPParser` option on http(s).request. See [`http.request`](https://nodejs.org/api/http.html#http_http_request_url_options_callback) for more information.
|
||||
|
||||
#### Manual Redirect
|
||||
|
||||
The `redirect: 'manual'` option for node-fetch is different from the browser & specification, which
|
||||
results in an [opaque-redirect filtered response](https://fetch.spec.whatwg.org/#concept-filtered-response-opaque-redirect).
|
||||
node-fetch gives you the typical [basic filtered response](https://fetch.spec.whatwg.org/#concept-filtered-response-basic) instead.
|
||||
|
||||
```js
|
||||
import fetch from 'node-fetch';
|
||||
|
||||
const response = await fetch('https://httpbin.org/status/301', { redirect: 'manual' });
|
||||
|
||||
if (response.status === 301 || response.status === 302) {
|
||||
const locationURL = new URL(response.headers.get('location'), response.url);
|
||||
const response2 = await fetch(locationURL, { redirect: 'manual' });
|
||||
console.dir(response2);
|
||||
}
|
||||
```
|
||||
|
||||
<a id="class-request"></a>
|
||||
|
||||
### Class: Request
|
||||
|
||||
An HTTP(S) request containing information about URL, method, headers, and the body. This class implements the [Body](#iface-body) interface.
|
||||
|
||||
Due to the nature of Node.js, the following properties are not implemented at this moment:
|
||||
|
||||
- `type`
|
||||
- `destination`
|
||||
- `mode`
|
||||
- `credentials`
|
||||
- `cache`
|
||||
- `integrity`
|
||||
- `keepalive`
|
||||
|
||||
The following node-fetch extension properties are provided:
|
||||
|
||||
- `follow`
|
||||
- `compress`
|
||||
- `counter`
|
||||
- `agent`
|
||||
- `highWaterMark`
|
||||
|
||||
See [options](#fetch-options) for exact meaning of these extensions.
|
||||
|
||||
#### new Request(input[, options])
|
||||
|
||||
<small>_(spec-compliant)_</small>
|
||||
|
||||
- `input` A string representing a URL, or another `Request` (which will be cloned)
|
||||
- `options` [Options](#fetch-options) for the HTTP(S) request
|
||||
|
||||
Constructs a new `Request` object. The constructor is identical to that in the [browser](https://developer.mozilla.org/en-US/docs/Web/API/Request/Request).
|
||||
|
||||
In most cases, directly `fetch(url, options)` is simpler than creating a `Request` object.
|
||||
|
||||
<a id="class-response"></a>
|
||||
|
||||
### Class: Response
|
||||
|
||||
An HTTP(S) response. This class implements the [Body](#iface-body) interface.
|
||||
|
||||
The following properties are not implemented in node-fetch at this moment:
|
||||
|
||||
- `trailer`
|
||||
|
||||
#### new Response([body[, options]])
|
||||
|
||||
<small>_(spec-compliant)_</small>
|
||||
|
||||
- `body` A `String` or [`Readable` stream][node-readable]
|
||||
- `options` A [`ResponseInit`][response-init] options dictionary
|
||||
|
||||
Constructs a new `Response` object. The constructor is identical to that in the [browser](https://developer.mozilla.org/en-US/docs/Web/API/Response/Response).
|
||||
|
||||
Because Node.js does not implement service workers (for which this class was designed), one rarely has to construct a `Response` directly.
|
||||
|
||||
#### response.ok
|
||||
|
||||
<small>_(spec-compliant)_</small>
|
||||
|
||||
Convenience property representing if the request ended normally. Will evaluate to true if the response status was greater than or equal to 200 but smaller than 300.
|
||||
|
||||
#### response.redirected
|
||||
|
||||
<small>_(spec-compliant)_</small>
|
||||
|
||||
Convenience property representing if the request has been redirected at least once. Will evaluate to true if the internal redirect counter is greater than 0.
|
||||
|
||||
#### response.type
|
||||
|
||||
<small>_(deviation from spec)_</small>
|
||||
|
||||
Convenience property representing the response's type. node-fetch only supports `'default'` and `'error'` and does not make use of [filtered responses](https://fetch.spec.whatwg.org/#concept-filtered-response).
|
||||
|
||||
<a id="class-headers"></a>
|
||||
|
||||
### Class: Headers
|
||||
|
||||
This class allows manipulating and iterating over a set of HTTP headers. All methods specified in the [Fetch Standard][whatwg-fetch] are implemented.
|
||||
|
||||
#### new Headers([init])
|
||||
|
||||
<small>_(spec-compliant)_</small>
|
||||
|
||||
- `init` Optional argument to pre-fill the `Headers` object
|
||||
|
||||
Construct a new `Headers` object. `init` can be either `null`, a `Headers` object, an key-value map object or any iterable object.
|
||||
|
||||
```js
|
||||
// Example adapted from https://fetch.spec.whatwg.org/#example-headers-class
|
||||
import {Headers} from 'node-fetch';
|
||||
|
||||
const meta = {
|
||||
'Content-Type': 'text/xml'
|
||||
};
|
||||
const headers = new Headers(meta);
|
||||
|
||||
// The above is equivalent to
|
||||
const meta = [['Content-Type', 'text/xml']];
|
||||
const headers = new Headers(meta);
|
||||
|
||||
// You can in fact use any iterable objects, like a Map or even another Headers
|
||||
const meta = new Map();
|
||||
meta.set('Content-Type', 'text/xml');
|
||||
const headers = new Headers(meta);
|
||||
const copyOfHeaders = new Headers(headers);
|
||||
```
|
||||
|
||||
<a id="iface-body"></a>
|
||||
|
||||
### Interface: Body
|
||||
|
||||
`Body` is an abstract interface with methods that are applicable to both `Request` and `Response` classes.
|
||||
|
||||
#### body.body
|
||||
|
||||
<small>_(deviation from spec)_</small>
|
||||
|
||||
- Node.js [`Readable` stream][node-readable]
|
||||
|
||||
Data are encapsulated in the `Body` object. Note that while the [Fetch Standard][whatwg-fetch] requires the property to always be a WHATWG `ReadableStream`, in node-fetch it is a Node.js [`Readable` stream][node-readable].
|
||||
|
||||
#### body.bodyUsed
|
||||
|
||||
<small>_(spec-compliant)_</small>
|
||||
|
||||
- `Boolean`
|
||||
|
||||
A boolean property for if this body has been consumed. Per the specs, a consumed body cannot be used again.
|
||||
|
||||
#### body.arrayBuffer()
|
||||
|
||||
#### body.formData()
|
||||
|
||||
#### body.blob()
|
||||
|
||||
#### body.json()
|
||||
|
||||
#### body.text()
|
||||
|
||||
`fetch` comes with methods to parse `multipart/form-data` payloads as well as
|
||||
`x-www-form-urlencoded` bodies using `.formData()` this comes from the idea that
|
||||
Service Worker can intercept such messages before it's sent to the server to
|
||||
alter them. This is useful for anybody building a server so you can use it to
|
||||
parse & consume payloads.
|
||||
|
||||
<details>
|
||||
<summary>Code example</summary>
|
||||
|
||||
```js
|
||||
import http from 'node:http'
|
||||
import { Response } from 'node-fetch'
|
||||
|
||||
http.createServer(async function (req, res) {
|
||||
const formData = await new Response(req, {
|
||||
headers: req.headers // Pass along the boundary value
|
||||
}).formData()
|
||||
const allFields = [...formData]
|
||||
|
||||
const file = formData.get('uploaded-files')
|
||||
const arrayBuffer = await file.arrayBuffer()
|
||||
const text = await file.text()
|
||||
const whatwgReadableStream = file.stream()
|
||||
|
||||
// other was to consume the request could be to do:
|
||||
const json = await new Response(req).json()
|
||||
const text = await new Response(req).text()
|
||||
const arrayBuffer = await new Response(req).arrayBuffer()
|
||||
const blob = await new Response(req, {
|
||||
headers: req.headers // So that `type` inherits `Content-Type`
|
||||
}.blob()
|
||||
})
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
<a id="class-fetcherror"></a>
|
||||
|
||||
### Class: FetchError
|
||||
|
||||
<small>_(node-fetch extension)_</small>
|
||||
|
||||
An operational error in the fetching process. See [ERROR-HANDLING.md][] for more info.
|
||||
|
||||
<a id="class-aborterror"></a>
|
||||
|
||||
### Class: AbortError
|
||||
|
||||
<small>_(node-fetch extension)_</small>
|
||||
|
||||
An Error thrown when the request is aborted in response to an `AbortSignal`'s `abort` event. It has a `name` property of `AbortError`. See [ERROR-HANDLING.MD][] for more info.
|
||||
|
||||
## TypeScript
|
||||
|
||||
**Since `3.x` types are bundled with `node-fetch`, so you don't need to install any additional packages.**
|
||||
|
||||
For older versions please use the type definitions from [DefinitelyTyped](https://github.com/DefinitelyTyped/DefinitelyTyped):
|
||||
|
||||
```sh
|
||||
npm install --save-dev @types/node-fetch@2.x
|
||||
```
|
||||
|
||||
## Acknowledgement
|
||||
|
||||
Thanks to [github/fetch](https://github.com/github/fetch) for providing a solid implementation reference.
|
||||
|
||||
## Team
|
||||
|
||||
| [](https://github.com/bitinn) | [](https://github.com/jimmywarting) | [](https://github.com/xxczaki) | [](https://github.com/Richienb) | [](https://github.com/gr2m) |
|
||||
| ----------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------- |
|
||||
| [David Frank](https://bitinn.net/) | [Jimmy Wärting](https://jimmy.warting.se/) | [Antoni Kepinski](https://kepinski.ch) | [Richie Bendall](https://www.richie-bendall.ml/) | [Gregor Martynus](https://twitter.com/gr2m) |
|
||||
|
||||
###### Former
|
||||
|
||||
- [Timothy Gu](https://github.com/timothygu)
|
||||
- [Jared Kantrowitz](https://github.com/jkantr)
|
||||
|
||||
## License
|
||||
|
||||
[MIT](LICENSE.md)
|
||||
|
||||
[whatwg-fetch]: https://fetch.spec.whatwg.org/
|
||||
[response-init]: https://fetch.spec.whatwg.org/#responseinit
|
||||
[node-readable]: https://nodejs.org/api/stream.html#stream_readable_streams
|
||||
[mdn-headers]: https://developer.mozilla.org/en-US/docs/Web/API/Headers
|
||||
[error-handling.md]: https://github.com/node-fetch/node-fetch/blob/master/docs/ERROR-HANDLING.md
|
||||
[FormData]: https://developer.mozilla.org/en-US/docs/Web/API/FormData
|
||||
[Blob]: https://developer.mozilla.org/en-US/docs/Web/API/Blob
|
||||
[File]: https://developer.mozilla.org/en-US/docs/Web/API/File
|
||||
397
_shared/lib/node-fetch/src/body.js
Normal file
397
_shared/lib/node-fetch/src/body.js
Normal file
|
|
@ -0,0 +1,397 @@
|
|||
|
||||
/**
|
||||
* Body.js
|
||||
*
|
||||
* Body interface provides common methods for Request and Response
|
||||
*/
|
||||
|
||||
import Stream, {PassThrough} from 'node:stream';
|
||||
import {types, deprecate, promisify} from 'node:util';
|
||||
import {Buffer} from 'node:buffer';
|
||||
|
||||
import Blob from 'fetch-blob';
|
||||
import {FormData, formDataToBlob} from 'formdata-polyfill/esm.min.js';
|
||||
|
||||
import {FetchError} from './errors/fetch-error.js';
|
||||
import {FetchBaseError} from './errors/base.js';
|
||||
import {isBlob, isURLSearchParameters} from './utils/is.js';
|
||||
|
||||
const pipeline = promisify(Stream.pipeline);
|
||||
const INTERNALS = Symbol('Body internals');
|
||||
|
||||
/**
|
||||
* Body mixin
|
||||
*
|
||||
* Ref: https://fetch.spec.whatwg.org/#body
|
||||
*
|
||||
* @param Stream body Readable stream
|
||||
* @param Object opts Response options
|
||||
* @return Void
|
||||
*/
|
||||
export default class Body {
|
||||
constructor(body, {
|
||||
size = 0
|
||||
} = {}) {
|
||||
let boundary = null;
|
||||
|
||||
if (body === null) {
|
||||
// Body is undefined or null
|
||||
body = null;
|
||||
} else if (isURLSearchParameters(body)) {
|
||||
// Body is a URLSearchParams
|
||||
body = Buffer.from(body.toString());
|
||||
} else if (isBlob(body)) {
|
||||
// Body is blob
|
||||
} else if (Buffer.isBuffer(body)) {
|
||||
// Body is Buffer
|
||||
} else if (types.isAnyArrayBuffer(body)) {
|
||||
// Body is ArrayBuffer
|
||||
body = Buffer.from(body);
|
||||
} else if (ArrayBuffer.isView(body)) {
|
||||
// Body is ArrayBufferView
|
||||
body = Buffer.from(body.buffer, body.byteOffset, body.byteLength);
|
||||
} else if (body instanceof Stream) {
|
||||
// Body is stream
|
||||
} else if (body instanceof FormData) {
|
||||
// Body is FormData
|
||||
body = formDataToBlob(body);
|
||||
boundary = body.type.split('=')[1];
|
||||
} else {
|
||||
// None of the above
|
||||
// coerce to string then buffer
|
||||
body = Buffer.from(String(body));
|
||||
}
|
||||
|
||||
let stream = body;
|
||||
|
||||
if (Buffer.isBuffer(body)) {
|
||||
stream = Stream.Readable.from(body);
|
||||
} else if (isBlob(body)) {
|
||||
stream = Stream.Readable.from(body.stream());
|
||||
}
|
||||
|
||||
this[INTERNALS] = {
|
||||
body,
|
||||
stream,
|
||||
boundary,
|
||||
disturbed: false,
|
||||
error: null
|
||||
};
|
||||
this.size = size;
|
||||
|
||||
if (body instanceof Stream) {
|
||||
body.on('error', error_ => {
|
||||
const error = error_ instanceof FetchBaseError ?
|
||||
error_ :
|
||||
new FetchError(`Invalid response body while trying to fetch ${this.url}: ${error_.message}`, 'system', error_);
|
||||
this[INTERNALS].error = error;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
get body() {
|
||||
return this[INTERNALS].stream;
|
||||
}
|
||||
|
||||
get bodyUsed() {
|
||||
return this[INTERNALS].disturbed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode response as ArrayBuffer
|
||||
*
|
||||
* @return Promise
|
||||
*/
|
||||
async arrayBuffer() {
|
||||
const {buffer, byteOffset, byteLength} = await consumeBody(this);
|
||||
return buffer.slice(byteOffset, byteOffset + byteLength);
|
||||
}
|
||||
|
||||
async formData() {
|
||||
const ct = this.headers.get('content-type');
|
||||
|
||||
if (ct.startsWith('application/x-www-form-urlencoded')) {
|
||||
const formData = new FormData();
|
||||
const parameters = new URLSearchParams(await this.text());
|
||||
|
||||
for (const [name, value] of parameters) {
|
||||
formData.append(name, value);
|
||||
}
|
||||
|
||||
return formData;
|
||||
}
|
||||
|
||||
const {toFormData} = await import('./utils/multipart-parser.js');
|
||||
return toFormData(this.body, ct);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return raw response as Blob
|
||||
*
|
||||
* @return Promise
|
||||
*/
|
||||
async blob() {
|
||||
const ct = (this.headers && this.headers.get('content-type')) || (this[INTERNALS].body && this[INTERNALS].body.type) || '';
|
||||
const buf = await this.arrayBuffer();
|
||||
|
||||
return new Blob([buf], {
|
||||
type: ct
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode response as json
|
||||
*
|
||||
* @return Promise
|
||||
*/
|
||||
async json() {
|
||||
const text = await this.text();
|
||||
return JSON.parse(text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode response as text
|
||||
*
|
||||
* @return Promise
|
||||
*/
|
||||
async text() {
|
||||
const buffer = await consumeBody(this);
|
||||
return new TextDecoder().decode(buffer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode response as buffer (non-spec api)
|
||||
*
|
||||
* @return Promise
|
||||
*/
|
||||
buffer() {
|
||||
return consumeBody(this);
|
||||
}
|
||||
}
|
||||
|
||||
Body.prototype.buffer = deprecate(Body.prototype.buffer, 'Please use \'response.arrayBuffer()\' instead of \'response.buffer()\'', 'node-fetch#buffer');
|
||||
|
||||
// In browsers, all properties are enumerable.
|
||||
Object.defineProperties(Body.prototype, {
|
||||
body: {enumerable: true},
|
||||
bodyUsed: {enumerable: true},
|
||||
arrayBuffer: {enumerable: true},
|
||||
blob: {enumerable: true},
|
||||
json: {enumerable: true},
|
||||
text: {enumerable: true},
|
||||
data: {get: deprecate(() => {},
|
||||
'data doesn\'t exist, use json(), text(), arrayBuffer(), or body instead',
|
||||
'https://github.com/node-fetch/node-fetch/issues/1000 (response)')}
|
||||
});
|
||||
|
||||
/**
|
||||
* Consume and convert an entire Body to a Buffer.
|
||||
*
|
||||
* Ref: https://fetch.spec.whatwg.org/#concept-body-consume-body
|
||||
*
|
||||
* @return Promise
|
||||
*/
|
||||
async function consumeBody(data) {
|
||||
if (data[INTERNALS].disturbed) {
|
||||
throw new TypeError(`body used already for: ${data.url}`);
|
||||
}
|
||||
|
||||
data[INTERNALS].disturbed = true;
|
||||
|
||||
if (data[INTERNALS].error) {
|
||||
throw data[INTERNALS].error;
|
||||
}
|
||||
|
||||
const {body} = data;
|
||||
|
||||
// Body is null
|
||||
if (body === null) {
|
||||
return Buffer.alloc(0);
|
||||
}
|
||||
|
||||
/* c8 ignore next 3 */
|
||||
if (!(body instanceof Stream)) {
|
||||
return Buffer.alloc(0);
|
||||
}
|
||||
|
||||
// Body is stream
|
||||
// get ready to actually consume the body
|
||||
const accum = [];
|
||||
let accumBytes = 0;
|
||||
|
||||
try {
|
||||
for await (const chunk of body) {
|
||||
if (data.size > 0 && accumBytes + chunk.length > data.size) {
|
||||
const error = new FetchError(`content size at ${data.url} over limit: ${data.size}`, 'max-size');
|
||||
body.destroy(error);
|
||||
throw error;
|
||||
}
|
||||
|
||||
accumBytes += chunk.length;
|
||||
accum.push(chunk);
|
||||
}
|
||||
} catch (error) {
|
||||
const error_ = error instanceof FetchBaseError ? error : new FetchError(`Invalid response body while trying to fetch ${data.url}: ${error.message}`, 'system', error);
|
||||
throw error_;
|
||||
}
|
||||
|
||||
if (body.readableEnded === true || body._readableState.ended === true) {
|
||||
try {
|
||||
if (accum.every(c => typeof c === 'string')) {
|
||||
return Buffer.from(accum.join(''));
|
||||
}
|
||||
|
||||
return Buffer.concat(accum, accumBytes);
|
||||
} catch (error) {
|
||||
throw new FetchError(`Could not create Buffer from response body for ${data.url}: ${error.message}`, 'system', error);
|
||||
}
|
||||
} else {
|
||||
throw new FetchError(`Premature close of server response while trying to fetch ${data.url}`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clone body given Res/Req instance
|
||||
*
|
||||
* @param Mixed instance Response or Request instance
|
||||
* @param String highWaterMark highWaterMark for both PassThrough body streams
|
||||
* @return Mixed
|
||||
*/
|
||||
export const clone = (instance, highWaterMark) => {
|
||||
let p1;
|
||||
let p2;
|
||||
let {body} = instance[INTERNALS];
|
||||
|
||||
// Don't allow cloning a used body
|
||||
if (instance.bodyUsed) {
|
||||
throw new Error('cannot clone body after it is used');
|
||||
}
|
||||
|
||||
// Check that body is a stream and not form-data object
|
||||
// note: we can't clone the form-data object without having it as a dependency
|
||||
if ((body instanceof Stream) && (typeof body.getBoundary !== 'function')) {
|
||||
// Tee instance body
|
||||
p1 = new PassThrough({highWaterMark});
|
||||
p2 = new PassThrough({highWaterMark});
|
||||
body.pipe(p1);
|
||||
body.pipe(p2);
|
||||
// Set instance body to teed body and return the other teed body
|
||||
instance[INTERNALS].stream = p1;
|
||||
body = p2;
|
||||
}
|
||||
|
||||
return body;
|
||||
};
|
||||
|
||||
const getNonSpecFormDataBoundary = deprecate(
|
||||
body => body.getBoundary(),
|
||||
'form-data doesn\'t follow the spec and requires special treatment. Use alternative package',
|
||||
'https://github.com/node-fetch/node-fetch/issues/1167'
|
||||
);
|
||||
|
||||
/**
|
||||
* Performs the operation "extract a `Content-Type` value from |object|" as
|
||||
* specified in the specification:
|
||||
* https://fetch.spec.whatwg.org/#concept-bodyinit-extract
|
||||
*
|
||||
* This function assumes that instance.body is present.
|
||||
*
|
||||
* @param {any} body Any options.body input
|
||||
* @returns {string | null}
|
||||
*/
|
||||
export const extractContentType = (body, request) => {
|
||||
// Body is null or undefined
|
||||
if (body === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Body is string
|
||||
if (typeof body === 'string') {
|
||||
return 'text/plain;charset=UTF-8';
|
||||
}
|
||||
|
||||
// Body is a URLSearchParams
|
||||
if (isURLSearchParameters(body)) {
|
||||
return 'application/x-www-form-urlencoded;charset=UTF-8';
|
||||
}
|
||||
|
||||
// Body is blob
|
||||
if (isBlob(body)) {
|
||||
return body.type || null;
|
||||
}
|
||||
|
||||
// Body is a Buffer (Buffer, ArrayBuffer or ArrayBufferView)
|
||||
if (Buffer.isBuffer(body) || types.isAnyArrayBuffer(body) || ArrayBuffer.isView(body)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (body instanceof FormData) {
|
||||
return `multipart/form-data; boundary=${request[INTERNALS].boundary}`;
|
||||
}
|
||||
|
||||
// Detect form data input from form-data module
|
||||
if (body && typeof body.getBoundary === 'function') {
|
||||
return `multipart/form-data;boundary=${getNonSpecFormDataBoundary(body)}`;
|
||||
}
|
||||
|
||||
// Body is stream - can't really do much about this
|
||||
if (body instanceof Stream) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Body constructor defaults other things to string
|
||||
return 'text/plain;charset=UTF-8';
|
||||
};
|
||||
|
||||
/**
|
||||
* The Fetch Standard treats this as if "total bytes" is a property on the body.
|
||||
* For us, we have to explicitly get it with a function.
|
||||
*
|
||||
* ref: https://fetch.spec.whatwg.org/#concept-body-total-bytes
|
||||
*
|
||||
* @param {any} obj.body Body object from the Body instance.
|
||||
* @returns {number | null}
|
||||
*/
|
||||
export const getTotalBytes = request => {
|
||||
const {body} = request[INTERNALS];
|
||||
|
||||
// Body is null or undefined
|
||||
if (body === null) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Body is Blob
|
||||
if (isBlob(body)) {
|
||||
return body.size;
|
||||
}
|
||||
|
||||
// Body is Buffer
|
||||
if (Buffer.isBuffer(body)) {
|
||||
return body.length;
|
||||
}
|
||||
|
||||
// Detect form data input from form-data module
|
||||
if (body && typeof body.getLengthSync === 'function') {
|
||||
return body.hasKnownLength && body.hasKnownLength() ? body.getLengthSync() : null;
|
||||
}
|
||||
|
||||
// Body is stream
|
||||
return null;
|
||||
};
|
||||
|
||||
/**
|
||||
* Write a Body to a Node.js WritableStream (e.g. http.Request) object.
|
||||
*
|
||||
* @param {Stream.Writable} dest The stream to write to.
|
||||
* @param obj.body Body object from the Body instance.
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
export const writeToStream = async (dest, {body}) => {
|
||||
if (body === null) {
|
||||
// Body is null
|
||||
dest.end();
|
||||
} else {
|
||||
// Body is stream
|
||||
await pipeline(body, dest);
|
||||
}
|
||||
};
|
||||
10
_shared/lib/node-fetch/src/errors/abort-error.js
Normal file
10
_shared/lib/node-fetch/src/errors/abort-error.js
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
import {FetchBaseError} from './base.js';
|
||||
|
||||
/**
|
||||
* AbortError interface for cancelled requests
|
||||
*/
|
||||
export class AbortError extends FetchBaseError {
|
||||
constructor(message, type = 'aborted') {
|
||||
super(message, type);
|
||||
}
|
||||
}
|
||||
17
_shared/lib/node-fetch/src/errors/base.js
Normal file
17
_shared/lib/node-fetch/src/errors/base.js
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
export class FetchBaseError extends Error {
|
||||
constructor(message, type) {
|
||||
super(message);
|
||||
// Hide custom error implementation details from end-users
|
||||
Error.captureStackTrace(this, this.constructor);
|
||||
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
get name() {
|
||||
return this.constructor.name;
|
||||
}
|
||||
|
||||
get [Symbol.toStringTag]() {
|
||||
return this.constructor.name;
|
||||
}
|
||||
}
|
||||
26
_shared/lib/node-fetch/src/errors/fetch-error.js
Normal file
26
_shared/lib/node-fetch/src/errors/fetch-error.js
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
|
||||
import {FetchBaseError} from './base.js';
|
||||
|
||||
/**
|
||||
* @typedef {{ address?: string, code: string, dest?: string, errno: number, info?: object, message: string, path?: string, port?: number, syscall: string}} SystemError
|
||||
*/
|
||||
|
||||
/**
|
||||
* FetchError interface for operational errors
|
||||
*/
|
||||
export class FetchError extends FetchBaseError {
|
||||
/**
|
||||
* @param {string} message - Error message for human
|
||||
* @param {string} [type] - Error type for machine
|
||||
* @param {SystemError} [systemError] - For Node.js system error
|
||||
*/
|
||||
constructor(message, type, systemError) {
|
||||
super(message, type);
|
||||
// When err.type is `system`, err.erroredSysCall contains system error and err.code contains system error code
|
||||
if (systemError) {
|
||||
// eslint-disable-next-line no-multi-assign
|
||||
this.code = this.errno = systemError.code;
|
||||
this.erroredSysCall = systemError.syscall;
|
||||
}
|
||||
}
|
||||
}
|
||||
267
_shared/lib/node-fetch/src/headers.js
Normal file
267
_shared/lib/node-fetch/src/headers.js
Normal file
|
|
@ -0,0 +1,267 @@
|
|||
/**
|
||||
* Headers.js
|
||||
*
|
||||
* Headers class offers convenient helpers
|
||||
*/
|
||||
|
||||
import {types} from 'node:util';
|
||||
import http from 'node:http';
|
||||
|
||||
/* c8 ignore next 9 */
|
||||
const validateHeaderName = typeof http.validateHeaderName === 'function' ?
|
||||
http.validateHeaderName :
|
||||
name => {
|
||||
if (!/^[\^`\-\w!#$%&'*+.|~]+$/.test(name)) {
|
||||
const error = new TypeError(`Header name must be a valid HTTP token [${name}]`);
|
||||
Object.defineProperty(error, 'code', {value: 'ERR_INVALID_HTTP_TOKEN'});
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
/* c8 ignore next 9 */
|
||||
const validateHeaderValue = typeof http.validateHeaderValue === 'function' ?
|
||||
http.validateHeaderValue :
|
||||
(name, value) => {
|
||||
if (/[^\t\u0020-\u007E\u0080-\u00FF]/.test(value)) {
|
||||
const error = new TypeError(`Invalid character in header content ["${name}"]`);
|
||||
Object.defineProperty(error, 'code', {value: 'ERR_INVALID_CHAR'});
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @typedef {Headers | Record<string, string> | Iterable<readonly [string, string]> | Iterable<Iterable<string>>} HeadersInit
|
||||
*/
|
||||
|
||||
/**
|
||||
* This Fetch API interface allows you to perform various actions on HTTP request and response headers.
|
||||
* These actions include retrieving, setting, adding to, and removing.
|
||||
* A Headers object has an associated header list, which is initially empty and consists of zero or more name and value pairs.
|
||||
* You can add to this using methods like append() (see Examples.)
|
||||
* In all methods of this interface, header names are matched by case-insensitive byte sequence.
|
||||
*
|
||||
*/
|
||||
export default class Headers extends URLSearchParams {
|
||||
/**
|
||||
* Headers class
|
||||
*
|
||||
* @constructor
|
||||
* @param {HeadersInit} [init] - Response headers
|
||||
*/
|
||||
constructor(init) {
|
||||
// Validate and normalize init object in [name, value(s)][]
|
||||
/** @type {string[][]} */
|
||||
let result = [];
|
||||
if (init instanceof Headers) {
|
||||
const raw = init.raw();
|
||||
for (const [name, values] of Object.entries(raw)) {
|
||||
result.push(...values.map(value => [name, value]));
|
||||
}
|
||||
} else if (init == null) { // eslint-disable-line no-eq-null, eqeqeq
|
||||
// No op
|
||||
} else if (typeof init === 'object' && !types.isBoxedPrimitive(init)) {
|
||||
const method = init[Symbol.iterator];
|
||||
// eslint-disable-next-line no-eq-null, eqeqeq
|
||||
if (method == null) {
|
||||
// Record<ByteString, ByteString>
|
||||
result.push(...Object.entries(init));
|
||||
} else {
|
||||
if (typeof method !== 'function') {
|
||||
throw new TypeError('Header pairs must be iterable');
|
||||
}
|
||||
|
||||
// Sequence<sequence<ByteString>>
|
||||
// Note: per spec we have to first exhaust the lists then process them
|
||||
result = [...init]
|
||||
.map(pair => {
|
||||
if (
|
||||
typeof pair !== 'object' || types.isBoxedPrimitive(pair)
|
||||
) {
|
||||
throw new TypeError('Each header pair must be an iterable object');
|
||||
}
|
||||
|
||||
return [...pair];
|
||||
}).map(pair => {
|
||||
if (pair.length !== 2) {
|
||||
throw new TypeError('Each header pair must be a name/value tuple');
|
||||
}
|
||||
|
||||
return [...pair];
|
||||
});
|
||||
}
|
||||
} else {
|
||||
throw new TypeError('Failed to construct \'Headers\': The provided value is not of type \'(sequence<sequence<ByteString>> or record<ByteString, ByteString>)');
|
||||
}
|
||||
|
||||
// Validate and lowercase
|
||||
result =
|
||||
result.length > 0 ?
|
||||
result.map(([name, value]) => {
|
||||
validateHeaderName(name);
|
||||
validateHeaderValue(name, String(value));
|
||||
return [String(name).toLowerCase(), String(value)];
|
||||
}) :
|
||||
undefined;
|
||||
|
||||
super(result);
|
||||
|
||||
// Returning a Proxy that will lowercase key names, validate parameters and sort keys
|
||||
// eslint-disable-next-line no-constructor-return
|
||||
return new Proxy(this, {
|
||||
get(target, p, receiver) {
|
||||
switch (p) {
|
||||
case 'append':
|
||||
case 'set':
|
||||
return (name, value) => {
|
||||
validateHeaderName(name);
|
||||
validateHeaderValue(name, String(value));
|
||||
return URLSearchParams.prototype[p].call(
|
||||
target,
|
||||
String(name).toLowerCase(),
|
||||
String(value)
|
||||
);
|
||||
};
|
||||
|
||||
case 'delete':
|
||||
case 'has':
|
||||
case 'getAll':
|
||||
return name => {
|
||||
validateHeaderName(name);
|
||||
return URLSearchParams.prototype[p].call(
|
||||
target,
|
||||
String(name).toLowerCase()
|
||||
);
|
||||
};
|
||||
|
||||
case 'keys':
|
||||
return () => {
|
||||
target.sort();
|
||||
return new Set(URLSearchParams.prototype.keys.call(target)).keys();
|
||||
};
|
||||
|
||||
default:
|
||||
return Reflect.get(target, p, receiver);
|
||||
}
|
||||
}
|
||||
});
|
||||
/* c8 ignore next */
|
||||
}
|
||||
|
||||
get [Symbol.toStringTag]() {
|
||||
return this.constructor.name;
|
||||
}
|
||||
|
||||
toString() {
|
||||
return Object.prototype.toString.call(this);
|
||||
}
|
||||
|
||||
get(name) {
|
||||
const values = this.getAll(name);
|
||||
if (values.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
let value = values.join(', ');
|
||||
if (/^content-encoding$/i.test(name)) {
|
||||
value = value.toLowerCase();
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
forEach(callback, thisArg = undefined) {
|
||||
for (const name of this.keys()) {
|
||||
Reflect.apply(callback, thisArg, [this.get(name), name, this]);
|
||||
}
|
||||
}
|
||||
|
||||
* values() {
|
||||
for (const name of this.keys()) {
|
||||
yield this.get(name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @type {() => IterableIterator<[string, string]>}
|
||||
*/
|
||||
* entries() {
|
||||
for (const name of this.keys()) {
|
||||
yield [name, this.get(name)];
|
||||
}
|
||||
}
|
||||
|
||||
[Symbol.iterator]() {
|
||||
return this.entries();
|
||||
}
|
||||
|
||||
/**
|
||||
* Node-fetch non-spec method
|
||||
* returning all headers and their values as array
|
||||
* @returns {Record<string, string[]>}
|
||||
*/
|
||||
raw() {
|
||||
return [...this.keys()].reduce((result, key) => {
|
||||
result[key] = this.getAll(key);
|
||||
return result;
|
||||
}, {});
|
||||
}
|
||||
|
||||
/**
|
||||
* For better console.log(headers) and also to convert Headers into Node.js Request compatible format
|
||||
*/
|
||||
[Symbol.for('nodejs.util.inspect.custom')]() {
|
||||
return [...this.keys()].reduce((result, key) => {
|
||||
const values = this.getAll(key);
|
||||
// Http.request() only supports string as Host header.
|
||||
// This hack makes specifying custom Host header possible.
|
||||
if (key === 'host') {
|
||||
result[key] = values[0];
|
||||
} else {
|
||||
result[key] = values.length > 1 ? values : values[0];
|
||||
}
|
||||
|
||||
return result;
|
||||
}, {});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Re-shaping object for Web IDL tests
|
||||
* Only need to do it for overridden methods
|
||||
*/
|
||||
Object.defineProperties(
|
||||
Headers.prototype,
|
||||
['get', 'entries', 'forEach', 'values'].reduce((result, property) => {
|
||||
result[property] = {enumerable: true};
|
||||
return result;
|
||||
}, {})
|
||||
);
|
||||
|
||||
/**
|
||||
* Create a Headers object from an http.IncomingMessage.rawHeaders, ignoring those that do
|
||||
* not conform to HTTP grammar productions.
|
||||
* @param {import('http').IncomingMessage['rawHeaders']} headers
|
||||
*/
|
||||
export function fromRawHeaders(headers = []) {
|
||||
return new Headers(
|
||||
headers
|
||||
// Split into pairs
|
||||
.reduce((result, value, index, array) => {
|
||||
if (index % 2 === 0) {
|
||||
result.push(array.slice(index, index + 2));
|
||||
}
|
||||
|
||||
return result;
|
||||
}, [])
|
||||
.filter(([name, value]) => {
|
||||
try {
|
||||
validateHeaderName(name);
|
||||
validateHeaderValue(name, String(value));
|
||||
return true;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
})
|
||||
|
||||
);
|
||||
}
|
||||
417
_shared/lib/node-fetch/src/index.js
Normal file
417
_shared/lib/node-fetch/src/index.js
Normal file
|
|
@ -0,0 +1,417 @@
|
|||
/**
|
||||
* Index.js
|
||||
*
|
||||
* a request API compatible with window.fetch
|
||||
*
|
||||
* All spec algorithm step numbers are based on https://fetch.spec.whatwg.org/commit-snapshots/ae716822cb3a61843226cd090eefc6589446c1d2/.
|
||||
*/
|
||||
|
||||
import http from 'node:http';
|
||||
import https from 'node:https';
|
||||
import zlib from 'node:zlib';
|
||||
import Stream, {PassThrough, pipeline as pump} from 'node:stream';
|
||||
import {Buffer} from 'node:buffer';
|
||||
|
||||
import dataUriToBuffer from 'data-uri-to-buffer';
|
||||
|
||||
import {writeToStream, clone} from './body.js';
|
||||
import Response from './response.js';
|
||||
import Headers, {fromRawHeaders} from './headers.js';
|
||||
import Request, {getNodeRequestOptions} from './request.js';
|
||||
import {FetchError} from './errors/fetch-error.js';
|
||||
import {AbortError} from './errors/abort-error.js';
|
||||
import {isRedirect} from './utils/is-redirect.js';
|
||||
import {FormData} from 'formdata-polyfill/esm.min.js';
|
||||
import {isDomainOrSubdomain, isSameProtocol} from './utils/is.js';
|
||||
import {parseReferrerPolicyFromHeader} from './utils/referrer.js';
|
||||
import {
|
||||
Blob,
|
||||
File,
|
||||
fileFromSync,
|
||||
fileFrom,
|
||||
blobFromSync,
|
||||
blobFrom
|
||||
} from 'fetch-blob/from.js';
|
||||
|
||||
export {FormData, Headers, Request, Response, FetchError, AbortError, isRedirect};
|
||||
export {Blob, File, fileFromSync, fileFrom, blobFromSync, blobFrom};
|
||||
|
||||
const supportedSchemas = new Set(['data:', 'http:', 'https:']);
|
||||
|
||||
/**
|
||||
* Fetch function
|
||||
*
|
||||
* @param {string | URL | import('./request').default} url - Absolute url or Request instance
|
||||
* @param {*} [options_] - Fetch options
|
||||
* @return {Promise<import('./response').default>}
|
||||
*/
|
||||
export default async function fetch(url, options_) {
|
||||
return new Promise((resolve, reject) => {
|
||||
// Build request object
|
||||
const request = new Request(url, options_);
|
||||
const {parsedURL, options} = getNodeRequestOptions(request);
|
||||
if (!supportedSchemas.has(parsedURL.protocol)) {
|
||||
throw new TypeError(`node-fetch cannot load ${url}. URL scheme "${parsedURL.protocol.replace(/:$/, '')}" is not supported.`);
|
||||
}
|
||||
|
||||
if (parsedURL.protocol === 'data:') {
|
||||
const data = dataUriToBuffer(request.url);
|
||||
const response = new Response(data, {headers: {'Content-Type': data.typeFull}});
|
||||
resolve(response);
|
||||
return;
|
||||
}
|
||||
|
||||
// Wrap http.request into fetch
|
||||
const send = (parsedURL.protocol === 'https:' ? https : http).request;
|
||||
const {signal} = request;
|
||||
let response = null;
|
||||
|
||||
const abort = () => {
|
||||
const error = new AbortError('The operation was aborted.');
|
||||
reject(error);
|
||||
if (request.body && request.body instanceof Stream.Readable) {
|
||||
request.body.destroy(error);
|
||||
}
|
||||
|
||||
if (!response || !response.body) {
|
||||
return;
|
||||
}
|
||||
|
||||
response.body.emit('error', error);
|
||||
};
|
||||
|
||||
if (signal && signal.aborted) {
|
||||
abort();
|
||||
return;
|
||||
}
|
||||
|
||||
const abortAndFinalize = () => {
|
||||
abort();
|
||||
finalize();
|
||||
};
|
||||
|
||||
// Send request
|
||||
const request_ = send(parsedURL.toString(), options);
|
||||
|
||||
if (signal) {
|
||||
signal.addEventListener('abort', abortAndFinalize);
|
||||
}
|
||||
|
||||
const finalize = () => {
|
||||
request_.abort();
|
||||
if (signal) {
|
||||
signal.removeEventListener('abort', abortAndFinalize);
|
||||
}
|
||||
};
|
||||
|
||||
request_.on('error', error => {
|
||||
reject(new FetchError(`request to ${request.url} failed, reason: ${error.message}`, 'system', error));
|
||||
finalize();
|
||||
});
|
||||
|
||||
fixResponseChunkedTransferBadEnding(request_, error => {
|
||||
if (response && response.body) {
|
||||
response.body.destroy(error);
|
||||
}
|
||||
});
|
||||
|
||||
/* c8 ignore next 18 */
|
||||
if (process.version < 'v14') {
|
||||
// Before Node.js 14, pipeline() does not fully support async iterators and does not always
|
||||
// properly handle when the socket close/end events are out of order.
|
||||
request_.on('socket', s => {
|
||||
let endedWithEventsCount;
|
||||
s.prependListener('end', () => {
|
||||
endedWithEventsCount = s._eventsCount;
|
||||
});
|
||||
s.prependListener('close', hadError => {
|
||||
// if end happened before close but the socket didn't emit an error, do it now
|
||||
if (response && endedWithEventsCount < s._eventsCount && !hadError) {
|
||||
const error = new Error('Premature close');
|
||||
error.code = 'ERR_STREAM_PREMATURE_CLOSE';
|
||||
response.body.emit('error', error);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
request_.on('response', response_ => {
|
||||
request_.setTimeout(0);
|
||||
const headers = fromRawHeaders(response_.rawHeaders);
|
||||
|
||||
// HTTP fetch step 5
|
||||
if (isRedirect(response_.statusCode)) {
|
||||
// HTTP fetch step 5.2
|
||||
const location = headers.get('Location');
|
||||
|
||||
// HTTP fetch step 5.3
|
||||
let locationURL = null;
|
||||
try {
|
||||
locationURL = location === null ? null : new URL(location, request.url);
|
||||
} catch {
|
||||
// error here can only be invalid URL in Location: header
|
||||
// do not throw when options.redirect == manual
|
||||
// let the user extract the errorneous redirect URL
|
||||
if (request.redirect !== 'manual') {
|
||||
reject(new FetchError(`uri requested responds with an invalid redirect URL: ${location}`, 'invalid-redirect'));
|
||||
finalize();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// HTTP fetch step 5.5
|
||||
switch (request.redirect) {
|
||||
case 'error':
|
||||
reject(new FetchError(`uri requested responds with a redirect, redirect mode is set to error: ${request.url}`, 'no-redirect'));
|
||||
finalize();
|
||||
return;
|
||||
case 'manual':
|
||||
// Nothing to do
|
||||
break;
|
||||
case 'follow': {
|
||||
// HTTP-redirect fetch step 2
|
||||
if (locationURL === null) {
|
||||
break;
|
||||
}
|
||||
|
||||
// HTTP-redirect fetch step 5
|
||||
if (request.counter >= request.follow) {
|
||||
reject(new FetchError(`maximum redirect reached at: ${request.url}`, 'max-redirect'));
|
||||
finalize();
|
||||
return;
|
||||
}
|
||||
|
||||
// HTTP-redirect fetch step 6 (counter increment)
|
||||
// Create a new Request object.
|
||||
const requestOptions = {
|
||||
headers: new Headers(request.headers),
|
||||
follow: request.follow,
|
||||
counter: request.counter + 1,
|
||||
agent: request.agent,
|
||||
compress: request.compress,
|
||||
method: request.method,
|
||||
body: clone(request),
|
||||
signal: request.signal,
|
||||
size: request.size,
|
||||
referrer: request.referrer,
|
||||
referrerPolicy: request.referrerPolicy
|
||||
};
|
||||
|
||||
// when forwarding sensitive headers like "Authorization",
|
||||
// "WWW-Authenticate", and "Cookie" to untrusted targets,
|
||||
// headers will be ignored when following a redirect to a domain
|
||||
// that is not a subdomain match or exact match of the initial domain.
|
||||
// For example, a redirect from "foo.com" to either "foo.com" or "sub.foo.com"
|
||||
// will forward the sensitive headers, but a redirect to "bar.com" will not.
|
||||
// headers will also be ignored when following a redirect to a domain using
|
||||
// a different protocol. For example, a redirect from "https://foo.com" to "http://foo.com"
|
||||
// will not forward the sensitive headers
|
||||
if (!isDomainOrSubdomain(request.url, locationURL) || !isSameProtocol(request.url, locationURL)) {
|
||||
for (const name of ['authorization', 'www-authenticate', 'cookie', 'cookie2']) {
|
||||
requestOptions.headers.delete(name);
|
||||
}
|
||||
}
|
||||
|
||||
// HTTP-redirect fetch step 9
|
||||
if (response_.statusCode !== 303 && request.body && options_.body instanceof Stream.Readable) {
|
||||
reject(new FetchError('Cannot follow redirect with body being a readable stream', 'unsupported-redirect'));
|
||||
finalize();
|
||||
return;
|
||||
}
|
||||
|
||||
// HTTP-redirect fetch step 11
|
||||
if (response_.statusCode === 303 || ((response_.statusCode === 301 || response_.statusCode === 302) && request.method === 'POST')) {
|
||||
requestOptions.method = 'GET';
|
||||
requestOptions.body = undefined;
|
||||
requestOptions.headers.delete('content-length');
|
||||
}
|
||||
|
||||
// HTTP-redirect fetch step 14
|
||||
const responseReferrerPolicy = parseReferrerPolicyFromHeader(headers);
|
||||
if (responseReferrerPolicy) {
|
||||
requestOptions.referrerPolicy = responseReferrerPolicy;
|
||||
}
|
||||
|
||||
// HTTP-redirect fetch step 15
|
||||
resolve(fetch(new Request(locationURL, requestOptions)));
|
||||
finalize();
|
||||
return;
|
||||
}
|
||||
|
||||
default:
|
||||
return reject(new TypeError(`Redirect option '${request.redirect}' is not a valid value of RequestRedirect`));
|
||||
}
|
||||
}
|
||||
|
||||
// Prepare response
|
||||
if (signal) {
|
||||
response_.once('end', () => {
|
||||
signal.removeEventListener('abort', abortAndFinalize);
|
||||
});
|
||||
}
|
||||
|
||||
let body = pump(response_, new PassThrough(), error => {
|
||||
if (error) {
|
||||
reject(error);
|
||||
}
|
||||
});
|
||||
// see https://github.com/nodejs/node/pull/29376
|
||||
/* c8 ignore next 3 */
|
||||
if (process.version < 'v12.10') {
|
||||
response_.on('aborted', abortAndFinalize);
|
||||
}
|
||||
|
||||
const responseOptions = {
|
||||
url: request.url,
|
||||
status: response_.statusCode,
|
||||
statusText: response_.statusMessage,
|
||||
headers,
|
||||
size: request.size,
|
||||
counter: request.counter,
|
||||
highWaterMark: request.highWaterMark
|
||||
};
|
||||
|
||||
// HTTP-network fetch step 12.1.1.3
|
||||
const codings = headers.get('Content-Encoding');
|
||||
|
||||
// HTTP-network fetch step 12.1.1.4: handle content codings
|
||||
|
||||
// in following scenarios we ignore compression support
|
||||
// 1. compression support is disabled
|
||||
// 2. HEAD request
|
||||
// 3. no Content-Encoding header
|
||||
// 4. no content response (204)
|
||||
// 5. content not modified response (304)
|
||||
if (!request.compress || request.method === 'HEAD' || codings === null || response_.statusCode === 204 || response_.statusCode === 304) {
|
||||
response = new Response(body, responseOptions);
|
||||
resolve(response);
|
||||
return;
|
||||
}
|
||||
|
||||
// For Node v6+
|
||||
// Be less strict when decoding compressed responses, since sometimes
|
||||
// servers send slightly invalid responses that are still accepted
|
||||
// by common browsers.
|
||||
// Always using Z_SYNC_FLUSH is what cURL does.
|
||||
const zlibOptions = {
|
||||
flush: zlib.Z_SYNC_FLUSH,
|
||||
finishFlush: zlib.Z_SYNC_FLUSH
|
||||
};
|
||||
|
||||
// For gzip
|
||||
if (codings === 'gzip' || codings === 'x-gzip') {
|
||||
body = pump(body, zlib.createGunzip(zlibOptions), error => {
|
||||
if (error) {
|
||||
reject(error);
|
||||
}
|
||||
});
|
||||
response = new Response(body, responseOptions);
|
||||
resolve(response);
|
||||
return;
|
||||
}
|
||||
|
||||
// For deflate
|
||||
if (codings === 'deflate' || codings === 'x-deflate') {
|
||||
// Handle the infamous raw deflate response from old servers
|
||||
// a hack for old IIS and Apache servers
|
||||
const raw = pump(response_, new PassThrough(), error => {
|
||||
if (error) {
|
||||
reject(error);
|
||||
}
|
||||
});
|
||||
raw.once('data', chunk => {
|
||||
// See http://stackoverflow.com/questions/37519828
|
||||
if ((chunk[0] & 0x0F) === 0x08) {
|
||||
body = pump(body, zlib.createInflate(), error => {
|
||||
if (error) {
|
||||
reject(error);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
body = pump(body, zlib.createInflateRaw(), error => {
|
||||
if (error) {
|
||||
reject(error);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
response = new Response(body, responseOptions);
|
||||
resolve(response);
|
||||
});
|
||||
raw.once('end', () => {
|
||||
// Some old IIS servers return zero-length OK deflate responses, so
|
||||
// 'data' is never emitted. See https://github.com/node-fetch/node-fetch/pull/903
|
||||
if (!response) {
|
||||
response = new Response(body, responseOptions);
|
||||
resolve(response);
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// For br
|
||||
if (codings === 'br') {
|
||||
body = pump(body, zlib.createBrotliDecompress(), error => {
|
||||
if (error) {
|
||||
reject(error);
|
||||
}
|
||||
});
|
||||
response = new Response(body, responseOptions);
|
||||
resolve(response);
|
||||
return;
|
||||
}
|
||||
|
||||
// Otherwise, use response as-is
|
||||
response = new Response(body, responseOptions);
|
||||
resolve(response);
|
||||
});
|
||||
|
||||
// eslint-disable-next-line promise/prefer-await-to-then
|
||||
writeToStream(request_, request).catch(reject);
|
||||
});
|
||||
}
|
||||
|
||||
function fixResponseChunkedTransferBadEnding(request, errorCallback) {
|
||||
const LAST_CHUNK = Buffer.from('0\r\n\r\n');
|
||||
|
||||
let isChunkedTransfer = false;
|
||||
let properLastChunkReceived = false;
|
||||
let previousChunk;
|
||||
|
||||
request.on('response', response => {
|
||||
const {headers} = response;
|
||||
isChunkedTransfer = headers['transfer-encoding'] === 'chunked' && !headers['content-length'];
|
||||
});
|
||||
|
||||
request.on('socket', socket => {
|
||||
const onSocketClose = () => {
|
||||
if (isChunkedTransfer && !properLastChunkReceived) {
|
||||
const error = new Error('Premature close');
|
||||
error.code = 'ERR_STREAM_PREMATURE_CLOSE';
|
||||
errorCallback(error);
|
||||
}
|
||||
};
|
||||
|
||||
const onData = buf => {
|
||||
properLastChunkReceived = Buffer.compare(buf.slice(-5), LAST_CHUNK) === 0;
|
||||
|
||||
// Sometimes final 0-length chunk and end of message code are in separate packets
|
||||
if (!properLastChunkReceived && previousChunk) {
|
||||
properLastChunkReceived = (
|
||||
Buffer.compare(previousChunk.slice(-3), LAST_CHUNK.slice(0, 3)) === 0 &&
|
||||
Buffer.compare(buf.slice(-2), LAST_CHUNK.slice(3)) === 0
|
||||
);
|
||||
}
|
||||
|
||||
previousChunk = buf;
|
||||
};
|
||||
|
||||
socket.prependListener('close', onSocketClose);
|
||||
socket.on('data', onData);
|
||||
|
||||
request.on('close', () => {
|
||||
socket.removeListener('close', onSocketClose);
|
||||
socket.removeListener('data', onData);
|
||||
});
|
||||
});
|
||||
}
|
||||
313
_shared/lib/node-fetch/src/request.js
Normal file
313
_shared/lib/node-fetch/src/request.js
Normal file
|
|
@ -0,0 +1,313 @@
|
|||
/**
|
||||
* Request.js
|
||||
*
|
||||
* Request class contains server only options
|
||||
*
|
||||
* All spec algorithm step numbers are based on https://fetch.spec.whatwg.org/commit-snapshots/ae716822cb3a61843226cd090eefc6589446c1d2/.
|
||||
*/
|
||||
|
||||
import {format as formatUrl} from 'node:url';
|
||||
import {deprecate} from 'node:util';
|
||||
import Headers from './headers.js';
|
||||
import Body, {clone, extractContentType, getTotalBytes} from './body.js';
|
||||
import {isAbortSignal} from './utils/is.js';
|
||||
import {getSearch} from './utils/get-search.js';
|
||||
import {
|
||||
validateReferrerPolicy, determineRequestsReferrer, DEFAULT_REFERRER_POLICY
|
||||
} from './utils/referrer.js';
|
||||
|
||||
const INTERNALS = Symbol('Request internals');
|
||||
|
||||
/**
|
||||
* Check if `obj` is an instance of Request.
|
||||
*
|
||||
* @param {*} object
|
||||
* @return {boolean}
|
||||
*/
|
||||
const isRequest = object => {
|
||||
return (
|
||||
typeof object === 'object' &&
|
||||
typeof object[INTERNALS] === 'object'
|
||||
);
|
||||
};
|
||||
|
||||
const doBadDataWarn = deprecate(() => {},
|
||||
'.data is not a valid RequestInit property, use .body instead',
|
||||
'https://github.com/node-fetch/node-fetch/issues/1000 (request)');
|
||||
|
||||
/**
|
||||
* Request class
|
||||
*
|
||||
* Ref: https://fetch.spec.whatwg.org/#request-class
|
||||
*
|
||||
* @param Mixed input Url or Request instance
|
||||
* @param Object init Custom options
|
||||
* @return Void
|
||||
*/
|
||||
export default class Request extends Body {
|
||||
constructor(input, init = {}) {
|
||||
let parsedURL;
|
||||
|
||||
// Normalize input and force URL to be encoded as UTF-8 (https://github.com/node-fetch/node-fetch/issues/245)
|
||||
if (isRequest(input)) {
|
||||
parsedURL = new URL(input.url);
|
||||
} else {
|
||||
parsedURL = new URL(input);
|
||||
input = {};
|
||||
}
|
||||
|
||||
if (parsedURL.username !== '' || parsedURL.password !== '') {
|
||||
throw new TypeError(`${parsedURL} is an url with embedded credentials.`);
|
||||
}
|
||||
|
||||
let method = init.method || input.method || 'GET';
|
||||
if (/^(delete|get|head|options|post|put)$/i.test(method)) {
|
||||
method = method.toUpperCase();
|
||||
}
|
||||
|
||||
if (!isRequest(init) && 'data' in init) {
|
||||
doBadDataWarn();
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-eq-null, eqeqeq
|
||||
if ((init.body != null || (isRequest(input) && input.body !== null)) &&
|
||||
(method === 'GET' || method === 'HEAD')) {
|
||||
throw new TypeError('Request with GET/HEAD method cannot have body');
|
||||
}
|
||||
|
||||
const inputBody = init.body ?
|
||||
init.body :
|
||||
(isRequest(input) && input.body !== null ?
|
||||
clone(input) :
|
||||
null);
|
||||
|
||||
super(inputBody, {
|
||||
size: init.size || input.size || 0
|
||||
});
|
||||
|
||||
const headers = new Headers(init.headers || input.headers || {});
|
||||
|
||||
if (inputBody !== null && !headers.has('Content-Type')) {
|
||||
const contentType = extractContentType(inputBody, this);
|
||||
if (contentType) {
|
||||
headers.set('Content-Type', contentType);
|
||||
}
|
||||
}
|
||||
|
||||
let signal = isRequest(input) ?
|
||||
input.signal :
|
||||
null;
|
||||
if ('signal' in init) {
|
||||
signal = init.signal;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-eq-null, eqeqeq
|
||||
if (signal != null && !isAbortSignal(signal)) {
|
||||
throw new TypeError('Expected signal to be an instanceof AbortSignal or EventTarget');
|
||||
}
|
||||
|
||||
// §5.4, Request constructor steps, step 15.1
|
||||
// eslint-disable-next-line no-eq-null, eqeqeq
|
||||
let referrer = init.referrer == null ? input.referrer : init.referrer;
|
||||
if (referrer === '') {
|
||||
// §5.4, Request constructor steps, step 15.2
|
||||
referrer = 'no-referrer';
|
||||
} else if (referrer) {
|
||||
// §5.4, Request constructor steps, step 15.3.1, 15.3.2
|
||||
const parsedReferrer = new URL(referrer);
|
||||
// §5.4, Request constructor steps, step 15.3.3, 15.3.4
|
||||
referrer = /^about:(\/\/)?client$/.test(parsedReferrer) ? 'client' : parsedReferrer;
|
||||
} else {
|
||||
referrer = undefined;
|
||||
}
|
||||
|
||||
this[INTERNALS] = {
|
||||
method,
|
||||
redirect: init.redirect || input.redirect || 'follow',
|
||||
headers,
|
||||
parsedURL,
|
||||
signal,
|
||||
referrer
|
||||
};
|
||||
|
||||
// Node-fetch-only options
|
||||
this.follow = init.follow === undefined ? (input.follow === undefined ? 20 : input.follow) : init.follow;
|
||||
this.compress = init.compress === undefined ? (input.compress === undefined ? true : input.compress) : init.compress;
|
||||
this.counter = init.counter || input.counter || 0;
|
||||
this.agent = init.agent || input.agent;
|
||||
this.highWaterMark = init.highWaterMark || input.highWaterMark || 16384;
|
||||
this.insecureHTTPParser = init.insecureHTTPParser || input.insecureHTTPParser || false;
|
||||
|
||||
// §5.4, Request constructor steps, step 16.
|
||||
// Default is empty string per https://fetch.spec.whatwg.org/#concept-request-referrer-policy
|
||||
this.referrerPolicy = init.referrerPolicy || input.referrerPolicy || '';
|
||||
}
|
||||
|
||||
/** @returns {string} */
|
||||
get method() {
|
||||
return this[INTERNALS].method;
|
||||
}
|
||||
|
||||
/** @returns {string} */
|
||||
get url() {
|
||||
return formatUrl(this[INTERNALS].parsedURL);
|
||||
}
|
||||
|
||||
/** @returns {Headers} */
|
||||
get headers() {
|
||||
return this[INTERNALS].headers;
|
||||
}
|
||||
|
||||
get redirect() {
|
||||
return this[INTERNALS].redirect;
|
||||
}
|
||||
|
||||
/** @returns {AbortSignal} */
|
||||
get signal() {
|
||||
return this[INTERNALS].signal;
|
||||
}
|
||||
|
||||
// https://fetch.spec.whatwg.org/#dom-request-referrer
|
||||
get referrer() {
|
||||
if (this[INTERNALS].referrer === 'no-referrer') {
|
||||
return '';
|
||||
}
|
||||
|
||||
if (this[INTERNALS].referrer === 'client') {
|
||||
return 'about:client';
|
||||
}
|
||||
|
||||
if (this[INTERNALS].referrer) {
|
||||
return this[INTERNALS].referrer.toString();
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
get referrerPolicy() {
|
||||
return this[INTERNALS].referrerPolicy;
|
||||
}
|
||||
|
||||
set referrerPolicy(referrerPolicy) {
|
||||
this[INTERNALS].referrerPolicy = validateReferrerPolicy(referrerPolicy);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clone this request
|
||||
*
|
||||
* @return Request
|
||||
*/
|
||||
clone() {
|
||||
return new Request(this);
|
||||
}
|
||||
|
||||
get [Symbol.toStringTag]() {
|
||||
return 'Request';
|
||||
}
|
||||
}
|
||||
|
||||
Object.defineProperties(Request.prototype, {
|
||||
method: {enumerable: true},
|
||||
url: {enumerable: true},
|
||||
headers: {enumerable: true},
|
||||
redirect: {enumerable: true},
|
||||
clone: {enumerable: true},
|
||||
signal: {enumerable: true},
|
||||
referrer: {enumerable: true},
|
||||
referrerPolicy: {enumerable: true}
|
||||
});
|
||||
|
||||
/**
|
||||
* Convert a Request to Node.js http request options.
|
||||
*
|
||||
* @param {Request} request - A Request instance
|
||||
* @return The options object to be passed to http.request
|
||||
*/
|
||||
export const getNodeRequestOptions = request => {
|
||||
const {parsedURL} = request[INTERNALS];
|
||||
const headers = new Headers(request[INTERNALS].headers);
|
||||
|
||||
// Fetch step 1.3
|
||||
if (!headers.has('Accept')) {
|
||||
headers.set('Accept', '*/*');
|
||||
}
|
||||
|
||||
// HTTP-network-or-cache fetch steps 2.4-2.7
|
||||
let contentLengthValue = null;
|
||||
if (request.body === null && /^(post|put)$/i.test(request.method)) {
|
||||
contentLengthValue = '0';
|
||||
}
|
||||
|
||||
if (request.body !== null) {
|
||||
const totalBytes = getTotalBytes(request);
|
||||
// Set Content-Length if totalBytes is a number (that is not NaN)
|
||||
if (typeof totalBytes === 'number' && !Number.isNaN(totalBytes)) {
|
||||
contentLengthValue = String(totalBytes);
|
||||
}
|
||||
}
|
||||
|
||||
if (contentLengthValue) {
|
||||
headers.set('Content-Length', contentLengthValue);
|
||||
}
|
||||
|
||||
// 4.1. Main fetch, step 2.6
|
||||
// > If request's referrer policy is the empty string, then set request's referrer policy to the
|
||||
// > default referrer policy.
|
||||
if (request.referrerPolicy === '') {
|
||||
request.referrerPolicy = DEFAULT_REFERRER_POLICY;
|
||||
}
|
||||
|
||||
// 4.1. Main fetch, step 2.7
|
||||
// > If request's referrer is not "no-referrer", set request's referrer to the result of invoking
|
||||
// > determine request's referrer.
|
||||
if (request.referrer && request.referrer !== 'no-referrer') {
|
||||
request[INTERNALS].referrer = determineRequestsReferrer(request);
|
||||
} else {
|
||||
request[INTERNALS].referrer = 'no-referrer';
|
||||
}
|
||||
|
||||
// 4.5. HTTP-network-or-cache fetch, step 6.9
|
||||
// > If httpRequest's referrer is a URL, then append `Referer`/httpRequest's referrer, serialized
|
||||
// > and isomorphic encoded, to httpRequest's header list.
|
||||
if (request[INTERNALS].referrer instanceof URL) {
|
||||
headers.set('Referer', request.referrer);
|
||||
}
|
||||
|
||||
// HTTP-network-or-cache fetch step 2.11
|
||||
if (!headers.has('User-Agent')) {
|
||||
headers.set('User-Agent', 'node-fetch');
|
||||
}
|
||||
|
||||
// HTTP-network-or-cache fetch step 2.15
|
||||
if (request.compress && !headers.has('Accept-Encoding')) {
|
||||
headers.set('Accept-Encoding', 'gzip, deflate, br');
|
||||
}
|
||||
|
||||
let {agent} = request;
|
||||
if (typeof agent === 'function') {
|
||||
agent = agent(parsedURL);
|
||||
}
|
||||
|
||||
// HTTP-network fetch step 4.2
|
||||
// chunked encoding is handled by Node.js
|
||||
|
||||
const search = getSearch(parsedURL);
|
||||
|
||||
// Pass the full URL directly to request(), but overwrite the following
|
||||
// options:
|
||||
const options = {
|
||||
// Overwrite search to retain trailing ? (issue #776)
|
||||
path: parsedURL.pathname + search,
|
||||
// The following options are not expressed in the URL
|
||||
method: request.method,
|
||||
headers: headers[Symbol.for('nodejs.util.inspect.custom')](),
|
||||
insecureHTTPParser: request.insecureHTTPParser,
|
||||
agent
|
||||
};
|
||||
|
||||
return {
|
||||
/** @type {URL} */
|
||||
parsedURL,
|
||||
options
|
||||
};
|
||||
};
|
||||
160
_shared/lib/node-fetch/src/response.js
Normal file
160
_shared/lib/node-fetch/src/response.js
Normal file
|
|
@ -0,0 +1,160 @@
|
|||
/**
|
||||
* Response.js
|
||||
*
|
||||
* Response class provides content decoding
|
||||
*/
|
||||
|
||||
import Headers from './headers.js';
|
||||
import Body, {clone, extractContentType} from './body.js';
|
||||
import {isRedirect} from './utils/is-redirect.js';
|
||||
|
||||
const INTERNALS = Symbol('Response internals');
|
||||
|
||||
/**
|
||||
* Response class
|
||||
*
|
||||
* Ref: https://fetch.spec.whatwg.org/#response-class
|
||||
*
|
||||
* @param Stream body Readable stream
|
||||
* @param Object opts Response options
|
||||
* @return Void
|
||||
*/
|
||||
export default class Response extends Body {
|
||||
constructor(body = null, options = {}) {
|
||||
super(body, options);
|
||||
|
||||
// eslint-disable-next-line no-eq-null, eqeqeq, no-negated-condition
|
||||
const status = options.status != null ? options.status : 200;
|
||||
|
||||
const headers = new Headers(options.headers);
|
||||
|
||||
if (body !== null && !headers.has('Content-Type')) {
|
||||
const contentType = extractContentType(body, this);
|
||||
if (contentType) {
|
||||
headers.append('Content-Type', contentType);
|
||||
}
|
||||
}
|
||||
|
||||
this[INTERNALS] = {
|
||||
type: 'default',
|
||||
url: options.url,
|
||||
status,
|
||||
statusText: options.statusText || '',
|
||||
headers,
|
||||
counter: options.counter,
|
||||
highWaterMark: options.highWaterMark
|
||||
};
|
||||
}
|
||||
|
||||
get type() {
|
||||
return this[INTERNALS].type;
|
||||
}
|
||||
|
||||
get url() {
|
||||
return this[INTERNALS].url || '';
|
||||
}
|
||||
|
||||
get status() {
|
||||
return this[INTERNALS].status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience property representing if the request ended normally
|
||||
*/
|
||||
get ok() {
|
||||
return this[INTERNALS].status >= 200 && this[INTERNALS].status < 300;
|
||||
}
|
||||
|
||||
get redirected() {
|
||||
return this[INTERNALS].counter > 0;
|
||||
}
|
||||
|
||||
get statusText() {
|
||||
return this[INTERNALS].statusText;
|
||||
}
|
||||
|
||||
get headers() {
|
||||
return this[INTERNALS].headers;
|
||||
}
|
||||
|
||||
get highWaterMark() {
|
||||
return this[INTERNALS].highWaterMark;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clone this response
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
clone() {
|
||||
return new Response(clone(this, this.highWaterMark), {
|
||||
type: this.type,
|
||||
url: this.url,
|
||||
status: this.status,
|
||||
statusText: this.statusText,
|
||||
headers: this.headers,
|
||||
ok: this.ok,
|
||||
redirected: this.redirected,
|
||||
size: this.size,
|
||||
highWaterMark: this.highWaterMark
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} url The URL that the new response is to originate from.
|
||||
* @param {number} status An optional status code for the response (e.g., 302.)
|
||||
* @returns {Response} A Response object.
|
||||
*/
|
||||
static redirect(url, status = 302) {
|
||||
if (!isRedirect(status)) {
|
||||
throw new RangeError('Failed to execute "redirect" on "response": Invalid status code');
|
||||
}
|
||||
|
||||
return new Response(null, {
|
||||
headers: {
|
||||
location: new URL(url).toString()
|
||||
},
|
||||
status
|
||||
});
|
||||
}
|
||||
|
||||
static error() {
|
||||
const response = new Response(null, {status: 0, statusText: ''});
|
||||
response[INTERNALS].type = 'error';
|
||||
return response;
|
||||
}
|
||||
|
||||
static json(data = undefined, init = {}) {
|
||||
const body = JSON.stringify(data);
|
||||
|
||||
if (body === undefined) {
|
||||
throw new TypeError('data is not JSON serializable');
|
||||
}
|
||||
|
||||
const headers = new Headers(init && init.headers);
|
||||
|
||||
if (!headers.has('content-type')) {
|
||||
headers.set('content-type', 'application/json');
|
||||
}
|
||||
|
||||
return new Response(body, {
|
||||
...init,
|
||||
headers
|
||||
});
|
||||
}
|
||||
|
||||
get [Symbol.toStringTag]() {
|
||||
return 'Response';
|
||||
}
|
||||
}
|
||||
|
||||
Object.defineProperties(Response.prototype, {
|
||||
type: {enumerable: true},
|
||||
url: {enumerable: true},
|
||||
status: {enumerable: true},
|
||||
ok: {enumerable: true},
|
||||
redirected: {enumerable: true},
|
||||
statusText: {enumerable: true},
|
||||
headers: {enumerable: true},
|
||||
clone: {enumerable: true}
|
||||
});
|
||||
9
_shared/lib/node-fetch/src/utils/get-search.js
Normal file
9
_shared/lib/node-fetch/src/utils/get-search.js
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
export const getSearch = parsedURL => {
|
||||
if (parsedURL.search) {
|
||||
return parsedURL.search;
|
||||
}
|
||||
|
||||
const lastOffset = parsedURL.href.length - 1;
|
||||
const hash = parsedURL.hash || (parsedURL.href[lastOffset] === '#' ? '#' : '');
|
||||
return parsedURL.href[lastOffset - hash.length] === '?' ? '?' : '';
|
||||
};
|
||||
11
_shared/lib/node-fetch/src/utils/is-redirect.js
Normal file
11
_shared/lib/node-fetch/src/utils/is-redirect.js
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
const redirectStatus = new Set([301, 302, 303, 307, 308]);
|
||||
|
||||
/**
|
||||
* Redirect code matching
|
||||
*
|
||||
* @param {number} code - Status code
|
||||
* @return {boolean}
|
||||
*/
|
||||
export const isRedirect = code => {
|
||||
return redirectStatus.has(code);
|
||||
};
|
||||
87
_shared/lib/node-fetch/src/utils/is.js
Normal file
87
_shared/lib/node-fetch/src/utils/is.js
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
/**
|
||||
* Is.js
|
||||
*
|
||||
* Object type checks.
|
||||
*/
|
||||
|
||||
const NAME = Symbol.toStringTag;
|
||||
|
||||
/**
|
||||
* Check if `obj` is a URLSearchParams object
|
||||
* ref: https://github.com/node-fetch/node-fetch/issues/296#issuecomment-307598143
|
||||
* @param {*} object - Object to check for
|
||||
* @return {boolean}
|
||||
*/
|
||||
export const isURLSearchParameters = object => {
|
||||
return (
|
||||
typeof object === 'object' &&
|
||||
typeof object.append === 'function' &&
|
||||
typeof object.delete === 'function' &&
|
||||
typeof object.get === 'function' &&
|
||||
typeof object.getAll === 'function' &&
|
||||
typeof object.has === 'function' &&
|
||||
typeof object.set === 'function' &&
|
||||
typeof object.sort === 'function' &&
|
||||
object[NAME] === 'URLSearchParams'
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if `object` is a W3C `Blob` object (which `File` inherits from)
|
||||
* @param {*} object - Object to check for
|
||||
* @return {boolean}
|
||||
*/
|
||||
export const isBlob = object => {
|
||||
return (
|
||||
object &&
|
||||
typeof object === 'object' &&
|
||||
typeof object.arrayBuffer === 'function' &&
|
||||
typeof object.type === 'string' &&
|
||||
typeof object.stream === 'function' &&
|
||||
typeof object.constructor === 'function' &&
|
||||
/^(Blob|File)$/.test(object[NAME])
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if `obj` is an instance of AbortSignal.
|
||||
* @param {*} object - Object to check for
|
||||
* @return {boolean}
|
||||
*/
|
||||
export const isAbortSignal = object => {
|
||||
return (
|
||||
typeof object === 'object' && (
|
||||
object[NAME] === 'AbortSignal' ||
|
||||
object[NAME] === 'EventTarget'
|
||||
)
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* isDomainOrSubdomain reports whether sub is a subdomain (or exact match) of
|
||||
* the parent domain.
|
||||
*
|
||||
* Both domains must already be in canonical form.
|
||||
* @param {string|URL} original
|
||||
* @param {string|URL} destination
|
||||
*/
|
||||
export const isDomainOrSubdomain = (destination, original) => {
|
||||
const orig = new URL(original).hostname;
|
||||
const dest = new URL(destination).hostname;
|
||||
|
||||
return orig === dest || orig.endsWith(`.${dest}`);
|
||||
};
|
||||
|
||||
/**
|
||||
* isSameProtocol reports whether the two provided URLs use the same protocol.
|
||||
*
|
||||
* Both domains must already be in canonical form.
|
||||
* @param {string|URL} original
|
||||
* @param {string|URL} destination
|
||||
*/
|
||||
export const isSameProtocol = (destination, original) => {
|
||||
const orig = new URL(original).protocol;
|
||||
const dest = new URL(destination).protocol;
|
||||
|
||||
return orig === dest;
|
||||
};
|
||||
432
_shared/lib/node-fetch/src/utils/multipart-parser.js
Normal file
432
_shared/lib/node-fetch/src/utils/multipart-parser.js
Normal file
|
|
@ -0,0 +1,432 @@
|
|||
import {File} from 'fetch-blob/from.js';
|
||||
import {FormData} from 'formdata-polyfill/esm.min.js';
|
||||
|
||||
let s = 0;
|
||||
const S = {
|
||||
START_BOUNDARY: s++,
|
||||
HEADER_FIELD_START: s++,
|
||||
HEADER_FIELD: s++,
|
||||
HEADER_VALUE_START: s++,
|
||||
HEADER_VALUE: s++,
|
||||
HEADER_VALUE_ALMOST_DONE: s++,
|
||||
HEADERS_ALMOST_DONE: s++,
|
||||
PART_DATA_START: s++,
|
||||
PART_DATA: s++,
|
||||
END: s++
|
||||
};
|
||||
|
||||
let f = 1;
|
||||
const F = {
|
||||
PART_BOUNDARY: f,
|
||||
LAST_BOUNDARY: f *= 2
|
||||
};
|
||||
|
||||
const LF = 10;
|
||||
const CR = 13;
|
||||
const SPACE = 32;
|
||||
const HYPHEN = 45;
|
||||
const COLON = 58;
|
||||
const A = 97;
|
||||
const Z = 122;
|
||||
|
||||
const lower = c => c | 0x20;
|
||||
|
||||
const noop = () => {};
|
||||
|
||||
class MultipartParser {
|
||||
/**
|
||||
* @param {string} boundary
|
||||
*/
|
||||
constructor(boundary) {
|
||||
this.index = 0;
|
||||
this.flags = 0;
|
||||
|
||||
this.onHeaderEnd = noop;
|
||||
this.onHeaderField = noop;
|
||||
this.onHeadersEnd = noop;
|
||||
this.onHeaderValue = noop;
|
||||
this.onPartBegin = noop;
|
||||
this.onPartData = noop;
|
||||
this.onPartEnd = noop;
|
||||
|
||||
this.boundaryChars = {};
|
||||
|
||||
boundary = '\r\n--' + boundary;
|
||||
const ui8a = new Uint8Array(boundary.length);
|
||||
for (let i = 0; i < boundary.length; i++) {
|
||||
ui8a[i] = boundary.charCodeAt(i);
|
||||
this.boundaryChars[ui8a[i]] = true;
|
||||
}
|
||||
|
||||
this.boundary = ui8a;
|
||||
this.lookbehind = new Uint8Array(this.boundary.length + 8);
|
||||
this.state = S.START_BOUNDARY;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Uint8Array} data
|
||||
*/
|
||||
write(data) {
|
||||
let i = 0;
|
||||
const length_ = data.length;
|
||||
let previousIndex = this.index;
|
||||
let {lookbehind, boundary, boundaryChars, index, state, flags} = this;
|
||||
const boundaryLength = this.boundary.length;
|
||||
const boundaryEnd = boundaryLength - 1;
|
||||
const bufferLength = data.length;
|
||||
let c;
|
||||
let cl;
|
||||
|
||||
const mark = name => {
|
||||
this[name + 'Mark'] = i;
|
||||
};
|
||||
|
||||
const clear = name => {
|
||||
delete this[name + 'Mark'];
|
||||
};
|
||||
|
||||
const callback = (callbackSymbol, start, end, ui8a) => {
|
||||
if (start === undefined || start !== end) {
|
||||
this[callbackSymbol](ui8a && ui8a.subarray(start, end));
|
||||
}
|
||||
};
|
||||
|
||||
const dataCallback = (name, clear) => {
|
||||
const markSymbol = name + 'Mark';
|
||||
if (!(markSymbol in this)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (clear) {
|
||||
callback(name, this[markSymbol], i, data);
|
||||
delete this[markSymbol];
|
||||
} else {
|
||||
callback(name, this[markSymbol], data.length, data);
|
||||
this[markSymbol] = 0;
|
||||
}
|
||||
};
|
||||
|
||||
for (i = 0; i < length_; i++) {
|
||||
c = data[i];
|
||||
|
||||
switch (state) {
|
||||
case S.START_BOUNDARY:
|
||||
if (index === boundary.length - 2) {
|
||||
if (c === HYPHEN) {
|
||||
flags |= F.LAST_BOUNDARY;
|
||||
} else if (c !== CR) {
|
||||
return;
|
||||
}
|
||||
|
||||
index++;
|
||||
break;
|
||||
} else if (index - 1 === boundary.length - 2) {
|
||||
if (flags & F.LAST_BOUNDARY && c === HYPHEN) {
|
||||
state = S.END;
|
||||
flags = 0;
|
||||
} else if (!(flags & F.LAST_BOUNDARY) && c === LF) {
|
||||
index = 0;
|
||||
callback('onPartBegin');
|
||||
state = S.HEADER_FIELD_START;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (c !== boundary[index + 2]) {
|
||||
index = -2;
|
||||
}
|
||||
|
||||
if (c === boundary[index + 2]) {
|
||||
index++;
|
||||
}
|
||||
|
||||
break;
|
||||
case S.HEADER_FIELD_START:
|
||||
state = S.HEADER_FIELD;
|
||||
mark('onHeaderField');
|
||||
index = 0;
|
||||
// falls through
|
||||
case S.HEADER_FIELD:
|
||||
if (c === CR) {
|
||||
clear('onHeaderField');
|
||||
state = S.HEADERS_ALMOST_DONE;
|
||||
break;
|
||||
}
|
||||
|
||||
index++;
|
||||
if (c === HYPHEN) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (c === COLON) {
|
||||
if (index === 1) {
|
||||
// empty header field
|
||||
return;
|
||||
}
|
||||
|
||||
dataCallback('onHeaderField', true);
|
||||
state = S.HEADER_VALUE_START;
|
||||
break;
|
||||
}
|
||||
|
||||
cl = lower(c);
|
||||
if (cl < A || cl > Z) {
|
||||
return;
|
||||
}
|
||||
|
||||
break;
|
||||
case S.HEADER_VALUE_START:
|
||||
if (c === SPACE) {
|
||||
break;
|
||||
}
|
||||
|
||||
mark('onHeaderValue');
|
||||
state = S.HEADER_VALUE;
|
||||
// falls through
|
||||
case S.HEADER_VALUE:
|
||||
if (c === CR) {
|
||||
dataCallback('onHeaderValue', true);
|
||||
callback('onHeaderEnd');
|
||||
state = S.HEADER_VALUE_ALMOST_DONE;
|
||||
}
|
||||
|
||||
break;
|
||||
case S.HEADER_VALUE_ALMOST_DONE:
|
||||
if (c !== LF) {
|
||||
return;
|
||||
}
|
||||
|
||||
state = S.HEADER_FIELD_START;
|
||||
break;
|
||||
case S.HEADERS_ALMOST_DONE:
|
||||
if (c !== LF) {
|
||||
return;
|
||||
}
|
||||
|
||||
callback('onHeadersEnd');
|
||||
state = S.PART_DATA_START;
|
||||
break;
|
||||
case S.PART_DATA_START:
|
||||
state = S.PART_DATA;
|
||||
mark('onPartData');
|
||||
// falls through
|
||||
case S.PART_DATA:
|
||||
previousIndex = index;
|
||||
|
||||
if (index === 0) {
|
||||
// boyer-moore derrived algorithm to safely skip non-boundary data
|
||||
i += boundaryEnd;
|
||||
while (i < bufferLength && !(data[i] in boundaryChars)) {
|
||||
i += boundaryLength;
|
||||
}
|
||||
|
||||
i -= boundaryEnd;
|
||||
c = data[i];
|
||||
}
|
||||
|
||||
if (index < boundary.length) {
|
||||
if (boundary[index] === c) {
|
||||
if (index === 0) {
|
||||
dataCallback('onPartData', true);
|
||||
}
|
||||
|
||||
index++;
|
||||
} else {
|
||||
index = 0;
|
||||
}
|
||||
} else if (index === boundary.length) {
|
||||
index++;
|
||||
if (c === CR) {
|
||||
// CR = part boundary
|
||||
flags |= F.PART_BOUNDARY;
|
||||
} else if (c === HYPHEN) {
|
||||
// HYPHEN = end boundary
|
||||
flags |= F.LAST_BOUNDARY;
|
||||
} else {
|
||||
index = 0;
|
||||
}
|
||||
} else if (index - 1 === boundary.length) {
|
||||
if (flags & F.PART_BOUNDARY) {
|
||||
index = 0;
|
||||
if (c === LF) {
|
||||
// unset the PART_BOUNDARY flag
|
||||
flags &= ~F.PART_BOUNDARY;
|
||||
callback('onPartEnd');
|
||||
callback('onPartBegin');
|
||||
state = S.HEADER_FIELD_START;
|
||||
break;
|
||||
}
|
||||
} else if (flags & F.LAST_BOUNDARY) {
|
||||
if (c === HYPHEN) {
|
||||
callback('onPartEnd');
|
||||
state = S.END;
|
||||
flags = 0;
|
||||
} else {
|
||||
index = 0;
|
||||
}
|
||||
} else {
|
||||
index = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (index > 0) {
|
||||
// when matching a possible boundary, keep a lookbehind reference
|
||||
// in case it turns out to be a false lead
|
||||
lookbehind[index - 1] = c;
|
||||
} else if (previousIndex > 0) {
|
||||
// if our boundary turned out to be rubbish, the captured lookbehind
|
||||
// belongs to partData
|
||||
const _lookbehind = new Uint8Array(lookbehind.buffer, lookbehind.byteOffset, lookbehind.byteLength);
|
||||
callback('onPartData', 0, previousIndex, _lookbehind);
|
||||
previousIndex = 0;
|
||||
mark('onPartData');
|
||||
|
||||
// reconsider the current character even so it interrupted the sequence
|
||||
// it could be the beginning of a new sequence
|
||||
i--;
|
||||
}
|
||||
|
||||
break;
|
||||
case S.END:
|
||||
break;
|
||||
default:
|
||||
throw new Error(`Unexpected state entered: ${state}`);
|
||||
}
|
||||
}
|
||||
|
||||
dataCallback('onHeaderField');
|
||||
dataCallback('onHeaderValue');
|
||||
dataCallback('onPartData');
|
||||
|
||||
// Update properties for the next call
|
||||
this.index = index;
|
||||
this.state = state;
|
||||
this.flags = flags;
|
||||
}
|
||||
|
||||
end() {
|
||||
if ((this.state === S.HEADER_FIELD_START && this.index === 0) ||
|
||||
(this.state === S.PART_DATA && this.index === this.boundary.length)) {
|
||||
this.onPartEnd();
|
||||
} else if (this.state !== S.END) {
|
||||
throw new Error('MultipartParser.end(): stream ended unexpectedly');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function _fileName(headerValue) {
|
||||
// matches either a quoted-string or a token (RFC 2616 section 19.5.1)
|
||||
const m = headerValue.match(/\bfilename=("(.*?)"|([^()<>@,;:\\"/[\]?={}\s\t]+))($|;\s)/i);
|
||||
if (!m) {
|
||||
return;
|
||||
}
|
||||
|
||||
const match = m[2] || m[3] || '';
|
||||
let filename = match.slice(match.lastIndexOf('\\') + 1);
|
||||
filename = filename.replace(/%22/g, '"');
|
||||
filename = filename.replace(/&#(\d{4});/g, (m, code) => {
|
||||
return String.fromCharCode(code);
|
||||
});
|
||||
return filename;
|
||||
}
|
||||
|
||||
export async function toFormData(Body, ct) {
|
||||
if (!/multipart/i.test(ct)) {
|
||||
throw new TypeError('Failed to fetch');
|
||||
}
|
||||
|
||||
const m = ct.match(/boundary=(?:"([^"]+)"|([^;]+))/i);
|
||||
|
||||
if (!m) {
|
||||
throw new TypeError('no or bad content-type header, no multipart boundary');
|
||||
}
|
||||
|
||||
const parser = new MultipartParser(m[1] || m[2]);
|
||||
|
||||
let headerField;
|
||||
let headerValue;
|
||||
let entryValue;
|
||||
let entryName;
|
||||
let contentType;
|
||||
let filename;
|
||||
const entryChunks = [];
|
||||
const formData = new FormData();
|
||||
|
||||
const onPartData = ui8a => {
|
||||
entryValue += decoder.decode(ui8a, {stream: true});
|
||||
};
|
||||
|
||||
const appendToFile = ui8a => {
|
||||
entryChunks.push(ui8a);
|
||||
};
|
||||
|
||||
const appendFileToFormData = () => {
|
||||
const file = new File(entryChunks, filename, {type: contentType});
|
||||
formData.append(entryName, file);
|
||||
};
|
||||
|
||||
const appendEntryToFormData = () => {
|
||||
formData.append(entryName, entryValue);
|
||||
};
|
||||
|
||||
const decoder = new TextDecoder('utf-8');
|
||||
decoder.decode();
|
||||
|
||||
parser.onPartBegin = function () {
|
||||
parser.onPartData = onPartData;
|
||||
parser.onPartEnd = appendEntryToFormData;
|
||||
|
||||
headerField = '';
|
||||
headerValue = '';
|
||||
entryValue = '';
|
||||
entryName = '';
|
||||
contentType = '';
|
||||
filename = null;
|
||||
entryChunks.length = 0;
|
||||
};
|
||||
|
||||
parser.onHeaderField = function (ui8a) {
|
||||
headerField += decoder.decode(ui8a, {stream: true});
|
||||
};
|
||||
|
||||
parser.onHeaderValue = function (ui8a) {
|
||||
headerValue += decoder.decode(ui8a, {stream: true});
|
||||
};
|
||||
|
||||
parser.onHeaderEnd = function () {
|
||||
headerValue += decoder.decode();
|
||||
headerField = headerField.toLowerCase();
|
||||
|
||||
if (headerField === 'content-disposition') {
|
||||
// matches either a quoted-string or a token (RFC 2616 section 19.5.1)
|
||||
const m = headerValue.match(/\bname=("([^"]*)"|([^()<>@,;:\\"/[\]?={}\s\t]+))/i);
|
||||
|
||||
if (m) {
|
||||
entryName = m[2] || m[3] || '';
|
||||
}
|
||||
|
||||
filename = _fileName(headerValue);
|
||||
|
||||
if (filename) {
|
||||
parser.onPartData = appendToFile;
|
||||
parser.onPartEnd = appendFileToFormData;
|
||||
}
|
||||
} else if (headerField === 'content-type') {
|
||||
contentType = headerValue;
|
||||
}
|
||||
|
||||
headerValue = '';
|
||||
headerField = '';
|
||||
};
|
||||
|
||||
for await (const chunk of Body) {
|
||||
parser.write(chunk);
|
||||
}
|
||||
|
||||
parser.end();
|
||||
|
||||
return formData;
|
||||
}
|
||||
340
_shared/lib/node-fetch/src/utils/referrer.js
Normal file
340
_shared/lib/node-fetch/src/utils/referrer.js
Normal file
|
|
@ -0,0 +1,340 @@
|
|||
import {isIP} from 'node:net';
|
||||
|
||||
/**
|
||||
* @external URL
|
||||
* @see {@link https://developer.mozilla.org/en-US/docs/Web/API/URL|URL}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @module utils/referrer
|
||||
* @private
|
||||
*/
|
||||
|
||||
/**
|
||||
* @see {@link https://w3c.github.io/webappsec-referrer-policy/#strip-url|Referrer Policy §8.4. Strip url for use as a referrer}
|
||||
* @param {string} URL
|
||||
* @param {boolean} [originOnly=false]
|
||||
*/
|
||||
export function stripURLForUseAsAReferrer(url, originOnly = false) {
|
||||
// 1. If url is null, return no referrer.
|
||||
if (url == null) { // eslint-disable-line no-eq-null, eqeqeq
|
||||
return 'no-referrer';
|
||||
}
|
||||
|
||||
url = new URL(url);
|
||||
|
||||
// 2. If url's scheme is a local scheme, then return no referrer.
|
||||
if (/^(about|blob|data):$/.test(url.protocol)) {
|
||||
return 'no-referrer';
|
||||
}
|
||||
|
||||
// 3. Set url's username to the empty string.
|
||||
url.username = '';
|
||||
|
||||
// 4. Set url's password to null.
|
||||
// Note: `null` appears to be a mistake as this actually results in the password being `"null"`.
|
||||
url.password = '';
|
||||
|
||||
// 5. Set url's fragment to null.
|
||||
// Note: `null` appears to be a mistake as this actually results in the fragment being `"#null"`.
|
||||
url.hash = '';
|
||||
|
||||
// 6. If the origin-only flag is true, then:
|
||||
if (originOnly) {
|
||||
// 6.1. Set url's path to null.
|
||||
// Note: `null` appears to be a mistake as this actually results in the path being `"/null"`.
|
||||
url.pathname = '';
|
||||
|
||||
// 6.2. Set url's query to null.
|
||||
// Note: `null` appears to be a mistake as this actually results in the query being `"?null"`.
|
||||
url.search = '';
|
||||
}
|
||||
|
||||
// 7. Return url.
|
||||
return url;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see {@link https://w3c.github.io/webappsec-referrer-policy/#enumdef-referrerpolicy|enum ReferrerPolicy}
|
||||
*/
|
||||
export const ReferrerPolicy = new Set([
|
||||
'',
|
||||
'no-referrer',
|
||||
'no-referrer-when-downgrade',
|
||||
'same-origin',
|
||||
'origin',
|
||||
'strict-origin',
|
||||
'origin-when-cross-origin',
|
||||
'strict-origin-when-cross-origin',
|
||||
'unsafe-url'
|
||||
]);
|
||||
|
||||
/**
|
||||
* @see {@link https://w3c.github.io/webappsec-referrer-policy/#default-referrer-policy|default referrer policy}
|
||||
*/
|
||||
export const DEFAULT_REFERRER_POLICY = 'strict-origin-when-cross-origin';
|
||||
|
||||
/**
|
||||
* @see {@link https://w3c.github.io/webappsec-referrer-policy/#referrer-policies|Referrer Policy §3. Referrer Policies}
|
||||
* @param {string} referrerPolicy
|
||||
* @returns {string} referrerPolicy
|
||||
*/
|
||||
export function validateReferrerPolicy(referrerPolicy) {
|
||||
if (!ReferrerPolicy.has(referrerPolicy)) {
|
||||
throw new TypeError(`Invalid referrerPolicy: ${referrerPolicy}`);
|
||||
}
|
||||
|
||||
return referrerPolicy;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see {@link https://w3c.github.io/webappsec-secure-contexts/#is-origin-trustworthy|Referrer Policy §3.2. Is origin potentially trustworthy?}
|
||||
* @param {external:URL} url
|
||||
* @returns `true`: "Potentially Trustworthy", `false`: "Not Trustworthy"
|
||||
*/
|
||||
export function isOriginPotentiallyTrustworthy(url) {
|
||||
// 1. If origin is an opaque origin, return "Not Trustworthy".
|
||||
// Not applicable
|
||||
|
||||
// 2. Assert: origin is a tuple origin.
|
||||
// Not for implementations
|
||||
|
||||
// 3. If origin's scheme is either "https" or "wss", return "Potentially Trustworthy".
|
||||
if (/^(http|ws)s:$/.test(url.protocol)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// 4. If origin's host component matches one of the CIDR notations 127.0.0.0/8 or ::1/128 [RFC4632], return "Potentially Trustworthy".
|
||||
const hostIp = url.host.replace(/(^\[)|(]$)/g, '');
|
||||
const hostIPVersion = isIP(hostIp);
|
||||
|
||||
if (hostIPVersion === 4 && /^127\./.test(hostIp)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (hostIPVersion === 6 && /^(((0+:){7})|(::(0+:){0,6}))0*1$/.test(hostIp)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// 5. If origin's host component is "localhost" or falls within ".localhost", and the user agent conforms to the name resolution rules in [let-localhost-be-localhost], return "Potentially Trustworthy".
|
||||
// We are returning FALSE here because we cannot ensure conformance to
|
||||
// let-localhost-be-loalhost (https://tools.ietf.org/html/draft-west-let-localhost-be-localhost)
|
||||
if (url.host === 'localhost' || url.host.endsWith('.localhost')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 6. If origin's scheme component is file, return "Potentially Trustworthy".
|
||||
if (url.protocol === 'file:') {
|
||||
return true;
|
||||
}
|
||||
|
||||
// 7. If origin's scheme component is one which the user agent considers to be authenticated, return "Potentially Trustworthy".
|
||||
// Not supported
|
||||
|
||||
// 8. If origin has been configured as a trustworthy origin, return "Potentially Trustworthy".
|
||||
// Not supported
|
||||
|
||||
// 9. Return "Not Trustworthy".
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see {@link https://w3c.github.io/webappsec-secure-contexts/#is-url-trustworthy|Referrer Policy §3.3. Is url potentially trustworthy?}
|
||||
* @param {external:URL} url
|
||||
* @returns `true`: "Potentially Trustworthy", `false`: "Not Trustworthy"
|
||||
*/
|
||||
export function isUrlPotentiallyTrustworthy(url) {
|
||||
// 1. If url is "about:blank" or "about:srcdoc", return "Potentially Trustworthy".
|
||||
if (/^about:(blank|srcdoc)$/.test(url)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// 2. If url's scheme is "data", return "Potentially Trustworthy".
|
||||
if (url.protocol === 'data:') {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Note: The origin of blob: and filesystem: URLs is the origin of the context in which they were
|
||||
// created. Therefore, blobs created in a trustworthy origin will themselves be potentially
|
||||
// trustworthy.
|
||||
if (/^(blob|filesystem):$/.test(url.protocol)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// 3. Return the result of executing §3.2 Is origin potentially trustworthy? on url's origin.
|
||||
return isOriginPotentiallyTrustworthy(url);
|
||||
}
|
||||
|
||||
/**
|
||||
* Modifies the referrerURL to enforce any extra security policy considerations.
|
||||
* @see {@link https://w3c.github.io/webappsec-referrer-policy/#determine-requests-referrer|Referrer Policy §8.3. Determine request's Referrer}, step 7
|
||||
* @callback module:utils/referrer~referrerURLCallback
|
||||
* @param {external:URL} referrerURL
|
||||
* @returns {external:URL} modified referrerURL
|
||||
*/
|
||||
|
||||
/**
|
||||
* Modifies the referrerOrigin to enforce any extra security policy considerations.
|
||||
* @see {@link https://w3c.github.io/webappsec-referrer-policy/#determine-requests-referrer|Referrer Policy §8.3. Determine request's Referrer}, step 7
|
||||
* @callback module:utils/referrer~referrerOriginCallback
|
||||
* @param {external:URL} referrerOrigin
|
||||
* @returns {external:URL} modified referrerOrigin
|
||||
*/
|
||||
|
||||
/**
|
||||
* @see {@link https://w3c.github.io/webappsec-referrer-policy/#determine-requests-referrer|Referrer Policy §8.3. Determine request's Referrer}
|
||||
* @param {Request} request
|
||||
* @param {object} o
|
||||
* @param {module:utils/referrer~referrerURLCallback} o.referrerURLCallback
|
||||
* @param {module:utils/referrer~referrerOriginCallback} o.referrerOriginCallback
|
||||
* @returns {external:URL} Request's referrer
|
||||
*/
|
||||
export function determineRequestsReferrer(request, {referrerURLCallback, referrerOriginCallback} = {}) {
|
||||
// There are 2 notes in the specification about invalid pre-conditions. We return null, here, for
|
||||
// these cases:
|
||||
// > Note: If request's referrer is "no-referrer", Fetch will not call into this algorithm.
|
||||
// > Note: If request's referrer policy is the empty string, Fetch will not call into this
|
||||
// > algorithm.
|
||||
if (request.referrer === 'no-referrer' || request.referrerPolicy === '') {
|
||||
return null;
|
||||
}
|
||||
|
||||
// 1. Let policy be request's associated referrer policy.
|
||||
const policy = request.referrerPolicy;
|
||||
|
||||
// 2. Let environment be request's client.
|
||||
// not applicable to node.js
|
||||
|
||||
// 3. Switch on request's referrer:
|
||||
if (request.referrer === 'about:client') {
|
||||
return 'no-referrer';
|
||||
}
|
||||
|
||||
// "a URL": Let referrerSource be request's referrer.
|
||||
const referrerSource = request.referrer;
|
||||
|
||||
// 4. Let request's referrerURL be the result of stripping referrerSource for use as a referrer.
|
||||
let referrerURL = stripURLForUseAsAReferrer(referrerSource);
|
||||
|
||||
// 5. Let referrerOrigin be the result of stripping referrerSource for use as a referrer, with the
|
||||
// origin-only flag set to true.
|
||||
let referrerOrigin = stripURLForUseAsAReferrer(referrerSource, true);
|
||||
|
||||
// 6. If the result of serializing referrerURL is a string whose length is greater than 4096, set
|
||||
// referrerURL to referrerOrigin.
|
||||
if (referrerURL.toString().length > 4096) {
|
||||
referrerURL = referrerOrigin;
|
||||
}
|
||||
|
||||
// 7. The user agent MAY alter referrerURL or referrerOrigin at this point to enforce arbitrary
|
||||
// policy considerations in the interests of minimizing data leakage. For example, the user
|
||||
// agent could strip the URL down to an origin, modify its host, replace it with an empty
|
||||
// string, etc.
|
||||
if (referrerURLCallback) {
|
||||
referrerURL = referrerURLCallback(referrerURL);
|
||||
}
|
||||
|
||||
if (referrerOriginCallback) {
|
||||
referrerOrigin = referrerOriginCallback(referrerOrigin);
|
||||
}
|
||||
|
||||
// 8.Execute the statements corresponding to the value of policy:
|
||||
const currentURL = new URL(request.url);
|
||||
|
||||
switch (policy) {
|
||||
case 'no-referrer':
|
||||
return 'no-referrer';
|
||||
|
||||
case 'origin':
|
||||
return referrerOrigin;
|
||||
|
||||
case 'unsafe-url':
|
||||
return referrerURL;
|
||||
|
||||
case 'strict-origin':
|
||||
// 1. If referrerURL is a potentially trustworthy URL and request's current URL is not a
|
||||
// potentially trustworthy URL, then return no referrer.
|
||||
if (isUrlPotentiallyTrustworthy(referrerURL) && !isUrlPotentiallyTrustworthy(currentURL)) {
|
||||
return 'no-referrer';
|
||||
}
|
||||
|
||||
// 2. Return referrerOrigin.
|
||||
return referrerOrigin.toString();
|
||||
|
||||
case 'strict-origin-when-cross-origin':
|
||||
// 1. If the origin of referrerURL and the origin of request's current URL are the same, then
|
||||
// return referrerURL.
|
||||
if (referrerURL.origin === currentURL.origin) {
|
||||
return referrerURL;
|
||||
}
|
||||
|
||||
// 2. If referrerURL is a potentially trustworthy URL and request's current URL is not a
|
||||
// potentially trustworthy URL, then return no referrer.
|
||||
if (isUrlPotentiallyTrustworthy(referrerURL) && !isUrlPotentiallyTrustworthy(currentURL)) {
|
||||
return 'no-referrer';
|
||||
}
|
||||
|
||||
// 3. Return referrerOrigin.
|
||||
return referrerOrigin;
|
||||
|
||||
case 'same-origin':
|
||||
// 1. If the origin of referrerURL and the origin of request's current URL are the same, then
|
||||
// return referrerURL.
|
||||
if (referrerURL.origin === currentURL.origin) {
|
||||
return referrerURL;
|
||||
}
|
||||
|
||||
// 2. Return no referrer.
|
||||
return 'no-referrer';
|
||||
|
||||
case 'origin-when-cross-origin':
|
||||
// 1. If the origin of referrerURL and the origin of request's current URL are the same, then
|
||||
// return referrerURL.
|
||||
if (referrerURL.origin === currentURL.origin) {
|
||||
return referrerURL;
|
||||
}
|
||||
|
||||
// Return referrerOrigin.
|
||||
return referrerOrigin;
|
||||
|
||||
case 'no-referrer-when-downgrade':
|
||||
// 1. If referrerURL is a potentially trustworthy URL and request's current URL is not a
|
||||
// potentially trustworthy URL, then return no referrer.
|
||||
if (isUrlPotentiallyTrustworthy(referrerURL) && !isUrlPotentiallyTrustworthy(currentURL)) {
|
||||
return 'no-referrer';
|
||||
}
|
||||
|
||||
// 2. Return referrerURL.
|
||||
return referrerURL;
|
||||
|
||||
default:
|
||||
throw new TypeError(`Invalid referrerPolicy: ${policy}`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see {@link https://w3c.github.io/webappsec-referrer-policy/#parse-referrer-policy-from-header|Referrer Policy §8.1. Parse a referrer policy from a Referrer-Policy header}
|
||||
* @param {Headers} headers Response headers
|
||||
* @returns {string} policy
|
||||
*/
|
||||
export function parseReferrerPolicyFromHeader(headers) {
|
||||
// 1. Let policy-tokens be the result of extracting header list values given `Referrer-Policy`
|
||||
// and response’s header list.
|
||||
const policyTokens = (headers.get('referrer-policy') || '').split(/[,\s]+/);
|
||||
|
||||
// 2. Let policy be the empty string.
|
||||
let policy = '';
|
||||
|
||||
// 3. For each token in policy-tokens, if token is a referrer policy and token is not the empty
|
||||
// string, then set policy to token.
|
||||
// Note: This algorithm loops over multiple policy values to allow deployment of new policy
|
||||
// values with fallbacks for older user agents, as described in § 11.1 Unknown Policy Values.
|
||||
for (const token of policyTokens) {
|
||||
if (token && ReferrerPolicy.has(token)) {
|
||||
policy = token;
|
||||
}
|
||||
}
|
||||
|
||||
// 4. Return policy.
|
||||
return policy;
|
||||
}
|
||||
|
|
@ -1,15 +1,18 @@
|
|||
GITADORA Plugin for Asphyxia-Core
|
||||
=================================
|
||||

|
||||

|
||||
|
||||
This plugin is based on converted from public-exported Asphyxia's Routes.
|
||||
|
||||
Supported Versions
|
||||
==================
|
||||
- Tri-Boost Re:EVOLVE
|
||||
- Matixx
|
||||
- Exchain
|
||||
- EXCHAIN
|
||||
- NEX+AGE
|
||||
|
||||
- HIGH-VOLTAGE
|
||||
- FUZZ-UP
|
||||
- GALAXY WAVE
|
||||
|
||||
When Plugin Doesn't work correctly / Startup Error on Plugin
|
||||
------------------------------------------------------------
|
||||
|
|
@ -26,9 +29,42 @@ Known Issues
|
|||
* Special Premium Encore on Nextage is unimplemented. However, a workaround is available. Try it.
|
||||
* Friends and Rivals are unimplemented.
|
||||
|
||||
Shared Data Options
|
||||
===================
|
||||
Two experimental options allow operators to share data across versions:
|
||||
|
||||
* **Shared Favorite Songs** (`shared_favorite_songs`, default: `false`): When enabled, favorite lists are unified across Guitar Freaks, DrumMania, and supported versions.
|
||||
* **Shared Song Scores** (`shared_song_scores`, default: `false`): When enabled, the server merges the best results for each chart across every stored version and saves them under a shared version identifier. The merged record uses the following shape (fields marked with `//` describe their meaning):
|
||||
|
||||
```
|
||||
scores: {
|
||||
"<musicid>": {
|
||||
update: [<seq>, <new_skill>], // Highest new_skill value seen and its associated seq
|
||||
diffs: {
|
||||
"<seq>": {
|
||||
perc: <number>, // Highest achievement percentage
|
||||
rank: <number>, // Highest rank reached for the chart
|
||||
clear: <boolean>, // Whether the chart has been cleared
|
||||
fc: <boolean>, // Whether a full combo was achieved
|
||||
ex: <boolean>, // Whether an excellent was achieved
|
||||
meter: "<string>",// Best meter value as a stringified bigint
|
||||
prog: <number>, // Highest progression value
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Scores are stored under `version: "shared"` but are automatically applied to the active module when loading a profile, ensuring players benefit from their best combined results regardless of the client version.
|
||||
|
||||
Release Notes
|
||||
=============
|
||||
|
||||
v1.4.0
|
||||
----------------
|
||||
* Added support for Tri-Boost Re:EVOLVE, HIGH-VOLTAGE, FUZZ-UP, GALAXY WAVE
|
||||
* Bugfix for launch core with "--dev/--console"
|
||||
|
||||
v1.3.0
|
||||
----------------
|
||||
* Added experimental 'Shared Favorite Songs' option. If disabled, players will be able to keep separate lists of favorite songs for each version of Gitadora, as well as between Guitar Freaks and Drummania. Enable this option to have a single unified list of favorite songs for both games, and across all versions. Default is false, to match original arcade behaviour.
|
||||
|
|
|
|||
|
|
@ -11,6 +11,37 @@ export function getEncoreStageData(info: EamuseInfo): EncoreStageData {
|
|||
const level: number = U.GetConfig("encore_version")
|
||||
const ntDummyEncore = U.GetConfig("nextage_dummy_encore")
|
||||
switch (getVersion(info)) {
|
||||
case 'galaxywave':
|
||||
return {
|
||||
level,
|
||||
musics: [
|
||||
2866, // Calm days
|
||||
2893, // 愛はToxic! feat.Lilymone
|
||||
2885, // Astrum
|
||||
2897, // DESPERATE ERROR
|
||||
2884, // Multiverse
|
||||
2919, // DOGMA
|
||||
2922, // Stay By My Side
|
||||
2937, // Prog for your Soul
|
||||
2963, // Zero Visibility
|
||||
2939, // Hopeful Daybreak!!!
|
||||
2956, // Over Time Groove
|
||||
]
|
||||
}
|
||||
case 'fuzzup':
|
||||
return {
|
||||
level,
|
||||
musics: [
|
||||
2812, // THE LAST OF FIREFACE
|
||||
2814, // ENCOUNT
|
||||
2783, // Q転直下
|
||||
2848, // Bloody Iron Maiden
|
||||
2860, // Serious Joke
|
||||
2844, // HyperNebula
|
||||
2877, // AVEL
|
||||
2892, // Elliptic Orbits
|
||||
]
|
||||
}
|
||||
case 'highvoltage':
|
||||
return {
|
||||
level,
|
||||
|
|
@ -58,7 +89,7 @@ export function getEncoreStageData(info: EamuseInfo): EncoreStageData {
|
|||
5060, // EXCELSIOR DIVE (CLASSIC)
|
||||
2530, // The ULTIMATES -CHRONICLE-
|
||||
2581, // 幸せの代償
|
||||
5046 // Rock to Infinity (CLASSIC)
|
||||
5046, // Rock to Infinity (CLASSIC)
|
||||
]
|
||||
}
|
||||
case 'matixx':
|
||||
|
|
@ -77,7 +108,22 @@ export function getEncoreStageData(info: EamuseInfo): EncoreStageData {
|
|||
2496, // CAPTURING XANADU
|
||||
2497, // Physical Decay
|
||||
2499, // Cinnamon
|
||||
2498 // けもののおうじゃ★めうめう
|
||||
2498, // けもののおうじゃ★めうめう
|
||||
]
|
||||
}
|
||||
case 're':
|
||||
return {
|
||||
level,
|
||||
musics: [
|
||||
2341, // Anathema
|
||||
2384, // White Forest
|
||||
2393, // REFLEXES MANIPULATION
|
||||
2392, // 主亡き機械人形のまなざし
|
||||
2406, // Exclamation
|
||||
2414, // MEDUSA
|
||||
2422, // BLACK ROSES
|
||||
2411, // ギタドラシカ
|
||||
2432, // Durian
|
||||
]
|
||||
}
|
||||
default:
|
||||
|
|
|
|||
12064
gitadora@asphyxia/data/mdb/fz.b64
Normal file
12064
gitadora@asphyxia/data/mdb/fz.b64
Normal file
File diff suppressed because it is too large
Load Diff
12499
gitadora@asphyxia/data/mdb/gw.b64
Normal file
12499
gitadora@asphyxia/data/mdb/gw.b64
Normal file
File diff suppressed because it is too large
Load Diff
|
|
@ -1,12 +1,14 @@
|
|||
import Logger from "../../utils/logger";
|
||||
import { CommonMusicData } from "../../models/commonmusicdata";
|
||||
|
||||
|
||||
export enum DATAVersion {
|
||||
GALAXYWAVE = "gw",
|
||||
FUZZUP = "fz",
|
||||
HIGHVOLTAGE = "hv",
|
||||
NEXTAGE = "nt",
|
||||
EXCHAIN = "ex",
|
||||
MATTIX = "mt"
|
||||
MATTIX = "mt",
|
||||
TBRE = "re"
|
||||
}
|
||||
|
||||
const allowedFormats = ['.json', '.xml', '.b64']
|
||||
|
|
@ -46,7 +48,15 @@ export async function readMDBFile(path: string, processHandler?: processRawDataH
|
|||
break;
|
||||
case '.b64':
|
||||
const buff = await IO.ReadFile(path, 'utf-8');
|
||||
const json = Buffer.from(buff, 'base64').toString('utf-8')
|
||||
const bufferCtor = (globalThis as {
|
||||
Buffer?: {
|
||||
from(input: string, encoding: string): { toString(encoding: string): string }
|
||||
}
|
||||
}).Buffer
|
||||
if (!bufferCtor) {
|
||||
throw new Error('Buffer is not available in the current environment.')
|
||||
}
|
||||
const json = bufferCtor.from(buff, 'base64').toString('utf-8')
|
||||
// Uncomment to save the decoded base64 file as JSON.
|
||||
// await IO.WriteFile(path.replace(".b64",".json"), json)
|
||||
result = JSON.parse(json)
|
||||
|
|
@ -54,6 +64,13 @@ export async function readMDBFile(path: string, processHandler?: processRawDataH
|
|||
default:
|
||||
throw `Invalid MDB file type: ${fileType}. Only .json, .xml, .b64 are supported.`
|
||||
}
|
||||
|
||||
// Some MDB sources may not provide seq_release_state. Ensure it is present for every song entry.
|
||||
result.music.forEach((entry) => {
|
||||
if (entry.seq_release_state == null) {
|
||||
entry.seq_release_state = K.ITEM('s32', 1)
|
||||
}
|
||||
})
|
||||
|
||||
let gfCount = result.music.filter((e) => e.cont_gf["@content"][0]).length
|
||||
let dmCount = result.music.filter((e) => e.cont_dm["@content"][0]).length
|
||||
|
|
@ -63,6 +80,10 @@ export async function readMDBFile(path: string, processHandler?: processRawDataH
|
|||
|
||||
export function gameVerToDataVer(ver: string): DATAVersion {
|
||||
switch(ver) {
|
||||
case 'galaxywave':
|
||||
return DATAVersion.GALAXYWAVE
|
||||
case 'fuzzup':
|
||||
return DATAVersion.FUZZUP
|
||||
case 'highvoltage':
|
||||
return DATAVersion.HIGHVOLTAGE
|
||||
case 'nextage':
|
||||
|
|
@ -70,8 +91,9 @@ export function gameVerToDataVer(ver: string): DATAVersion {
|
|||
case 'exchain':
|
||||
return DATAVersion.EXCHAIN
|
||||
case 'matixx':
|
||||
default:
|
||||
return DATAVersion.MATTIX
|
||||
default:
|
||||
return DATAVersion.TBRE
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -93,9 +115,18 @@ export function findMDBFile(fileNameWithoutExtension: string, path: string = nul
|
|||
}
|
||||
|
||||
for (const ext of allowedFormats) {
|
||||
const filePath = path + fileNameWithoutExtension + ext
|
||||
if (IO.Exists(filePath)) {
|
||||
return filePath
|
||||
const candidateFileNames = ext === ".xml"
|
||||
? [
|
||||
`mdb_${fileNameWithoutExtension}${ext}`,
|
||||
`${fileNameWithoutExtension}${ext}`,
|
||||
]
|
||||
: [`${fileNameWithoutExtension}${ext}`]
|
||||
|
||||
for (const fileName of candidateFileNames) {
|
||||
const filePath = path + fileName
|
||||
if (IO.Exists(filePath)) {
|
||||
return filePath
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -108,7 +139,7 @@ export async function loadSongsForGameVersion(gameVer: string, processHandler?:
|
|||
let mdbFile = findMDBFile(ver, mdbFolder)
|
||||
|
||||
if (mdbFile == null) {
|
||||
throw `No valid MDB files were found in the data/mdb subfolder. Ensure that this folder contains at least one of the following: ${ver}.json, ${ver}.xml or ${ver}.b64`
|
||||
throw `No valid MDB files were found in the data/mdb subfolder. Ensure that this folder contains at least one of the following: ${ver}.json, mdb_${ver}.xml (${ver}.xml as fallback) or ${ver}.b64`
|
||||
}
|
||||
|
||||
const music = await readMDBFile(mdbFile, processHandler ?? defaultProcessRawXmlData)
|
||||
|
|
@ -140,7 +171,8 @@ export async function defaultProcessRawXmlData(path: string): Promise<CommonMusi
|
|||
cont_dm: K.ITEM('bool', dm == 0 ? 0 : 1),
|
||||
is_secret: K.ITEM('bool', m.number("is_secret", 0)),
|
||||
is_hot: K.ITEM('bool', type == 2 ? 0 : 1),
|
||||
data_ver: K.ITEM('s32', m.number("data_ver", 115)),
|
||||
data_ver: K.ITEM('s32', m.number("data_ver", 255)),
|
||||
seq_release_state: K.ITEM('s32', 1),
|
||||
diff: K.ARRAY('u16', [
|
||||
d[0],
|
||||
d[1],
|
||||
|
|
|
|||
7276
gitadora@asphyxia/data/mdb/re.b64
Normal file
7276
gitadora@asphyxia/data/mdb/re.b64
Normal file
File diff suppressed because it is too large
Load Diff
|
|
@ -1,6 +1,6 @@
|
|||
import { Extra } from "../models/extra";
|
||||
import { FavoriteMusic } from "../models/favoritemusic";
|
||||
import { isSharedFavoriteMusicEnabled } from "../utils";
|
||||
import { isSharedFavoriteMusicEnabled } from "../utils/index";
|
||||
import Logger from "../utils/logger";
|
||||
|
||||
const logger = new Logger("FavoriteMusic");
|
||||
|
|
@ -60,7 +60,6 @@ export async function applySharedFavoriteMusicToExtra(refid : string, extra : Ex
|
|||
let favoriteMusic = await loadFavoriteMusic(refid)
|
||||
|
||||
if (favoriteMusic == null) {
|
||||
logger.debugInfo(`No shared favourite music available for profile ${refid}. Using game specific favorites. Favorites will be saved as shared favorites at the end of the game session.`);
|
||||
return
|
||||
}
|
||||
|
||||
|
|
@ -84,10 +83,17 @@ export async function saveFavoriteMusic(refid: string, data : FavoriteMusic) : P
|
|||
}, data)
|
||||
}
|
||||
|
||||
export async function loadFavoriteMusic(refid : string) : Promise<FavoriteMusic>
|
||||
export async function loadFavoriteMusic(refid : string) : Promise<FavoriteMusic | null>
|
||||
{
|
||||
return await DB.FindOne<FavoriteMusic>(refid, {
|
||||
const favoriteMusic = await DB.FindOne<FavoriteMusic>(refid, {
|
||||
collection: 'favoritemusic'
|
||||
})
|
||||
|
||||
if (!favoriteMusic) {
|
||||
logger.debugInfo(`No shared favourite music available for profile ${refid}. Using game specific favorites. Favorites will be saved as shared favorites at the end of the game session.`);
|
||||
return null
|
||||
}
|
||||
|
||||
return favoriteMusic
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import { findMDBFile, readMDBFile, loadSongsForGameVersion } from "../data/mdb";
|
|||
import { CommonMusicDataField } from "../models/commonmusicdata";
|
||||
import Logger from "../utils/logger"
|
||||
import { getPlayableMusicResponse, PlayableMusicResponse } from "../models/Responses/playablemusicresponse";
|
||||
import { isAsphyxiaDebugMode } from "../utils/index";
|
||||
|
||||
const logger = new Logger("MusicList")
|
||||
|
||||
|
|
@ -31,5 +32,10 @@ export const playableMusic: EPR = async (info, data, send) => {
|
|||
|
||||
let response : PlayableMusicResponse = getPlayableMusicResponse(music)
|
||||
await send.object(response)
|
||||
|
||||
if (isAsphyxiaDebugMode()) {
|
||||
await IO.WriteFile(`apisamples/playableMusicList.json`, JSON.stringify(music, null, 4))
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
|
|
|||
90
gitadora@asphyxia/handlers/SharedScores.ts
Normal file
90
gitadora@asphyxia/handlers/SharedScores.ts
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
import { PLUGIN_VER } from "../const";
|
||||
import { Scores } from "../models/scores";
|
||||
|
||||
type ScoreDiff = Scores['scores'][string]['diffs'][string];
|
||||
type ScoreEntry = Scores['scores'][string];
|
||||
|
||||
function selectBetterMeter(existing?: string, incoming?: string): string {
|
||||
if (!incoming) return existing ?? "0";
|
||||
if (!existing) return incoming;
|
||||
|
||||
try {
|
||||
return BigInt(incoming) > BigInt(existing) ? incoming : existing;
|
||||
} catch (e) {
|
||||
return incoming || existing;
|
||||
}
|
||||
}
|
||||
|
||||
function mergeScoreDiff(existing: ScoreDiff | undefined, incoming: ScoreDiff): ScoreDiff {
|
||||
if (!existing) return incoming;
|
||||
|
||||
return {
|
||||
perc: Math.max(existing.perc ?? 0, incoming.perc ?? 0),
|
||||
rank: Math.max(existing.rank ?? 0, incoming.rank ?? 0),
|
||||
meter: selectBetterMeter(existing.meter, incoming.meter),
|
||||
prog: Math.max(existing.prog ?? 0, incoming.prog ?? 0),
|
||||
clear: (existing.clear ?? false) || (incoming.clear ?? false),
|
||||
fc: (existing.fc ?? false) || (incoming.fc ?? false),
|
||||
ex: (existing.ex ?? false) || (incoming.ex ?? false),
|
||||
};
|
||||
}
|
||||
|
||||
function mergeScoreEntry(existing: ScoreEntry | undefined, incoming: ScoreEntry): ScoreEntry {
|
||||
const mergedDiffs: ScoreEntry['diffs'] = existing ? { ...existing.diffs } : {};
|
||||
|
||||
for (const [seq, diff] of Object.entries(incoming.diffs)) {
|
||||
mergedDiffs[seq] = mergeScoreDiff(mergedDiffs[seq], diff);
|
||||
}
|
||||
|
||||
const mergedUpdate = existing?.update ? [...existing.update] : [0, 0];
|
||||
if (incoming.update && (mergedUpdate[1] ?? 0) < incoming.update[1]) {
|
||||
mergedUpdate[0] = incoming.update[0];
|
||||
mergedUpdate[1] = incoming.update[1];
|
||||
}
|
||||
|
||||
return {
|
||||
update: mergedUpdate,
|
||||
diffs: mergedDiffs,
|
||||
};
|
||||
}
|
||||
|
||||
function mergeScoreCollections(target: Scores['scores'], incoming: Scores['scores']): Scores['scores'] {
|
||||
const merged = { ...target } as Scores['scores'];
|
||||
|
||||
for (const [mid, entry] of Object.entries(incoming)) {
|
||||
merged[mid] = mergeScoreEntry(merged[mid], entry);
|
||||
}
|
||||
|
||||
return merged;
|
||||
}
|
||||
|
||||
async function persistSharedScores(refid: string, game: 'gf' | 'dm', scores: Scores['scores']) {
|
||||
await DB.Upsert<Scores>(refid, { collection: 'scores', game, version: 'shared' }, {
|
||||
collection: 'scores',
|
||||
version: 'shared',
|
||||
pluginVer: PLUGIN_VER,
|
||||
game,
|
||||
scores,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Load and merge scores across all versions for a player/game pair and persist them under version "shared".
|
||||
*/
|
||||
export async function getMergedSharedScores(refid: string, game: 'gf' | 'dm'): Promise<Scores['scores']> {
|
||||
const scoreDocs = await DB.Find<Scores>(refid, { collection: 'scores', game });
|
||||
const mergedScores = scoreDocs.reduce<Scores['scores']>((acc, doc) => mergeScoreCollections(acc, doc.scores), {} as Scores['scores']);
|
||||
|
||||
await persistSharedScores(refid, game, mergedScores);
|
||||
return mergedScores;
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge the provided score set into the shared scores document for the player/game pair.
|
||||
*/
|
||||
export async function mergeScoresIntoShared(refid: string, game: 'gf' | 'dm', scores: Scores['scores']) {
|
||||
const existingShared = await DB.FindOne<Scores>(refid, { collection: 'scores', game, version: 'shared' });
|
||||
const mergedScores = mergeScoreCollections(existingShared?.scores ?? {}, scores);
|
||||
|
||||
await persistSharedScores(refid, game, mergedScores);
|
||||
}
|
||||
|
|
@ -1,5 +1,8 @@
|
|||
/// <reference lib="es2020.bigint" />
|
||||
|
||||
import { getEncoreStageData } from "../data/extrastage";
|
||||
import Logger from "../utils/logger";
|
||||
import { getVersion } from "../utils";
|
||||
|
||||
const logger = new Logger('info');
|
||||
export const shopInfoRegist: EPR = async (info, data, send) => {
|
||||
|
|
@ -21,90 +24,343 @@ export const gameInfoGet: EPR = async (info, data, send) => {
|
|||
|
||||
const eventData = getEventDataResponse()
|
||||
const extraData = getEncoreStageData(info)
|
||||
|
||||
await send.object({
|
||||
now_date: K.ITEM('u64', BigInt(Date.now())),
|
||||
extra: {
|
||||
extra_lv: K.ITEM('u8', extraData.level),
|
||||
extramusic: {
|
||||
music: extraData.musics.map(mid => {
|
||||
return {
|
||||
musicid: K.ITEM('s32', mid),
|
||||
get_border: K.ITEM('u8', 0),
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
infect_music: { term: K.ITEM('u8', 0) },
|
||||
unlock_challenge: { term: K.ITEM('u8', 0) },
|
||||
battle: { term: K.ITEM('u8', 0) },
|
||||
battle_chara: { term: K.ITEM('u8', 0) },
|
||||
data_ver_limit: { term: K.ITEM('u8', 0) },
|
||||
ea_pass_propel: { term: K.ITEM('u8', 0) },
|
||||
monthly_skill: {
|
||||
term: K.ITEM('u8', 0),
|
||||
target_music: {
|
||||
music: {
|
||||
musicid: K.ITEM('s32', 0),
|
||||
},
|
||||
const VER = getVersion(info)
|
||||
if (VER == "galaxywave"){
|
||||
await send.object({
|
||||
now_date: K.ITEM('u64', BigInt(Date.now())),
|
||||
extra: {
|
||||
extra_lv: K.ITEM('s32', extraData.level),
|
||||
extramusic: {
|
||||
music: extraData.musics.map(mid => {
|
||||
return {
|
||||
musicid: K.ITEM('s32', mid),
|
||||
get_border: K.ITEM('u8', 0),
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
},
|
||||
update_prog: { term: K.ITEM('u8', 0) },
|
||||
rockwave: { event_list: {} },
|
||||
general_term: {},
|
||||
jubeat_omiyage_challenge: {},
|
||||
kac2017: {},
|
||||
nostalgia_concert: {},
|
||||
trbitemdata: {},
|
||||
ctrl_movie: {},
|
||||
ng_jacket: {},
|
||||
ng_recommend_music: {},
|
||||
ranking: {
|
||||
skill_0_999: {},
|
||||
skill_1000_1499: {},
|
||||
skill_1500_1999: {},
|
||||
skill_2000_2499: {},
|
||||
skill_2500_2999: {},
|
||||
skill_3000_3499: {},
|
||||
skill_3500_3999: {},
|
||||
skill_4000_4499: {},
|
||||
skill_4500_4999: {},
|
||||
skill_5000_5499: {},
|
||||
skill_5500_5999: {},
|
||||
skill_6000_6499: {},
|
||||
skill_6500_6999: {},
|
||||
skill_7000_7499: {},
|
||||
skill_7500_7999: {},
|
||||
skill_8000_8499: {},
|
||||
skill_8500_9999: {},
|
||||
total: {},
|
||||
original: {},
|
||||
bemani: {},
|
||||
famous: {},
|
||||
anime: {},
|
||||
band: {},
|
||||
western: {},
|
||||
},
|
||||
processing_report_state: K.ITEM('u8', 0),
|
||||
assert_report_state: K.ITEM('u8', 0),
|
||||
recommendmusic: { '@attr': { nr: 0 } },
|
||||
demomusic: { '@attr': { nr: 0 } },
|
||||
event_skill: {},
|
||||
temperature: { is_send: K.ITEM('bool', 0) },
|
||||
bemani_summer_2018: { is_open: K.ITEM('bool', 0) },
|
||||
kac2018: {
|
||||
event: {
|
||||
term: K.ITEM('s32', 0),
|
||||
since: K.ITEM('u64', BigInt(0)),
|
||||
till: K.ITEM('u64', BigInt(0)),
|
||||
is_open: K.ITEM('bool', 0),
|
||||
infect_music: { term: K.ITEM('u8', 0) },
|
||||
unlock_challenge: { term: K.ITEM('s32', 0) },
|
||||
battle: { term: K.ITEM('s32', 0) },
|
||||
battle_chara: { term: K.ITEM('s32', 0) },
|
||||
data_ver_limit: { term: K.ITEM('s32', 0) },
|
||||
ea_pass_propel: { term: K.ITEM('s32', 0) },
|
||||
monthly_skill: {
|
||||
term: K.ITEM('u8', 0),
|
||||
target_music: {
|
||||
music_id: K.ARRAY('s32', [0, 0, 0, 0, 0, 0]),
|
||||
music: {
|
||||
musicid: K.ITEM('s32', 0),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
...eventData,
|
||||
});
|
||||
update_prog: { term: K.ITEM('s32', 0) },
|
||||
rockwave: {
|
||||
event_list: {
|
||||
event: {
|
||||
data_id: K.ITEM('s32', 0),
|
||||
data_version: K.ITEM('s32', 0),
|
||||
event_id: K.ITEM('s32', 0),
|
||||
event_type: K.ITEM('s32', 0),
|
||||
start_date: K.ITEM('u64', BigInt(0)),
|
||||
end_date: K.ITEM('u64', BigInt(0)),
|
||||
is_open: K.ITEM('bool', 0),
|
||||
bg_no: K.ITEM('s32', 0),
|
||||
target_musicid: K.ITEM('s32', 0),
|
||||
clear_border: K.ITEM('s32', 0),
|
||||
reward_musicid: K.ITEM('s32', 0),
|
||||
reward_musicid_border_list: K.ITEM('s32', 0),
|
||||
reward_stickerid: K.ITEM('s32', 0),
|
||||
reward_stickerid_list: K.ITEM('s32', 0),
|
||||
reward_stickerid_border_list: K.ITEM('s32', 0),
|
||||
firstbit: K.ITEM('s32', 0),
|
||||
quest_no: K.ITEM('s32', 0),
|
||||
target_music_list: {
|
||||
music: {
|
||||
musicid: K.ITEM('s32', 0),
|
||||
}
|
||||
},
|
||||
ranking_list: K.ITEM('u64', BigInt(0)),
|
||||
}
|
||||
}
|
||||
},
|
||||
general_term: {
|
||||
termdata: {
|
||||
type: K.ITEM('str', ''),
|
||||
term: K.ITEM('s32', 0),
|
||||
state: K.ITEM('s32', 0),
|
||||
start_date_ms: K.ITEM('u64', BigInt(0)),
|
||||
end_date_ms: K.ITEM('u64', BigInt(0)),
|
||||
}
|
||||
},
|
||||
jubeat_omiyage_challenge: {},
|
||||
kac2017: {},
|
||||
nostalgia_concert: {},
|
||||
trbitemdata: {},
|
||||
ctrl_movie: {},
|
||||
ng_jacket: {},
|
||||
ng_recommend_music: {},
|
||||
ranking: {
|
||||
skill_0_999: {},
|
||||
skill_1000_1499: {},
|
||||
skill_1500_1999: {},
|
||||
skill_2000_2499: {},
|
||||
skill_2500_2999: {},
|
||||
skill_3000_3499: {},
|
||||
skill_3500_3999: {},
|
||||
skill_4000_4499: {},
|
||||
skill_4500_4999: {},
|
||||
skill_5000_5499: {},
|
||||
skill_5500_5999: {},
|
||||
skill_6000_6499: {},
|
||||
skill_6500_6999: {},
|
||||
skill_7000_7499: {},
|
||||
skill_7500_7999: {},
|
||||
skill_8000_8499: {},
|
||||
skill_8500_9999: {},
|
||||
total: {},
|
||||
original: {},
|
||||
bemani: {},
|
||||
famous: {},
|
||||
anime: {},
|
||||
band: {},
|
||||
western: {},
|
||||
},
|
||||
processing_report_state: K.ITEM('u8', 0),
|
||||
assert_report_state: K.ITEM('u8', 0),
|
||||
recommendmusic: { '@attr': { nr: 0 } },
|
||||
demomusic: { '@attr': { nr: 0 } },
|
||||
event_skill: {},
|
||||
temperature: { is_send: K.ITEM('bool', 0) },
|
||||
bemani_summer_2018: { is_open: K.ITEM('bool', 0) },
|
||||
kac2018: {
|
||||
event: {
|
||||
term: K.ITEM('s32', 0),
|
||||
since: K.ITEM('u64', BigInt(0)),
|
||||
till: K.ITEM('u64', BigInt(0)),
|
||||
is_open: K.ITEM('bool', 0),
|
||||
target_music: {
|
||||
music_id: K.ARRAY('s32', [0, 0, 0, 0, 0, 0]),
|
||||
},
|
||||
},
|
||||
},
|
||||
...eventData,
|
||||
});
|
||||
} else if (VER == "fuzzup"){
|
||||
await send.object({
|
||||
now_date: K.ITEM('u64', BigInt(Date.now())),
|
||||
extra: {
|
||||
extra_lv: K.ITEM('u8', extraData.level),
|
||||
extramusic: {
|
||||
music: extraData.musics.map(mid => {
|
||||
return {
|
||||
musicid: K.ITEM('s32', mid),
|
||||
get_border: K.ITEM('u8', 0),
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
infect_music: { term: K.ITEM('u8', 0) },
|
||||
unlock_challenge: { term: K.ITEM('u8', 0) },
|
||||
battle: { term: K.ITEM('u8', 0) },
|
||||
battle_chara: { term: K.ITEM('u8', 0) },
|
||||
data_ver_limit: { term: K.ITEM('s32', 0) },
|
||||
ea_pass_propel: { term: K.ITEM('u8', 0) },
|
||||
monthly_skill: {
|
||||
term: K.ITEM('u8', 0),
|
||||
target_music: {
|
||||
music: {
|
||||
musicid: K.ITEM('s32', 0),
|
||||
},
|
||||
},
|
||||
},
|
||||
update_prog: { term: K.ITEM('u8', 0) },
|
||||
rockwave: { event_list: {} },
|
||||
general_term: {},
|
||||
jubeat_omiyage_challenge: {},
|
||||
kac2017: {},
|
||||
nostalgia_concert: {},
|
||||
trbitemdata: {},
|
||||
ctrl_movie: {},
|
||||
ng_jacket: {},
|
||||
ng_recommend_music: {},
|
||||
ranking: {
|
||||
skill_0_999: {},
|
||||
skill_1000_1499: {},
|
||||
skill_1500_1999: {},
|
||||
skill_2000_2499: {},
|
||||
skill_2500_2999: {},
|
||||
skill_3000_3499: {},
|
||||
skill_3500_3999: {},
|
||||
skill_4000_4499: {},
|
||||
skill_4500_4999: {},
|
||||
skill_5000_5499: {},
|
||||
skill_5500_5999: {},
|
||||
skill_6000_6499: {},
|
||||
skill_6500_6999: {},
|
||||
skill_7000_7499: {},
|
||||
skill_7500_7999: {},
|
||||
skill_8000_8499: {},
|
||||
skill_8500_9999: {},
|
||||
total: {},
|
||||
original: {},
|
||||
bemani: {},
|
||||
famous: {},
|
||||
anime: {},
|
||||
band: {},
|
||||
western: {},
|
||||
},
|
||||
processing_report_state: K.ITEM('u8', 0),
|
||||
assert_report_state: K.ITEM('u8', 0),
|
||||
recommendmusic: { '@attr': { nr: 0 } },
|
||||
demomusic: { '@attr': { nr: 0 } },
|
||||
event_skill: {},
|
||||
temperature: { is_send: K.ITEM('bool', 0) },
|
||||
bemani_summer_2018: { is_open: K.ITEM('bool', 0) },
|
||||
kac2018: {
|
||||
event: {
|
||||
term: K.ITEM('s32', 0),
|
||||
since: K.ITEM('u64', BigInt(0)),
|
||||
till: K.ITEM('u64', BigInt(0)),
|
||||
is_open: K.ITEM('bool', 0),
|
||||
target_music: {
|
||||
music_id: K.ARRAY('s32', [0, 0, 0, 0, 0, 0]),
|
||||
},
|
||||
},
|
||||
},
|
||||
livehouse: {
|
||||
event_list: {
|
||||
event: {
|
||||
is_open: K.ITEM('bool', 0),
|
||||
term: K.ITEM('u8', 0),
|
||||
start_date_ms: K.ITEM('u64', BigInt(0)),
|
||||
end_date_ms: K.ITEM('u64', BigInt(0)),
|
||||
livehouse_name: K.ITEM('str', 'Asphyxia'),
|
||||
reward_list: {
|
||||
reward: {
|
||||
reward_id: K.ITEM('s32', 0),
|
||||
reward_kind: K.ITEM('s32', 0),
|
||||
reward_itemid: K.ITEM('s32', 0),
|
||||
unlock_border: K.ITEM('s32', 0),
|
||||
},
|
||||
},
|
||||
requirements_musicid: K.ITEM('s32', 0),
|
||||
member_table: K.ITEM('s32', 0),
|
||||
},
|
||||
},
|
||||
bonus: {
|
||||
term: K.ITEM('u8', 0),
|
||||
stage_bonus: K.ITEM('s32', 0),
|
||||
charm_bonus: K.ITEM('s32', 0),
|
||||
start_date_ms: K.ITEM('u64', BigInt(0)),
|
||||
end_date_ms: K.ITEM('u64', BigInt(0)),
|
||||
},
|
||||
},
|
||||
...eventData,
|
||||
});
|
||||
}//Older
|
||||
else {
|
||||
await send.object({
|
||||
now_date: K.ITEM('u64', BigInt(Date.now())),
|
||||
extra: {
|
||||
extra_lv: K.ITEM('u8', extraData.level),
|
||||
extramusic: {
|
||||
music: extraData.musics.map(mid => {
|
||||
return {
|
||||
musicid: K.ITEM('s32', mid),
|
||||
get_border: K.ITEM('u8', 0),
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
infect_music: { term: K.ITEM('u8', 0) },
|
||||
unlock_challenge: { term: K.ITEM('u8', 0) },
|
||||
battle: { term: K.ITEM('u8', 0) },
|
||||
battle_chara: { term: K.ITEM('u8', 0) },
|
||||
data_ver_limit: { term: K.ITEM('u8', 0) },
|
||||
ea_pass_propel: { term: K.ITEM('u8', 0) },
|
||||
monthly_skill: {
|
||||
term: K.ITEM('u8', 0),
|
||||
target_music: {
|
||||
music: {
|
||||
musicid: K.ITEM('s32', 0),
|
||||
},
|
||||
},
|
||||
},
|
||||
update_prog: { term: K.ITEM('u8', 0) },
|
||||
rockwave: { event_list: {} },
|
||||
general_term: {},
|
||||
jubeat_omiyage_challenge: {},
|
||||
kac2017: {},
|
||||
nostalgia_concert: {},
|
||||
trbitemdata: {},
|
||||
ctrl_movie: {},
|
||||
ng_jacket: {},
|
||||
ng_recommend_music: {},
|
||||
ranking: {
|
||||
skill_0_999: {},
|
||||
skill_1000_1499: {},
|
||||
skill_1500_1999: {},
|
||||
skill_2000_2499: {},
|
||||
skill_2500_2999: {},
|
||||
skill_3000_3499: {},
|
||||
skill_3500_3999: {},
|
||||
skill_4000_4499: {},
|
||||
skill_4500_4999: {},
|
||||
skill_5000_5499: {},
|
||||
skill_5500_5999: {},
|
||||
skill_6000_6499: {},
|
||||
skill_6500_6999: {},
|
||||
skill_7000_7499: {},
|
||||
skill_7500_7999: {},
|
||||
skill_8000_8499: {},
|
||||
skill_8500_9999: {},
|
||||
total: {},
|
||||
original: {},
|
||||
bemani: {},
|
||||
famous: {},
|
||||
anime: {},
|
||||
band: {},
|
||||
western: {},
|
||||
},
|
||||
processing_report_state: K.ITEM('u8', 0),
|
||||
assert_report_state: K.ITEM('u8', 0),
|
||||
recommendmusic: { '@attr': { nr: 0 } },
|
||||
demomusic: { '@attr': { nr: 0 } },
|
||||
event_skill: {},
|
||||
temperature: { is_send: K.ITEM('bool', 0) },
|
||||
bemani_summer_2018: { is_open: K.ITEM('bool', 0) },
|
||||
kac2018: {
|
||||
event: {
|
||||
term: K.ITEM('s32', 0),
|
||||
since: K.ITEM('u64', BigInt(0)),
|
||||
till: K.ITEM('u64', BigInt(0)),
|
||||
is_open: K.ITEM('bool', 0),
|
||||
target_music: {
|
||||
music_id: K.ARRAY('s32', [0, 0, 0, 0, 0, 0]),
|
||||
},
|
||||
},
|
||||
},
|
||||
KAC2016: {
|
||||
is_entry: K.ITEM('bool', 0),
|
||||
term: K.ITEM('u8', 0),
|
||||
musicid: K.ITEM('s32', 0),
|
||||
},
|
||||
KAC2016_skill_ranking: { term: K.ITEM('u8', 0) },
|
||||
season_sticker: { term: K.ITEM('u8', 0) },
|
||||
paseli_point_lose: { term: K.ITEM('u8', 0) },
|
||||
nostal_link: { term: K.ITEM('u8', 0) },
|
||||
encore_advent: { term: K.ITEM('u8', 0) },
|
||||
sdvx_stamprally: { term: K.ITEM('u8', 0) },
|
||||
sdvx_stamprally2: { term: K.ITEM('u8', 0) },
|
||||
floor_policy_2_info: { term: K.ITEM('u8', 0) },
|
||||
long_otobear_fes_2: {
|
||||
term: K.ITEM('u8', 0),
|
||||
bonus_musicid: K.ITEM('s32', 0),
|
||||
},
|
||||
...eventData,
|
||||
});
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
function getEventDataResponse() {
|
||||
|
|
@ -114,6 +370,41 @@ function getEventDataResponse() {
|
|||
},
|
||||
bear_fes: {},
|
||||
nextadium: {},
|
||||
galaxy_parade: {
|
||||
corner_list: {
|
||||
corner: {
|
||||
is_open: K.ITEM('bool', 0),
|
||||
data_ver: K.ITEM('s32', 0),
|
||||
genre: K.ITEM('s32', 0),
|
||||
corner_id: K.ITEM('s32', 0),
|
||||
corner_name: K.ITEM('str', ''),
|
||||
start_date_ms: K.ITEM('u64', BigInt(0)),
|
||||
end_date_ms: K.ITEM('u64', BigInt(0)),
|
||||
requirements_musicid: K.ITEM('s32', 0),
|
||||
reward_list: {
|
||||
reward: {
|
||||
reward_id: K.ITEM('s32', 0),
|
||||
reward_kind: K.ITEM('s32', 0),
|
||||
reward_itemid: K.ITEM('s32', 0),
|
||||
unlock_border: K.ITEM('s32', 0),
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
gacha_table: {
|
||||
chara_odds: {
|
||||
chara_id: K.ITEM('s32', 0),
|
||||
odds: K.ITEM('s32', 0),
|
||||
}
|
||||
},
|
||||
bonus: {
|
||||
term: K.ITEM('s32', 0),
|
||||
stage_bonus: K.ITEM('s32', 0),
|
||||
charm_bonus: K.ITEM('s32', 0),
|
||||
start_date_ms: K.ITEM('u64', BigInt(0)),
|
||||
end_date_ms: K.ITEM('u64', BigInt(0)),
|
||||
}
|
||||
},
|
||||
};
|
||||
const time = BigInt(31536000);
|
||||
|
||||
|
|
@ -129,7 +420,8 @@ function getEventDataResponse() {
|
|||
term: K.ITEM('u8', 0),
|
||||
start_date_ms: K.ITEM('u64', time),
|
||||
end_date_ms: K.ITEM('u64', time),
|
||||
bonus_musicid: {},
|
||||
//bonus_musicid: {},
|
||||
bonus_musicid: K.ITEM('s32', 0),
|
||||
};
|
||||
addition[`sdvx_stamprally3`] = obj;
|
||||
addition[`chronicle_1`] = obj;
|
||||
|
|
@ -159,14 +451,42 @@ function getEventDataResponse() {
|
|||
addition['monstar_subjugation'][`monstar_subjugation_${i}`] = obj;
|
||||
addition['bear_fes'][`bear_fes_${i}`] = obj;
|
||||
}
|
||||
|
||||
if (i <= 2) {
|
||||
addition[`gitadora_oracle_${i}`] = {
|
||||
term: K.ITEM('u8', 0),
|
||||
bonus_musicid: K.ITEM('s32', 0),
|
||||
};
|
||||
addition[`gitadora_oracle_${i}`] = {
|
||||
term: K.ITEM('u8', 0),
|
||||
bonus_musicid: K.ITEM('s32', 0),
|
||||
};
|
||||
}
|
||||
|
||||
if (i <= 3) {
|
||||
addition[`kouyou_challenge_${i}`] = {
|
||||
term: K.ITEM('u8', 0),
|
||||
bonus_musicid: K.ITEM('s32', 0),
|
||||
};
|
||||
addition[`dokidoki_valentine2_${i}`] = {
|
||||
term: K.ITEM('u8', 0),
|
||||
bonus_musicid: K.ITEM('s32', 0),
|
||||
};
|
||||
addition[`wakuteka_whiteday2_${i}`] = { term: K.ITEM('u8', 0) };
|
||||
addition[`ohanami_challenge_${i}`] = {
|
||||
term: K.ITEM('u8', 0),
|
||||
bonus_musicid: K.ITEM('s32', 0),
|
||||
};
|
||||
addition[`otobear_in_the_tsubo_${i}`] = {
|
||||
term: K.ITEM('u8', 0),
|
||||
bonus_musicid: K.ITEM('s32', 0),
|
||||
};
|
||||
addition[`summer_craft_${i}`] = {
|
||||
term: K.ITEM('u8', 0),
|
||||
bonus_musicid: K.ITEM('s32', 0),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return addition
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
/// <reference lib="es2020.bigint" />
|
||||
|
||||
import { getDefaultPlayerInfo, PlayerInfo } from "../models/playerinfo";
|
||||
import { PlayerRanking } from "../models/playerranking";
|
||||
import { getDefaultProfile, Profile } from "../models/profile";
|
||||
|
|
@ -8,7 +10,7 @@ import { getDefaultScores, Scores } from "../models/scores";
|
|||
|
||||
import { PLUGIN_VER } from "../const";
|
||||
import Logger from "../utils/logger"
|
||||
import { isAsphyxiaDebugMode } from "../utils/index";
|
||||
import { isAsphyxiaDebugMode, isSharedSongScoresEnabled } from "../utils/index";
|
||||
import { SecretMusicEntry } from "../models/secretmusicentry";
|
||||
import { CheckPlayerResponse, getCheckPlayerResponse } from "../models/Responses/checkplayerresponse";
|
||||
import { getPlayerStickerResponse, PlayerStickerResponse } from "../models/Responses/playerstickerresponse";
|
||||
|
|
@ -18,6 +20,7 @@ import { getDefaultBattleDataResponse } from "../models/Responses/battledataresp
|
|||
import { applySharedFavoriteMusicToExtra, saveSharedFavoriteMusicFromExtra } from "./FavoriteMusic";
|
||||
import { getPlayerRecordResponse } from "../models/Responses/playerrecordresponse";
|
||||
import { getPlayerPlayInfoResponse, PlayerPlayInfoResponse } from "../models/Responses/playerplayinforesponse";
|
||||
import { getMergedSharedScores, mergeScoresIntoShared } from "./SharedScores";
|
||||
|
||||
const logger = new Logger("profiles")
|
||||
|
||||
|
|
@ -70,6 +73,7 @@ export const getPlayer: EPR = async (info, data, send) => {
|
|||
const time = BigInt(31536000);
|
||||
const dm = isDM(info);
|
||||
const game = dm ? 'dm' : 'gf';
|
||||
const sharedScoresEnabled = isSharedSongScoresEnabled();
|
||||
|
||||
logger.debugInfo(`Loading ${game} profile for player ${no} with refid: ${refid}`)
|
||||
const name = await DB.FindOne<PlayerInfo>(refid, {
|
||||
|
|
@ -82,8 +86,8 @@ export const getPlayer: EPR = async (info, data, send) => {
|
|||
const gfRecord = await getRecord(refid, version, 'gf')
|
||||
const dmExtra = await getExtra(refid, version, 'dm')
|
||||
const gfExtra = await getExtra(refid, version, 'gf')
|
||||
const dmScores = (await getScore(refid, version, 'dm')).scores
|
||||
const gfScores = (await getScore(refid, version, 'gf')).scores
|
||||
const dmScores = sharedScoresEnabled ? await getMergedSharedScores(refid, 'dm') : (await getScore(refid, version, 'dm')).scores
|
||||
const gfScores = sharedScoresEnabled ? await getMergedSharedScores(refid, 'gf') : (await getScore(refid, version, 'gf')).scores
|
||||
|
||||
const profile = dm ? dmProfile : gfProfile;
|
||||
const extra = dm ? dmExtra : gfExtra;
|
||||
|
|
@ -213,13 +217,33 @@ export const getPlayer: EPR = async (info, data, send) => {
|
|||
recommend_musicid_list: K.ARRAY('s32', extra.recommend_musicid_list ?? Array(5).fill(-1)),
|
||||
record,
|
||||
groove: {
|
||||
extra_gauge: K.ITEM('s32', profile.extra_gauge),
|
||||
extra_gauge: K.ITEM('s32', (profile.extra_gauge+95)),
|
||||
encore_gauge: K.ITEM('s32', profile.encore_gauge),
|
||||
encore_cnt: K.ITEM('s32', profile.encore_cnt),
|
||||
encore_success: K.ITEM('s32', profile.encore_success),
|
||||
unlock_point: K.ITEM('s32', profile.unlock_point),
|
||||
},
|
||||
musiclist: { '@attr': { nr: musicdata.length }, musicdata },
|
||||
deluxe: {
|
||||
deluxe_content: K.ITEM('s32', 0),
|
||||
target_id: K.ITEM('s32', 0),
|
||||
multiply: K.ITEM('s32', 0),
|
||||
point: K.ITEM('s32', 0),
|
||||
},
|
||||
galaxy_parade: {
|
||||
score_list: {},
|
||||
last_corner_id: K.ITEM('s32', 0),
|
||||
chara_list: {},
|
||||
last_sort_category: K.ITEM('s32', 0),
|
||||
last_sort_order: K.ITEM('s32', 0),
|
||||
team_member: {
|
||||
chara_id_guitar: K.ITEM('s32', 0),
|
||||
chara_id_bass: K.ITEM('s32', 0),
|
||||
chara_id_drum: K.ITEM('s32', 0),
|
||||
chara_id_free1: K.ITEM('s32', 0),
|
||||
chara_id_free2: K.ITEM('s32', 0),
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const playerRanking = await getPlayerRanking(refid, version, game)
|
||||
|
|
@ -227,15 +251,55 @@ export const getPlayer: EPR = async (info, data, send) => {
|
|||
const addition: any = {
|
||||
monstar_subjugation: {},
|
||||
bear_fes: {},
|
||||
galaxy_parade: {
|
||||
corner_list: {
|
||||
corner: {
|
||||
is_open: K.ITEM('bool', 0),
|
||||
data_ver: K.ITEM('s32', 0),
|
||||
genre: K.ITEM('s32', 0),
|
||||
corner_id: K.ITEM('s32', 0),
|
||||
corner_name: K.ITEM('str', ''),
|
||||
start_date_ms: K.ITEM('u64', BigInt(0)),
|
||||
end_date_ms: K.ITEM('u64', BigInt(0)),
|
||||
requirements_musicid: K.ITEM('s32', 0),
|
||||
reward_list: {
|
||||
reward: {
|
||||
reward_id: K.ITEM('s32', 0),
|
||||
reward_kind: K.ITEM('s32', 0),
|
||||
reward_itemid: K.ITEM('s32', 0),
|
||||
unlock_border: K.ITEM('s32', 0),
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
gacha_table: {
|
||||
chara_odds: {
|
||||
chara_id: K.ITEM('s32', 0),
|
||||
odds: K.ITEM('s32', 0),
|
||||
}
|
||||
},
|
||||
bonus: {
|
||||
term: K.ITEM('s32', 0),
|
||||
stage_bonus: K.ITEM('s32', 0),
|
||||
charm_bonus: K.ITEM('s32', 0),
|
||||
start_date_ms: K.ITEM('u64', BigInt(0)),
|
||||
end_date_ms: K.ITEM('u64', BigInt(0)),
|
||||
}
|
||||
},
|
||||
};
|
||||
for (let i = 1; i <= 20; ++i) {
|
||||
const obj = { point: K.ITEM('s32', 0) };
|
||||
if (i == 1) {
|
||||
addition['long_otobear_fes_1'] = obj;
|
||||
addition['long_otobear_fes_2'] = obj;
|
||||
addition['phrase_combo_challenge'] = obj;
|
||||
addition['sdvx_stamprally'] = obj;
|
||||
addition['sdvx_stamprally2'] = obj;
|
||||
addition['sdvx_stamprally3'] = obj;
|
||||
addition['chronicle_1'] = obj;
|
||||
} else {
|
||||
addition['gitadora_oracle_1'] = obj;
|
||||
addition['gitadora_oracle_2'] = obj;
|
||||
} else {
|
||||
addition[`phrase_combo_challenge_${i}`] = obj;
|
||||
}
|
||||
|
||||
|
|
@ -254,6 +318,15 @@ export const getPlayer: EPR = async (info, data, send) => {
|
|||
point_3: K.ITEM('s32', 0),
|
||||
};
|
||||
addition[`kouyou_challenge_${i}`] = { point: K.ITEM('s32', 0) };
|
||||
addition[`dokidoki_valentine2_${i}`] = { point: K.ITEM('s32', 0) };
|
||||
addition[`ohanami_challenge_${i}`] = { point: K.ITEM('s32', 0) };
|
||||
addition[`otobear_in_the_tsubo_${i}`] = { point: K.ITEM('s32', 0) };
|
||||
addition[`summer_craft_${i}`] = { point: K.ITEM('s32', 0) };
|
||||
addition[`wakuteka_whiteday2_${i}`] = {
|
||||
point_1: K.ITEM('s32', 0),
|
||||
point_2: K.ITEM('s32', 0),
|
||||
point_3: K.ITEM('s32', 0),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -307,6 +380,21 @@ export const getPlayer: EPR = async (info, data, send) => {
|
|||
},
|
||||
event_score: { eventlist: {} },
|
||||
rockwave: { score_list: {} },
|
||||
livehouse: {
|
||||
score_list: {
|
||||
score: {
|
||||
term: K.ITEM('u8', -1),
|
||||
reward_id: K.ITEM('s32', -1),
|
||||
unlock_point: K.ITEM('s32', -1),
|
||||
chara_id_guitar: K.ITEM('s32', -1),
|
||||
chara_id_bass: K.ITEM('s32', -1),
|
||||
chara_id_drum: K.ITEM('s32', -1),
|
||||
chara_id_other: K.ITEM('s32', -1),
|
||||
leader: K.ITEM('s32', -1),
|
||||
},
|
||||
last_livehouse: K.ITEM('s32', -1),
|
||||
}
|
||||
},
|
||||
jubeat_omiyage_challenge: {},
|
||||
light_mode_reward_item: { itemid: K.ITEM('s32', -1), rarity: K.ITEM('s32', 0) },
|
||||
standard_mode_reward_item: { itemid: K.ITEM('s32', -1), rarity: K.ITEM('s32', 0) },
|
||||
|
|
@ -325,6 +413,20 @@ export const getPlayer: EPR = async (info, data, send) => {
|
|||
kac2017: {
|
||||
entry_status: K.ITEM('s32', 0),
|
||||
},
|
||||
KAC2016: {
|
||||
is_entry: K.ITEM('bool', 0),
|
||||
},
|
||||
KAC2016_skill_ranking: {
|
||||
skill: {
|
||||
skill: K.ITEM('s32', -1),
|
||||
rank: K.ITEM('s32', -1),
|
||||
total_nr: K.ITEM('s32', -1),
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
|
||||
|
||||
nostalgia_concert: {},
|
||||
bemani_summer_2018: {
|
||||
linkage_id: K.ITEM('s32', -1),
|
||||
|
|
@ -424,6 +526,7 @@ export const savePlayers: EPR = async (info, data, send) => {
|
|||
const version = getVersion(info);
|
||||
const dm = isDM(info);
|
||||
const game = dm ? 'dm' : 'gf';
|
||||
const sharedScoresEnabled = isSharedSongScoresEnabled();
|
||||
|
||||
let players = $(data).elements("player")
|
||||
|
||||
|
|
@ -449,7 +552,7 @@ export const savePlayers: EPR = async (info, data, send) => {
|
|||
throw "Request data is missing required parameter: player.refid"
|
||||
}
|
||||
|
||||
await saveSinglePlayer(player, refid, no, version, game);
|
||||
await saveSinglePlayer(player, refid, no, version, game, sharedScoresEnabled);
|
||||
|
||||
let ranking = await getPlayerRanking(refid, version, game)
|
||||
let responsePart = getSaveProfileResponse(no, ranking)
|
||||
|
|
@ -469,7 +572,7 @@ export const savePlayers: EPR = async (info, data, send) => {
|
|||
}
|
||||
};
|
||||
|
||||
async function saveSinglePlayer(dataplayer: KDataReader, refid: string, no: number, version: string, game: 'gf' | 'dm')
|
||||
async function saveSinglePlayer(dataplayer: KDataReader, refid: string, no: number, version: string, game: 'gf' | 'dm', sharedScoresEnabled: boolean)
|
||||
{
|
||||
logger.debugInfo(`Saving ${game} profile for player ${no} with refid: ${refid}`)
|
||||
const profile = await getProfile(refid, version, game) as any;
|
||||
|
|
@ -612,7 +715,11 @@ async function saveSinglePlayer(dataplayer: KDataReader, refid: string, no: numb
|
|||
logStagesPlayed(playedStages)
|
||||
|
||||
const scores = await updatePlayerScoreCollection(refid, playedStages, version, game)
|
||||
await saveScore(refid, version, game, scores);
|
||||
await saveScore(refid, version, game, scores);
|
||||
|
||||
if (sharedScoresEnabled) {
|
||||
await mergeScoresIntoShared(refid, game, scores);
|
||||
}
|
||||
await saveSharedFavoriteMusicFromExtra(refid, extra)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -40,12 +40,19 @@ export function register() {
|
|||
|
||||
R.Config("shared_favorite_songs", {
|
||||
name: "Shared Favorite Songs (Experimental)",
|
||||
desc: "If disabled, players will be able to keep separate lists of favorite songs for each version of Gitadora, as well as between Guitar Freaks and Drummania. " +
|
||||
desc: "If disabled, players will be able to keep separate lists of favorite songs for each version of Gitadora, as well as between Guitar Freaks and Drummania. " +
|
||||
"Enable this option to have a single unified list of favorite songs for both games, and across all versions. Default is false, to match original arcade behaviour.",
|
||||
type: "boolean",
|
||||
default: false,
|
||||
})
|
||||
|
||||
R.Config("shared_song_scores", {
|
||||
name: "Shared Song Scores (Experimental)",
|
||||
desc: "If disabled, players will keep separate scoreboards per version. Enable to merge best scores across all versions and games into a shared store.",
|
||||
type: "boolean",
|
||||
default: false,
|
||||
})
|
||||
|
||||
R.DataFile("data/mdb/custom.xml", {
|
||||
accept: ".xml",
|
||||
name: "Custom MDB",
|
||||
|
|
@ -56,11 +63,17 @@ export function register() {
|
|||
|
||||
const MultiRoute = (method: string, handler: EPR | boolean) => {
|
||||
// Helper for register multiple versions.
|
||||
R.Route(`${method}`, handler);
|
||||
R.Route(`re_${method}`, handler);
|
||||
R.Route(`matixx_${method}`, handler);
|
||||
R.Route(`exchain_${method}`, handler);
|
||||
R.Route(`matixx_${method}`, handler);
|
||||
R.Route(`nextage_${method}`, handler)
|
||||
R.Route(`highvoltage_${method}`, handler)
|
||||
// TODO: TB, TBRE and more older version?
|
||||
R.Route(`fuzzup_${method}`, handler)
|
||||
R.Route(`galaxywave_${method}`, handler)
|
||||
R.Route(`galaxywave_delta_${method}`, handler)
|
||||
// TODO: TB, and more older version?
|
||||
};
|
||||
|
||||
// Info
|
||||
|
|
|
|||
|
|
@ -24,16 +24,16 @@ export interface BattleDataResponse
|
|||
|
||||
score: {
|
||||
battle_class: KITEM<'s32'>,
|
||||
max_battle_class: KITEM<'s32'>,
|
||||
battle_point: KITEM<'s32'>,
|
||||
win: KITEM<'s32'>,
|
||||
lose: KITEM<'s32'>,
|
||||
draw: KITEM<'s32'>,
|
||||
consecutive_win: KITEM<'s32'>,
|
||||
max_consecutive_win: KITEM<'s32'>,
|
||||
glorious_win: KITEM<'s32'>,
|
||||
max_defeat_skill: KITEM<'s32'>,
|
||||
latest_result: KITEM<'s32'>,
|
||||
max_battle_class: KITEM<'s32'>,
|
||||
battle_point: KITEM<'s32'>,
|
||||
win: KITEM<'s32'>,
|
||||
lose: KITEM<'s32'>,
|
||||
draw: KITEM<'s32'>,
|
||||
consecutive_win: KITEM<'s32'>,
|
||||
max_consecutive_win: KITEM<'s32'>,
|
||||
glorious_win: KITEM<'s32'>,
|
||||
max_defeat_skill: KITEM<'s32'>,
|
||||
latest_result: KITEM<'s32'>,
|
||||
|
||||
}
|
||||
history: {}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ export interface CommonMusicDataField {
|
|||
is_hot: KITEM<"bool">;
|
||||
data_ver: KITEM<"s32">;
|
||||
diff: KARRAY<"u16">;
|
||||
seq_release_state: KITEM<"s32">;
|
||||
}
|
||||
|
||||
export interface CommonMusicData {
|
||||
|
|
|
|||
|
|
@ -34,8 +34,8 @@ export function getDefaultExtra(game: 'gf' | 'dm', version: string, id: number)
|
|||
reward_status: Array(50).fill(0),
|
||||
}
|
||||
result.playstyle[1] = 1 // Note scroll speed (should default to 1.0x)
|
||||
result.playstyle[36] = 20 // Unknown
|
||||
result.playstyle[48] = 20 // Unknown
|
||||
result.playstyle[36] = 20 // Target Timing Adjustment
|
||||
result.playstyle[48] = 20 // Note Display Adjustment
|
||||
|
||||
return result
|
||||
}
|
||||
|
|
|
|||
8
gitadora@asphyxia/models/playerstickerresponse.ts
Normal file
8
gitadora@asphyxia/models/playerstickerresponse.ts
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
export interface PlayerStickerResponse {
|
||||
id: KITEM<'s32'>,
|
||||
pos_x: KITEM<'float'> ,
|
||||
pos_y: KITEM<'float'>,
|
||||
scale_x: KITEM<'float'> ,
|
||||
scale_y: KITEM<'float'>,
|
||||
rotate: KITEM<'float'>
|
||||
}
|
||||
5
gitadora@asphyxia/models/secretmusicresponse.ts
Normal file
5
gitadora@asphyxia/models/secretmusicresponse.ts
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
export interface SecretMusicResponse {
|
||||
musicid: KITEM<'s32'>;
|
||||
seq: KITEM<'u16'>;
|
||||
kind: KITEM<'s32'>;
|
||||
}
|
||||
|
|
@ -8,7 +8,14 @@ export const isDM = (info: EamuseInfo) => {
|
|||
|
||||
export const getVersion = (info: EamuseInfo) => {
|
||||
const moduleName: string = info.module;
|
||||
return moduleName.match(/([^_]*)_(.*)/)[1];
|
||||
const moduleMatch = moduleName.match(/([^_]*)_(.*)/);
|
||||
|
||||
if (moduleMatch && moduleMatch[1]) {
|
||||
return moduleMatch[1];
|
||||
}
|
||||
|
||||
console.error(`Unable to parse version from module name "${moduleName}".`);
|
||||
return "unknown";
|
||||
};
|
||||
|
||||
export function isRequiredCoreVersion(major: number, minor: number) {
|
||||
|
|
@ -19,10 +26,14 @@ export function isRequiredCoreVersion(major: number, minor: number) {
|
|||
};
|
||||
|
||||
export function isAsphyxiaDebugMode() : boolean {
|
||||
const argv = process.argv
|
||||
return argv.includes("--dev") || argv.includes("--console")
|
||||
const argv = (globalThis as { process?: { argv?: string[] } }).process?.argv ?? [];
|
||||
return argv.includes("--dev") || argv.includes("--console");
|
||||
}
|
||||
|
||||
export function isSharedFavoriteMusicEnabled() : boolean{
|
||||
return Boolean(U.GetConfig("shared_favorite_songs"))
|
||||
}
|
||||
}
|
||||
|
||||
export function isSharedSongScoresEnabled() : boolean{
|
||||
return Boolean(U.GetConfig("shared_song_scores"))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,21 +14,31 @@
|
|||
return "Unknown"
|
||||
}
|
||||
}
|
||||
|
||||
function getFullVersionName(shortName) {
|
||||
switch (shortName) {
|
||||
case "exchain" :
|
||||
return "GITADORA EXCHAIN"
|
||||
|
||||
function getFullGameVersion(shortVer) {
|
||||
switch (shortVer) {
|
||||
case "re" :
|
||||
return "Tri-Boost Re:EVOLVE"
|
||||
case "matixx":
|
||||
return "Matixx"
|
||||
case "EXCHAIN":
|
||||
return "exchain"
|
||||
case "nextage":
|
||||
return "GITADORA NEX+AGE"
|
||||
return "NEX+AGE"
|
||||
case "highvoltage":
|
||||
return "GITADORA HIGH-VOLTAGE"
|
||||
default:
|
||||
return "HIGH-VOLTAGE"
|
||||
case "fuzzup":
|
||||
return "FUZZ-UP"
|
||||
case "galaxywave":
|
||||
return "GALAXY WAVE"
|
||||
case "galaxywave_delta":
|
||||
return "GALAXY WAVE DELTA"
|
||||
default:
|
||||
return "Unknown"
|
||||
}
|
||||
}
|
||||
|
||||
const versions = ["exchain", "nextage", "highvoltage"]
|
||||
const versions = ["re", "matixx", "exchain", "nextage", "highvoltage", "fuzzup", "galaxywave", "galaxywave_delta"]
|
||||
const games = ["gf", "dm"]
|
||||
|
||||
function generateLeaderboards(infos, profiles) {
|
||||
|
|
@ -77,7 +87,7 @@
|
|||
-
|
||||
|
||||
each board in generateLeaderboards(infos, profiles)
|
||||
h3 #{getFullVersionName(board.version)} #{getFullGameName(board.game)}
|
||||
h3 #{getFullGameName(board.game)} #{getFullGameVersion(board.version)}
|
||||
table
|
||||
tr
|
||||
th Rank
|
||||
|
|
|
|||
|
|
@ -6,11 +6,34 @@
|
|||
-
|
||||
function getFullGameName(shortName) {
|
||||
switch (shortName) {
|
||||
case "gf":
|
||||
return "GuitarFreaks"
|
||||
case "dm" :
|
||||
return "Drummania"
|
||||
case "gf":
|
||||
return "Guitar Freaks"
|
||||
default:
|
||||
return "DrumMania"
|
||||
default:
|
||||
return "Unknown"
|
||||
}
|
||||
}
|
||||
|
||||
function getFullGameVersion(shortVer) {
|
||||
switch (shortVer) {
|
||||
case "re" :
|
||||
return "Tri-Boost Re:EVOLVE"
|
||||
case "matixx":
|
||||
return "Matixx"
|
||||
case "EXCHAIN":
|
||||
return "exchain"
|
||||
case "nextage":
|
||||
return "NEX+AGE"
|
||||
case "highvoltage":
|
||||
return "HIGH-VOLTAGE"
|
||||
case "fuzzup":
|
||||
return "FUZZ-UP"
|
||||
case "galaxywave":
|
||||
return "GALAXY WAVE"
|
||||
case "galaxywave_delta":
|
||||
return "GALAXY WAVE DELTA"
|
||||
default:
|
||||
return "Unknown"
|
||||
}
|
||||
}
|
||||
|
|
@ -23,7 +46,7 @@ div
|
|||
p.card-header-title
|
||||
span.icon
|
||||
i.mdi.mdi-account-edit
|
||||
| User Detail (#{i.version})
|
||||
| User Detail (#{getFullGameVersion(i.version)})
|
||||
.card-content
|
||||
form(method="post" action="/emit/updatePlayerInfo")
|
||||
.field
|
||||
|
|
@ -55,7 +78,7 @@ div
|
|||
p.card-header-title
|
||||
span.icon
|
||||
i.mdi.mdi-account-details
|
||||
| Profile Detail (#{getFullGameName(pr.game)} #{pr.version})
|
||||
| Profile Detail (#{getFullGameName(pr.game)} #{getFullGameVersion(pr.version)})
|
||||
.card-content
|
||||
form(method="post")
|
||||
.field
|
||||
|
|
|
|||
170
iidx@asphyxia/README.md
Normal file
170
iidx@asphyxia/README.md
Normal file
|
|
@ -0,0 +1,170 @@
|
|||
# beatmaniaIIDX
|
||||
|
||||
Plugin Version: **v0.1.17**
|
||||
|
||||
---
|
||||
|
||||
Supported Versions
|
||||
- beatmaniaIIDX 14 GOLD (2007072301)
|
||||
- beatmaniaIIDX 15 DJ TROOPERS (2008031100)
|
||||
- beatmaniaIIDX 16 EMPRESS (2009072200)
|
||||
- beatmaniaIIDX 17 SIRIUS (2010071200)
|
||||
- beatmaniaIIDX 18 Resort Anthem (2011071200)
|
||||
- beatmaniaIIDX 19 Lincle (2012090300)
|
||||
- beatmaniaIIDX 20 tricoro (2013090900)
|
||||
- beatmaniaIIDX 21 SPADA (2014071600)
|
||||
- beatmaniaIIDX 22 PENDUAL (2015080500)
|
||||
- beatmaniaIIDX 23 copula (2016083100)
|
||||
- beatmaniaIIDX 24 SINOBUZ (2017082800)
|
||||
- beatmaniaIIDX 25 CANNON BALLERS (2018091900)
|
||||
- beatmaniaIIDX 26 Rootage (2019090200)
|
||||
- beatmaniaIIDX 27 HEROIC VERSE (2020092900)
|
||||
- beatmaniaIIDX 28 BISTROVER (2021091500)
|
||||
- beatmaniaIIDX 29 CastHour (2022082400)
|
||||
- beatmaniaIIDX 30 RESIDENT (2023090500)
|
||||
- beatmaniaIIDX 31 EPOLIS (2024082600)
|
||||
- beatmaniaIIDX 32 Pinky Crush (2025082500)
|
||||
|
||||
---
|
||||
|
||||
Features
|
||||
- STEP UP (Partial)
|
||||
- SKILL ANALYZER
|
||||
- EVENT (Partial)
|
||||
- ARENA (LOCAL only)
|
||||
- RANDOME LANE TICKET
|
||||
- FAVORITE/SONG SELECTION NOTES
|
||||
- ORIGINAL FILTER
|
||||
|
||||
---
|
||||
|
||||
Known Issues
|
||||
- Clear Lamps may display invalid lamps due to missing conversion code
|
||||
- DJ LEVEL folders are broken in ~ DJ TROOPERS due to missing rank\_id
|
||||
- LEGGENDARIA play records before HEROIC VERSE may not display on higher version due to missing conversion code
|
||||
- SUPER FUTURE 2323 play records doesn't display on other version due to missing conversion code
|
||||
- ONE MORE EXTRA STAGE progress won't save (can't test this due to skill issue)
|
||||
- Some of licensed songs are locked behind (kinda solved with music\_open but needs to be verified)
|
||||
- Some of badges aren't saving in RESIDENT ~ (needs to figure out name to id)
|
||||
|
||||
---
|
||||
|
||||
Changelogs
|
||||
|
||||
**v0.1.0**
|
||||
- Added Initial support for Lincle
|
||||
|
||||
**v0.1.1**
|
||||
- Added Initial support for HEROIC VERSE
|
||||
- Expanded score array to adapting newer difficulty (SPN ~ DPA [6] -> SPB ~ DPL [10])
|
||||
- This borked previous score datas recorded with v0.1.0
|
||||
- All score data now shared with all version
|
||||
- as it doesn't have music\_id conversion, it will display incorrect data on certain versions
|
||||
- Added Initial customize support (no webui)
|
||||
|
||||
**v0.1.2**
|
||||
- Added Initial support for BISTROVER
|
||||
- Added Initial Rival support (partial webui)
|
||||
|
||||
**v0.1.3**
|
||||
- Added Initial support for CastHour
|
||||
|
||||
**v0.1.4**
|
||||
- Added Initial support for RESIDENT
|
||||
|
||||
**v0.1.5**
|
||||
- Added Initial support for Resort Anthem
|
||||
- LEAGUE, STORY does not work yet
|
||||
- Fixed where s\_hispeed/d\_hispeed doesn't save correctly
|
||||
|
||||
**v0.1.6**
|
||||
- Added Initial support for tricoro
|
||||
- Some of event savings are broken
|
||||
- Added movie\_upload url setting on plugin setting (BISTROVER ~)
|
||||
- This uses JSON instead of XML and this requires additional setup (can't test or implement this as I don't own NVIDIA GPU)
|
||||
|
||||
**v0.1.7**
|
||||
- Added Initial support for SPADA
|
||||
- Some of event savings are broken
|
||||
- Fixed where rtype didn't save correctly (BISTROVER ~)
|
||||
|
||||
**v0.1.8**
|
||||
- Added RIVAL pacemaker support
|
||||
- Added Initial support for PENDUAL
|
||||
- Some of event savings are broken
|
||||
- Fixed where old\_linkage\_secret\_flg is missing on pc.get response (RESIDENT)
|
||||
- Fixed where game could crash due to invalid rival qprodata
|
||||
- Fixed where lift isn't saving (SPADA)
|
||||
|
||||
**v0.1.9**
|
||||
- Added Initial support for copula
|
||||
- Some of event savings are broken
|
||||
- Added shop.getconvention/shop.setconvention/shop.getname/shop.savename response
|
||||
|
||||
**v0.1.10**
|
||||
- Added Initial support for SINOBUZ ~ Rootage
|
||||
- Converted from asphyxia\_route\_public
|
||||
|
||||
**v0.1.11**
|
||||
- Added Shop Ranking support
|
||||
- Changed pc.common/gameSystem.systemInfo response not to use pugFile
|
||||
- IIDX\_CPUS on models/arena.ts came from asphyxia\_route\_public
|
||||
|
||||
**v0.1.12**
|
||||
- Exposed some of pc.common attributes to plugin settings (WIP)
|
||||
- Added Experimental WebUI (WIP)
|
||||
- Added music.crate/music.breg response
|
||||
- CLEAR RATE and BEGINNER clear lamp may not work on certain versions
|
||||
- Added Initial support for SIRIUS
|
||||
- Fixed where Venue Top didn't save correctly (BISTROVER ~)
|
||||
- Fixed where music.appoint send empty response even rival has score data but player doesn't have score data
|
||||
- Fixed where FAVORITE may work only on specific version
|
||||
- Fixed where shop name always displayed as "CORE" instead of saved one
|
||||
- Fixed where rlist STEP UP achieve value was fixed value instead of saved one
|
||||
- Fixed where fcombo isn't saving (Resort Anthem)
|
||||
- Removed shop.savename as not working as intented
|
||||
|
||||
**v0.1.13**
|
||||
- Added Initial support for DJ TROOPERS
|
||||
- Added Initial support for EMPRESS
|
||||
- Fixed where EXPERT result does not display total cleared users and ranking position
|
||||
|
||||
**v0.1.14**
|
||||
- Added Experimental OMEGA-Attack event saving support on tricoro
|
||||
- Reworked on SINOBUZ ~ Rootage responses
|
||||
- Fixed where Base64toBuffer returns invalid value sometimes
|
||||
- Fixed where timing display option isn't saving on certain versions
|
||||
|
||||
**v0.1.15**
|
||||
- Added Initial support for GOLD
|
||||
- Added Disable Beginner Option
|
||||
- Added Experimental Badge saving support
|
||||
- Added Experimental score import/export
|
||||
- Fixed where plugin may fail to register due to missing types in dev mode (invalid setup for dev, just enough to get around)
|
||||
- Fixed where unable to login after first-play (SPADA, SINOBUZ, Rootage)
|
||||
- Fixed where pacemaker isn't working as intended due to malformed ghost data on music.appoint response (~ DJ TROOPERS)
|
||||
- Fixed where pacemaker isn't working as intented due to wrong condition check (HEROIC VERSE ~)
|
||||
- Fixed where pacemaker sub-type isn't load correctly (HEROIC VERSE ~)
|
||||
- Fixed where QPRO data doesn't get saved in WebUI
|
||||
|
||||
**v0.1.16**
|
||||
- Added Initial support for EPOLIS
|
||||
- Added music\_open on gameSystem.systemInfo response
|
||||
- Added EXTRA FAVORITE support
|
||||
- Fixed where lightning settings doesn't get saved on logout
|
||||
- Fixed where Disable Music Preview, Disable HCN Color, VEFX Lock settings doesn't reflect
|
||||
- Fixed where MISS COUNT has 0 as default (including score import)
|
||||
- Fixed where MISS COUNT doesn't get updated when exscore is same
|
||||
- Fixed where lightning model settings saved incorrectly
|
||||
- Fixed where unable to import score if user has DP scores
|
||||
- Fixed where unable to achieve dan if you failed once
|
||||
- Fixed where unable to login (tricoro, CastHour, Rootage)
|
||||
- Fixed where unable to specify rival in WebUI
|
||||
- Fixed where music.arenaCPU isn't working as intended due to change of type (EPOLIS ~)
|
||||
- Fixed where qpro head equip request handle as hand equip (@anzuwork)
|
||||
- Added error message for invalid score database entries
|
||||
- Reverted `v0.1.15` dev mode related code changes (now requires proper dev setup, refer parent README.md)
|
||||
- WebUI is now display values of corresponding version
|
||||
|
||||
**v0.1.17**
|
||||
- Added Initial support for Pinky Crush
|
||||
94
iidx@asphyxia/data/grade.json
Normal file
94
iidx@asphyxia/data/grade.json
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
{
|
||||
"31": {
|
||||
"0": {
|
||||
"15": {
|
||||
"music_id": [ 25090, 23068, 19004, 29045 ],
|
||||
"class_id": [ 3, 3, 3, 3 ],
|
||||
"kind": 0
|
||||
},
|
||||
"16": {
|
||||
"music_id": [ 23005, 27078, 22065, 27060 ],
|
||||
"class_id": [ 3, 3, 3, 3 ],
|
||||
"kind": 0
|
||||
},
|
||||
"17": {
|
||||
"music_id": [ 29007, 26108, 19002, 18004 ],
|
||||
"class_id": [ 3, 3, 3, 3 ],
|
||||
"kind": 0
|
||||
},
|
||||
"18": {
|
||||
"music_id": [ 25007, 18032, 16020, 12004 ],
|
||||
"class_id": [ 3, 3, 3, 3 ],
|
||||
"kind": 0
|
||||
}
|
||||
},
|
||||
"1": {
|
||||
"15": {
|
||||
"music_id": [ 15032, 29033, 27092, 30020 ],
|
||||
"class_id": [ 3, 3, 3, 3 ],
|
||||
"kind": 0
|
||||
},
|
||||
"16": {
|
||||
"music_id": [ 10028, 26070, 28091, 23075 ],
|
||||
"class_id": [ 3, 3, 3, 3 ],
|
||||
"kind": 0
|
||||
},
|
||||
"17": {
|
||||
"music_id": [ 26012, 28002, 17017, 28005 ],
|
||||
"class_id": [ 3, 3, 3, 3 ],
|
||||
"kind": 0
|
||||
},
|
||||
"18": {
|
||||
"music_id": [ 28008, 15001, 19002, 9028 ],
|
||||
"class_id": [ 3, 3, 3, 3 ],
|
||||
"kind": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
"32": {
|
||||
"0": {
|
||||
"15": {
|
||||
"music_id": [ 19022, 30033, 27013, 29045 ],
|
||||
"class_id": [ 3, 3, 3, 3 ],
|
||||
"kind": 0
|
||||
},
|
||||
"16": {
|
||||
"music_id": [ 27034, 24023, 16009, 25085 ],
|
||||
"class_id": [ 3, 3, 3, 3 ],
|
||||
"kind": 0
|
||||
},
|
||||
"17": {
|
||||
"music_id": [ 26087, 19002, 29050, 30024 ],
|
||||
"class_id": [ 3, 3, 3, 3 ],
|
||||
"kind": 0
|
||||
},
|
||||
"18": {
|
||||
"music_id": [ 30052, 18032, 16020, 12004 ],
|
||||
"class_id": [ 3, 3, 3, 3 ],
|
||||
"kind": 0
|
||||
}
|
||||
},
|
||||
"1": {
|
||||
"15": {
|
||||
"music_id": [ 12002, 31063, 23046, 30020 ],
|
||||
"class_id": [ 3, 3, 3, 3 ],
|
||||
"kind": 0
|
||||
},
|
||||
"16": {
|
||||
"music_id": [ 26106, 14021, 29052, 23075 ],
|
||||
"class_id": [ 3, 3, 3, 3 ],
|
||||
"kind": 0
|
||||
},
|
||||
"17": {
|
||||
"music_id": [ 29042, 26043, 17017, 28005 ],
|
||||
"class_id": [ 3, 3, 3, 3 ],
|
||||
"kind": 0
|
||||
},
|
||||
"18": {
|
||||
"music_id": [ 25007, 29017, 19002, 9028 ],
|
||||
"class_id": [ 3, 3, 3, 3 ],
|
||||
"kind": 0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
82
iidx@asphyxia/data/music_open.json
Normal file
82
iidx@asphyxia/data/music_open.json
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
{
|
||||
"26": {
|
||||
"26002": { "kind": 0 },
|
||||
"26006": { "kind": 0 },
|
||||
"26022": { "kind": 0 },
|
||||
"26045": { "kind": 0 }
|
||||
},
|
||||
"27": {
|
||||
"27070": { "kind": 0 },
|
||||
"27071": { "kind": 0 },
|
||||
"27073": { "kind": 0 }
|
||||
},
|
||||
"28": {
|
||||
"28001": { "kind": 0 },
|
||||
"28036": { "kind": 0 },
|
||||
"28038": { "kind": 0 },
|
||||
"28072": { "kind": 0 },
|
||||
"28074": { "kind": 0 }
|
||||
},
|
||||
"29": {
|
||||
"29071": { "kind": 0 },
|
||||
"29072": { "kind": 0 },
|
||||
"29075": { "kind": 0 },
|
||||
"29081": { "kind": 0 },
|
||||
"29082": { "kind": 0 },
|
||||
"29085": { "kind": 0 },
|
||||
"29101": { "kind": 0 },
|
||||
"29102": { "kind": 0 },
|
||||
"29103": { "kind": 0 }
|
||||
},
|
||||
"30": {
|
||||
"30038": { "kind": 0 },
|
||||
"30082": { "kind": 0 },
|
||||
"30083": { "kind": 0 },
|
||||
"30084": { "kind": 0 },
|
||||
"30085": { "kind": 0 },
|
||||
"30101": { "kind": 0 },
|
||||
"30102": { "kind": 0 },
|
||||
"30104": { "kind": 0 },
|
||||
"30105": { "kind": 0 }
|
||||
},
|
||||
"31": {
|
||||
"31021": { "kind": 0 },
|
||||
"31022": { "kind": 0 },
|
||||
"31023": { "kind": 0 },
|
||||
"31024": { "kind": 0 },
|
||||
"31025": { "kind": 0 },
|
||||
"31065": { "kind": 0 },
|
||||
"31066": { "kind": 0 },
|
||||
"31097": { "kind": 0 },
|
||||
"31098": { "kind": 0 },
|
||||
"31099": { "kind": 0 },
|
||||
"31100": { "kind": 0 },
|
||||
"31101": { "kind": 0 },
|
||||
"31102": { "kind": 0 },
|
||||
"31110": { "kind": 0 },
|
||||
"31112": { "kind": 0 },
|
||||
"31113": { "kind": 0 }
|
||||
},
|
||||
"32": {
|
||||
"32022": { "kind": 0 },
|
||||
"32049": { "kind": 0 },
|
||||
"32078": { "kind": 0 },
|
||||
"32079": { "kind": 0 },
|
||||
"32080": { "kind": 0 },
|
||||
"32081": { "kind": 0 },
|
||||
"32082": { "kind": 0 },
|
||||
"32083": { "kind": 0 },
|
||||
"32084": { "kind": 0 },
|
||||
"32085": { "kind": 0 },
|
||||
"32096": { "kind": 0 },
|
||||
"32097": { "kind": 0 },
|
||||
"32098": { "kind": 0 },
|
||||
"32019": { "kind": 0 },
|
||||
"32101": { "kind": 0 },
|
||||
"32102": { "kind": 0 },
|
||||
"32103": { "kind": 0 },
|
||||
"32104": { "kind": 0 },
|
||||
"32110": { "kind": 0 },
|
||||
"32111": { "kind": 0 }
|
||||
}
|
||||
}
|
||||
177
iidx@asphyxia/handlers/gamesystem.ts
Normal file
177
iidx@asphyxia/handlers/gamesystem.ts
Normal file
|
|
@ -0,0 +1,177 @@
|
|||
import { IIDX_CPUS } from "../models/arena";
|
||||
import { GetVersion } from "../util";
|
||||
|
||||
export const gssysteminfo: EPR = async (info, data, send) => {
|
||||
const version = GetVersion(info);
|
||||
if (version < 24) return send.success();
|
||||
|
||||
let result: any = {
|
||||
arena_schedule: {
|
||||
phase: K.ITEM("u8", U.GetConfig("ArenaPhase")),
|
||||
start: K.ITEM("u32", 1605784800),
|
||||
end: K.ITEM("u32", 4102326000)
|
||||
},
|
||||
arena_music_difficult: [],
|
||||
maching_class_range: [],
|
||||
arena_cpu_define: [],
|
||||
}
|
||||
|
||||
// following datas are made up needs to figure out correct way to do it //
|
||||
let music_open = JSON.parse(await IO.ReadFile("data/music_open.json", "utf-8"));
|
||||
if (!_.isNil(music_open[version])) {
|
||||
result = Object.assign(result, { music_open: [] });
|
||||
|
||||
Object.keys(music_open).forEach(v => {
|
||||
Object.keys(music_open[v]).forEach(m => {
|
||||
if (Number(v) > version) return;
|
||||
|
||||
result.music_open.push({
|
||||
music_id: K.ITEM("s32", Number(m)),
|
||||
kind: K.ITEM("s32", music_open[v][m].kind),
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
switch (version) {
|
||||
case 32:
|
||||
result.arena_schedule.phase = K.ITEM("u8", 3);
|
||||
result.arena_schedult = Object.assign(result.arena_schedule, { season: K.ITEM("u8", 0) }); // arena season for online //
|
||||
|
||||
case 31:
|
||||
result.arena_schedult = Object.assign(result.arena_schedule, { rule_type: K.ITEM("u8", 0) }); // arena rule for online //
|
||||
|
||||
result = Object.assign(result, { grade_course: [] });
|
||||
|
||||
// following datas are made up needs to figure out correct way to do it //
|
||||
let grade = JSON.parse(await IO.ReadFile("data/grade.json", "utf-8"));
|
||||
if (!_.isNil(grade[version])) {
|
||||
Object.keys(grade[version]).forEach(s => {
|
||||
Object.keys(grade[version][s]).forEach(c => {
|
||||
result.grade_course.push({
|
||||
play_style: K.ITEM("s32", Number(s)),
|
||||
grade_id: K.ITEM("s32", Number(c)),
|
||||
is_valid: K.ITEM("bool", true),
|
||||
music_id_0: K.ITEM("s32", grade[version][s][c].music_id[0]),
|
||||
class_id_0: K.ITEM("s32", grade[version][s][c].class_id[0]),
|
||||
music_id_1: K.ITEM("s32", grade[version][s][c].music_id[1]),
|
||||
class_id_1: K.ITEM("s32", grade[version][s][c].class_id[1]),
|
||||
music_id_2: K.ITEM("s32", grade[version][s][c].music_id[2]),
|
||||
class_id_2: K.ITEM("s32", grade[version][s][c].class_id[2]),
|
||||
music_id_3: K.ITEM("s32", grade[version][s][c].music_id[3]),
|
||||
class_id_3: K.ITEM("s32", grade[version][s][c].class_id[3]),
|
||||
index: K.ITEM("s32", result.grade_course.length),
|
||||
cube_num: K.ITEM("s32", 0),
|
||||
kind: K.ITEM("s32", grade[version][s][c].kind),
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// arena_music_difficult //
|
||||
for (let s = 0; s < 2; ++s) {
|
||||
for (let c = 0; c < 20; ++c) {
|
||||
result.arena_music_difficult.push({
|
||||
play_style: K.ITEM("s32", s),
|
||||
arena_class: K.ITEM("s32", c),
|
||||
low_difficult: K.ITEM("s32", 1),
|
||||
high_difficult: K.ITEM("s32", 12),
|
||||
is_leggendaria: K.ITEM("bool", 1),
|
||||
force_music_list_id: K.ITEM("s32", 0),
|
||||
});
|
||||
|
||||
result.maching_class_range.push({
|
||||
play_style: K.ITEM("s32", s),
|
||||
matching_class: K.ITEM("s32", c),
|
||||
low_arena_class: K.ITEM("s32", 1),
|
||||
high_arena_class: K.ITEM("s32", 20),
|
||||
});
|
||||
|
||||
result.arena_cpu_define.push({
|
||||
play_style: K.ITEM("s32", s),
|
||||
arena_class: K.ITEM("s32", c),
|
||||
grade_id: K.ITEM("s32", IIDX_CPUS[s][c][0]),
|
||||
low_music_difficult: K.ITEM("s32", IIDX_CPUS[s][c][1]),
|
||||
high_music_difficult: K.ITEM("s32", IIDX_CPUS[s][c][2]),
|
||||
is_leggendaria: K.ITEM("bool", IIDX_CPUS[s][c][3]),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
switch (version) {
|
||||
case 29:
|
||||
result = Object.assign(result, {
|
||||
CommonBossPhase: K.ATTR({ val: String(3) }),
|
||||
Event1InternalPhase: K.ATTR({ val: String(U.GetConfig("ch_event")) }),
|
||||
ExtraBossEventPhase: K.ATTR({ val: String(U.GetConfig("ch_extraboss")) }),
|
||||
isNewSongAnother12OpenFlg: K.ATTR({ val: String(Number(U.GetConfig("NewSongAnother12"))) }),
|
||||
gradeOpenPhase: K.ATTR({ val: String(U.GetConfig("Grade")) }),
|
||||
isEiseiOpenFlg: K.ATTR({ val: String(Number(U.GetConfig("Eisei"))) }),
|
||||
WorldTourismOpenList: K.ATTR({ val: String(-1) }),
|
||||
BPLBattleOpenPhase: K.ATTR({ val: String(2) }),
|
||||
});
|
||||
break;
|
||||
case 30:
|
||||
result = Object.assign(result, {
|
||||
CommonBossPhase: K.ATTR({ val: String(3) }),
|
||||
Event1InternalPhase: K.ATTR({ val: String(U.GetConfig("rs_event")) }),
|
||||
ExtraBossEventPhase: K.ATTR({ val: String(U.GetConfig("rs_extraboss")) }),
|
||||
isNewSongAnother12OpenFlg: K.ATTR({ val: String(Number(U.GetConfig("NewSongAnother12"))) }),
|
||||
gradeOpenPhase: K.ATTR({ val: String(U.GetConfig("Grade")) }),
|
||||
isEiseiOpenFlg: K.ATTR({ val: String(Number(U.GetConfig("Eisei"))) }),
|
||||
WorldTourismOpenList: K.ATTR({ val: String(-1) }),
|
||||
BPLBattleOpenPhase: K.ATTR({ val: String(2) }),
|
||||
})
|
||||
break;
|
||||
case 31:
|
||||
let totalMetron = 0;
|
||||
let eventData = await DB.Find(null, {
|
||||
collection: "event_1",
|
||||
version: version,
|
||||
event_data: "myepo_map",
|
||||
});
|
||||
|
||||
if (!_.isNil(eventData)) {
|
||||
eventData.forEach((res: any) => {
|
||||
totalMetron += Number(res.metron_total_get);
|
||||
});
|
||||
}
|
||||
|
||||
Object.assign(result, {
|
||||
CommonBossPhase: K.ATTR({ val: String(3) }),
|
||||
Event1Value: K.ATTR({ val: String(U.GetConfig("ep_event")) }),
|
||||
Event1Phase: K.ATTR({ val: String(U.GetConfig("ep_event1")) }),
|
||||
Event2Phase: K.ATTR({ val: String(U.GetConfig("ep_event2")) }),
|
||||
ExtraBossEventPhase: K.ATTR({ val: String(U.GetConfig("ep_extraboss")) }),
|
||||
isNewSongAnother12OpenFlg: K.ATTR({ val: String(Number(U.GetConfig("NewSongAnother12"))) }),
|
||||
isKiwamiOpenFlg: K.ATTR({ val: String(Number(U.GetConfig("Eisei"))) }),
|
||||
WorldTourismOpenList: K.ATTR({ val: String(-1) }),
|
||||
BPLBattleOpenPhase: K.ATTR({ val: String(2) }),
|
||||
UnlockLeggendaria: K.ATTR({ val: String(1) }),
|
||||
BPLSerialCodePhase: K.ATTR({ val: String(0) }),
|
||||
Event1AllPlayerTotalGetMetron: K.ATTR({ val: String(totalMetron) }), // total amount of all users metron //
|
||||
});
|
||||
break;
|
||||
case 32:
|
||||
result = Object.assign(result, {
|
||||
Event1Value: K.ATTR({ val: String(U.GetConfig("pc_event")) }), // TEST //
|
||||
Event1Phase: K.ATTR({ val: String(U.GetConfig("pc_event1")) }), // TEST //
|
||||
Event2Phase: K.ATTR({ val: String(U.GetConfig("pc_event2")) }), // TEST //
|
||||
ExtraBossEventPhase: K.ATTR({ val: String(U.GetConfig("pc_extraboss")) }), // TEST //
|
||||
isNewSongAnother12OpenFlg: K.ATTR({ val: String(Number(U.GetConfig("NewSongAnother12"))) }),
|
||||
isKiwamiOpenFlg: K.ATTR({ val: String(Number(U.GetConfig("Eisei"))) }),
|
||||
WorldTourismOpenList: K.ATTR({ val: String(-1) }),
|
||||
OldBPLBattleOpenPhase: K.ATTR({ val: String(3) }),
|
||||
});
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return send.object(result);
|
||||
};
|
||||
208
iidx@asphyxia/handlers/grade.ts
Normal file
208
iidx@asphyxia/handlers/grade.ts
Normal file
|
|
@ -0,0 +1,208 @@
|
|||
import { pcdata } from "../models/pcdata";
|
||||
import { grade } from "../models/grade";
|
||||
import { IDtoRef, GetVersion } from "../util";
|
||||
import { eisei_grade } from "../models/lightning";
|
||||
import { badge } from "../models/badge";
|
||||
|
||||
export const graderaised: EPR = async (info, data, send) => {
|
||||
const version = GetVersion(info);
|
||||
const iidxid = Number($(data).attr().iidxid);
|
||||
const refid = await IDtoRef(iidxid);
|
||||
const gid = Number($(data).attr().gid);
|
||||
const gtype = Number($(data).attr().gtype);
|
||||
|
||||
let cflg = Number($(data).attr().cflg);
|
||||
let achi = Number($(data).attr().achi);
|
||||
|
||||
let pcdata = await DB.FindOne<pcdata>(refid, { collection: "pcdata", version: version });
|
||||
let grade = await DB.FindOne<grade>(refid, {
|
||||
collection: "grade",
|
||||
version: version,
|
||||
style: gtype,
|
||||
gradeId: gid,
|
||||
});
|
||||
|
||||
if (version >= 23) cflg = Number($(data).attr().cstage);
|
||||
|
||||
const isTDJ = !_.isNil($(data).element("lightning_play_data")); // lightning model //
|
||||
const hasEiseiData = (!_.isNil($(data).element("eisei_data")) || !_.isNil($(data).element("eisei_grade_data")) || !_.isNil($(data).element("kiwami_data")));
|
||||
if (isTDJ && hasEiseiData) {
|
||||
let eisei_clear_type: number;
|
||||
let eisei_grade_id: number;
|
||||
let eisei_grade_type: number;
|
||||
let eisei_stage_num: number;
|
||||
let eisei_option: number;
|
||||
|
||||
let eisei_past_achievement: number[];
|
||||
let eisei_past_selected_course: number[];
|
||||
let eisei_max_past_achievement: number[];
|
||||
let eisei_max_past_selected_course: number[];
|
||||
|
||||
switch (version) {
|
||||
case 27:
|
||||
eisei_clear_type = Number($(data).attr("eisei_data").clear_type);
|
||||
eisei_grade_id = Number($(data).attr("eisei_data").grade_id);
|
||||
eisei_grade_type = Number($(data).attr("eisei_data").grade_type);
|
||||
eisei_stage_num = Number($(data).attr("eisei_data").stage_num);
|
||||
|
||||
eisei_past_achievement = $(data).element("eisei_data").numbers("past_achievement");
|
||||
eisei_max_past_achievement = $(data).element("eisei_data").numbers("max_past_achievement");
|
||||
break;
|
||||
case 30:
|
||||
eisei_clear_type = Number($(data).element("eisei_data").attr().clear_type);
|
||||
eisei_grade_id = Number($(data).element("eisei_data").attr().grade_id);
|
||||
eisei_grade_type = Number($(data).element("eisei_data").attr().grade_type);
|
||||
eisei_stage_num = Number($(data).element("eisei_data").attr().stage_num);
|
||||
eisei_option = Number($(data).element("eisei_data").attr().option);
|
||||
|
||||
eisei_past_achievement = $(data).element("eisei_data").numbers("past_achievement");
|
||||
eisei_past_selected_course = $(data).element("eisei_data").numbers("past_selected_course");
|
||||
eisei_max_past_achievement = $(data).element("eisei_data").numbers("max_past_achievement");
|
||||
eisei_max_past_selected_course = $(data).element("eisei_data").numbers("max_past_selected_course");
|
||||
break;
|
||||
case 31:
|
||||
case 32:
|
||||
eisei_clear_type = Number($(data).attr("kiwami_data").clear_type);
|
||||
eisei_grade_id = Number($(data).attr("kiwami_data").grade_id);
|
||||
eisei_grade_type = Number($(data).attr("kiwami_data").grade_type);
|
||||
eisei_stage_num = Number($(data).attr("kiwami_data").stage_num);
|
||||
eisei_option = Number($(data).attr("kiwami_data").option);
|
||||
|
||||
eisei_past_achievement = $(data).element("kiwami_data").numbers("past_achievement");
|
||||
eisei_past_selected_course = $(data).element("kiwami_data").numbers("past_selected_course");
|
||||
eisei_max_past_achievement = $(data).element("kiwami_data").numbers("max_past_achievement");
|
||||
eisei_max_past_selected_course = $(data).element("kiwami_data").numbers("max_past_selected_course");
|
||||
break;
|
||||
|
||||
default:
|
||||
eisei_clear_type = Number($(data).attr("eisei_grade_data").clear_type);
|
||||
eisei_grade_id = Number($(data).attr("eisei_grade_data").grade_id);
|
||||
eisei_grade_type = Number($(data).attr("eisei_grade_data").grade_type);
|
||||
eisei_stage_num = Number($(data).attr("eisei_grade_data").stage_num);
|
||||
|
||||
eisei_past_achievement = $(data).element("eisei_grade_data").numbers("past_achievement");
|
||||
eisei_past_selected_course = $(data).element("eisei_grade_data").numbers("past_selected_course");
|
||||
eisei_max_past_achievement = $(data).element("eisei_grade_data").numbers("max_past_achievement");
|
||||
eisei_max_past_selected_course = $(data).element("eisei_grade_data").numbers("max_past_selected_course");
|
||||
break;
|
||||
}
|
||||
|
||||
await DB.Upsert<eisei_grade>(
|
||||
refid,
|
||||
{
|
||||
collection: "eisei_grade",
|
||||
version: version,
|
||||
grade_type: eisei_grade_type,
|
||||
grade_id: eisei_grade_id,
|
||||
},
|
||||
{
|
||||
$set: {
|
||||
clear_type: eisei_clear_type,
|
||||
stage_num: eisei_stage_num,
|
||||
option: eisei_option,
|
||||
|
||||
past_achievement: eisei_past_achievement,
|
||||
past_selected_course: eisei_past_selected_course,
|
||||
max_past_achievement: eisei_max_past_achievement,
|
||||
max_past_selected_course: eisei_max_past_selected_course,
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
return send.object(
|
||||
K.ATTR({
|
||||
pnum: "1", // This isn't visible to user and seems leftover //
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
let updatePcdata = false;
|
||||
let updateGrade = false;
|
||||
if (_.isNil(pcdata)) return send.deny();
|
||||
if (_.isNil(grade)) {
|
||||
if (cflg == 4) {
|
||||
if (gtype == 0) pcdata.sgid = Math.max(gid, pcdata.sgid);
|
||||
else pcdata.dgid = Math.max(gid, pcdata.dgid);
|
||||
|
||||
updatePcdata = true;
|
||||
}
|
||||
|
||||
updateGrade = true;
|
||||
} else {
|
||||
if (cflg >= grade.maxStage || achi >= grade.archive) {
|
||||
cflg = Math.max(cflg, grade.maxStage);
|
||||
achi = Math.max(achi, grade.archive);
|
||||
|
||||
updateGrade = true;
|
||||
}
|
||||
|
||||
if (cflg == 4) {
|
||||
if (gtype == 0) pcdata.sgid = Math.max(gid, pcdata.sgid);
|
||||
else pcdata.dgid = Math.max(gid, pcdata.dgid);
|
||||
|
||||
updatePcdata = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (updatePcdata) {
|
||||
await DB.Upsert<pcdata>(
|
||||
refid,
|
||||
{
|
||||
collection: "pcdata",
|
||||
version: version,
|
||||
},
|
||||
{
|
||||
$set: pcdata
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
if (updateGrade) {
|
||||
await DB.Upsert<grade>(
|
||||
refid,
|
||||
{
|
||||
collection: "grade",
|
||||
version: version,
|
||||
style: gtype,
|
||||
gradeId: gid,
|
||||
},
|
||||
{
|
||||
$set: {
|
||||
maxStage: cflg,
|
||||
archive: achi,
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
if (!_.isNil($(data).element("badge"))) {
|
||||
await DB.Upsert<badge>(
|
||||
refid,
|
||||
{
|
||||
collection: "badge",
|
||||
version: version,
|
||||
category_name: "grade",
|
||||
flg_id: Number($(data).attr("badge").badge_flg_id),
|
||||
},
|
||||
{
|
||||
$set: {
|
||||
flg: Number($(data).attr("badge").badge_flg),
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
let gradeUser = await DB.Find<grade>(null, {
|
||||
collection: "grade",
|
||||
version: version,
|
||||
style: gtype,
|
||||
gradeId: gid,
|
||||
maxStage: 4,
|
||||
});
|
||||
|
||||
return send.object(
|
||||
K.ATTR({
|
||||
pnum: String(gradeUser.length),
|
||||
})
|
||||
);
|
||||
};
|
||||
1033
iidx@asphyxia/handlers/music.ts
Normal file
1033
iidx@asphyxia/handlers/music.ts
Normal file
File diff suppressed because it is too large
Load Diff
5350
iidx@asphyxia/handlers/pc.ts
Normal file
5350
iidx@asphyxia/handlers/pc.ts
Normal file
File diff suppressed because it is too large
Load Diff
173
iidx@asphyxia/handlers/ranking.ts
Normal file
173
iidx@asphyxia/handlers/ranking.ts
Normal file
|
|
@ -0,0 +1,173 @@
|
|||
import { expert, ranking } from "../models/ranking";
|
||||
import { profile } from "../models/profile";
|
||||
import { GetVersion, IDtoRef } from "../util";
|
||||
|
||||
export const rankingentry: EPR = async (info, data, send) => {
|
||||
// pside //
|
||||
const version = GetVersion(info);
|
||||
const refid = await IDtoRef(Number($(data).attr().iidxid));
|
||||
|
||||
const coid = Number($(data).attr().coid);
|
||||
const clid = Number($(data).attr().clid);
|
||||
|
||||
const opname = $(data).attr().opname;
|
||||
const oppid = Number($(data).attr().oppid);
|
||||
const pgnum = Number($(data).attr().pgnum);
|
||||
const gnum = Number($(data).attr().gnum);
|
||||
const opt = Number($(data).attr().opt);
|
||||
const opt2 = Number($(data).attr().opt2);
|
||||
const clr = Number($(data).attr().clr);
|
||||
|
||||
const exscore = (pgnum * 2 + gnum);
|
||||
const cstage = Number($(data).attr().cstage);
|
||||
|
||||
const expert_data = await DB.FindOne<expert>(refid, {
|
||||
collection: "expert",
|
||||
version: version,
|
||||
coid: coid,
|
||||
});
|
||||
|
||||
let pgArray = Array<number>(6).fill(0); // PGREAT //
|
||||
let gArray = Array<number>(6).fill(0); // GREAT //
|
||||
let cArray = Array<number>(6).fill(0); // CLEAR FLAGS //
|
||||
let optArray = Array<number>(6).fill(0); // USED OPTION (SP/DP) //
|
||||
let opt2Array = Array<number>(6).fill(0); // USED OPTION (DP) //
|
||||
let esArray = Array<number>(6).fill(0); // EXSCORE //
|
||||
if (_.isNil(expert_data)) {
|
||||
cArray[clid] = clr;
|
||||
pgArray[clid] = pgnum;
|
||||
gArray[clid] = gnum;
|
||||
optArray[clid] = opt;
|
||||
opt2Array[clid] = opt2;
|
||||
esArray[clid] = exscore;
|
||||
}
|
||||
else {
|
||||
cArray = expert_data.cArray;
|
||||
pgArray = expert_data.pgArray;
|
||||
gArray = expert_data.gArray;
|
||||
optArray = expert_data.optArray;
|
||||
opt2Array = expert_data.opt2Array;
|
||||
esArray = expert_data.esArray;
|
||||
|
||||
const pExscore = esArray[clid];
|
||||
if (exscore > pExscore) {
|
||||
pgArray[clid] = pgnum;
|
||||
gArray[clid] = gnum;
|
||||
optArray[clid] = opt;
|
||||
opt2Array[clid] = opt2;
|
||||
esArray[clid] = exscore;
|
||||
}
|
||||
|
||||
cArray[clid] = Math.max(cArray[clid], clr);
|
||||
}
|
||||
|
||||
await DB.Upsert<expert>(
|
||||
refid,
|
||||
{
|
||||
collection: "expert",
|
||||
version: version,
|
||||
coid: coid,
|
||||
},
|
||||
{
|
||||
$set: {
|
||||
cArray,
|
||||
pgArray,
|
||||
gArray,
|
||||
optArray,
|
||||
opt2Array,
|
||||
esArray,
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
const profile = await DB.FindOne<profile>(refid, {
|
||||
collection: "profile",
|
||||
});
|
||||
const name = profile.name;
|
||||
await DB.Upsert<ranking>(
|
||||
{
|
||||
collection: "ranking",
|
||||
version: version,
|
||||
coid: coid,
|
||||
clid: clid,
|
||||
},
|
||||
{
|
||||
$set: {
|
||||
pgnum: pgnum,
|
||||
gnum: gnum,
|
||||
name: name,
|
||||
opname: opname,
|
||||
pid: oppid,
|
||||
udate: 0,
|
||||
|
||||
exscore: exscore,
|
||||
maxStage: cstage,
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
let expertUser = await DB.Find<ranking>({
|
||||
collection: "ranking",
|
||||
version: version,
|
||||
coid: coid,
|
||||
clid: clid,
|
||||
});
|
||||
expertUser.sort((a: ranking, b: ranking) => b.exscore - a.exscore);
|
||||
let rankPos = expertUser.findIndex((a: ranking) => a.name == name);
|
||||
|
||||
return send.object(K.ATTR({
|
||||
anum: String(expertUser.length),
|
||||
jun: String(rankPos + 1),
|
||||
}));
|
||||
};
|
||||
|
||||
export const rankingoentry: EPR = async (info, data, send) => {
|
||||
const version = GetVersion(info);
|
||||
const refid = await IDtoRef(Number($(data).attr().iidxid));
|
||||
|
||||
const coid = Number($(data).attr().coid);
|
||||
const clid = Number($(data).attr().clid);
|
||||
|
||||
const pgnum = Number($(data).attr().pgnum);
|
||||
const gnum = Number($(data).attr().gnum);
|
||||
const opt = Number($(data).attr().opt);
|
||||
const opt2 = Number($(data).attr().opt2);
|
||||
const clr = Number($(data).attr().clr);
|
||||
|
||||
const exscore = (pgnum * 2 + gnum);
|
||||
|
||||
// TODO:: figure out what this does //
|
||||
|
||||
return send.success();
|
||||
};
|
||||
|
||||
export const rankinggetranker: EPR = async (info, data, send) => {
|
||||
const version = GetVersion(info);
|
||||
const ranking = await DB.Find<ranking>({
|
||||
collection: "ranking",
|
||||
version: version,
|
||||
coid: Number($(data).attr().coid),
|
||||
clid: Number($(data).attr().clid),
|
||||
});
|
||||
let result = {
|
||||
ranker: [],
|
||||
}
|
||||
|
||||
if (_.isNil(ranking)) return send.success();
|
||||
|
||||
ranking.sort((a: ranking, b: ranking) => b.exscore - a.exscore);
|
||||
ranking.forEach((res) => {
|
||||
result.ranker.push(
|
||||
K.ATTR({
|
||||
gnum: String(res.gnum),
|
||||
pgnum: String(res.pgnum),
|
||||
name: res.name,
|
||||
opname: res.opname,
|
||||
pid: String(res.pid),
|
||||
udate: String(res.udate),
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
return send.object(result);
|
||||
};
|
||||
89
iidx@asphyxia/handlers/shop.ts
Normal file
89
iidx@asphyxia/handlers/shop.ts
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
import { convention_data, shop_data } from "../models/shop";
|
||||
import { GetVersion } from "../util";
|
||||
|
||||
export const shopgetname: EPR = async (info, data, send) => {
|
||||
const shop_data = await DB.FindOne<shop_data>({
|
||||
collection: "shop_data",
|
||||
});
|
||||
|
||||
if (_.isNil(shop_data)) {
|
||||
await DB.Insert<shop_data>({
|
||||
collection: "shop_data",
|
||||
|
||||
opname: "CORE",
|
||||
pid: 53,
|
||||
cls_opt: 0,
|
||||
});
|
||||
|
||||
return send.object(
|
||||
K.ATTR({
|
||||
opname: "CORE",
|
||||
pid: "53",
|
||||
cls_opt: "0",
|
||||
hr: "0",
|
||||
mi: "0",
|
||||
}),
|
||||
{ encoding: "shift_jis" }
|
||||
);
|
||||
}
|
||||
|
||||
return send.object(
|
||||
K.ATTR({
|
||||
opname: shop_data.opname,
|
||||
pid: String(shop_data.pid),
|
||||
cls_opt: String(shop_data.cls_opt),
|
||||
hr: "0",
|
||||
mi: "0",
|
||||
}),
|
||||
{ encoding: "shift_jis" }
|
||||
);
|
||||
};
|
||||
|
||||
export const shopsavename: EPR = async (info, data, send) => {
|
||||
// removed saving code as opname attribute being sent as shift_jis but KDataReader read as utf-8 //
|
||||
return send.success();
|
||||
};
|
||||
|
||||
export const shopgetconvention: EPR = async (info, data, send) => {
|
||||
const version = GetVersion(info);
|
||||
|
||||
const convention_data = await DB.FindOne<convention_data>({
|
||||
collection: "shop_convention",
|
||||
version: version,
|
||||
});
|
||||
if (_.isNil(convention_data)) return send.deny();
|
||||
|
||||
return send.object(
|
||||
K.ATTR({
|
||||
music_0: String(convention_data.music_0),
|
||||
music_1: String(convention_data.music_1),
|
||||
music_2: String(convention_data.music_2),
|
||||
music_3: String(convention_data.music_3),
|
||||
},
|
||||
{
|
||||
valid: K.ITEM("bool", convention_data.valid),
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
export const shopsetconvention: EPR = async (info, data, send) => {
|
||||
const version = GetVersion(info);
|
||||
|
||||
await DB.Upsert<convention_data>(
|
||||
{
|
||||
collection: "shop_convention",
|
||||
version: version,
|
||||
},
|
||||
{
|
||||
$set: {
|
||||
music_0: $(data).number("music_0"),
|
||||
music_1: $(data).number("music_1"),
|
||||
music_2: $(data).number("music_2"),
|
||||
music_3: $(data).number("music_3"),
|
||||
valid: $(data).bool("valid"),
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
return send.success();
|
||||
};
|
||||
429
iidx@asphyxia/handlers/webui.ts
Normal file
429
iidx@asphyxia/handlers/webui.ts
Normal file
|
|
@ -0,0 +1,429 @@
|
|||
import { profile } from "../models/profile";
|
||||
import { rival } from "../models/rival";
|
||||
import { custom } from "../models/custom";
|
||||
import { score, old_score } from "../models/score";
|
||||
import { lightning_custom } from "../models/lightning";
|
||||
|
||||
export const updateRivalSettings = async (data) => {
|
||||
let update_array = [];
|
||||
|
||||
if (!(_.isEmpty(data.sp_rival1))) {
|
||||
let update_data = {
|
||||
play_style: 1,
|
||||
index: 0,
|
||||
rival_refid: data.sp_rival1,
|
||||
};
|
||||
|
||||
update_array.push(update_data);
|
||||
} else {
|
||||
await DB.Remove<rival>(data.refid,
|
||||
{
|
||||
collection: "rival",
|
||||
play_style: 1,
|
||||
index: 0,
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
if (!(_.isEmpty(data.sp_rival2))) {
|
||||
let update_data = {
|
||||
play_style: 1,
|
||||
index: 1,
|
||||
rival_refid: data.sp_rival2,
|
||||
};
|
||||
|
||||
update_array.push(update_data);
|
||||
} else {
|
||||
await DB.Remove<rival>(data.refid,
|
||||
{
|
||||
collection: "rival",
|
||||
play_style: 1,
|
||||
index: 1,
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
if (!(_.isEmpty(data.sp_rival3))) {
|
||||
let update_data = {
|
||||
play_style: 1,
|
||||
index: 2,
|
||||
rival_refid: data.sp_rival3,
|
||||
};
|
||||
|
||||
update_array.push(update_data);
|
||||
} else {
|
||||
await DB.Remove<rival>(data.refid,
|
||||
{
|
||||
collection: "rival",
|
||||
play_style: 1,
|
||||
index: 2,
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
if (!(_.isEmpty(data.sp_rival4))) {
|
||||
let update_data = {
|
||||
play_style: 1,
|
||||
index: 3,
|
||||
rival_refid: data.sp_rival4,
|
||||
};
|
||||
|
||||
update_array.push(update_data);
|
||||
} else {
|
||||
await DB.Remove<rival>(data.refid,
|
||||
{
|
||||
collection: "rival",
|
||||
play_style: 1,
|
||||
index: 3,
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
if (!(_.isEmpty(data.sp_rival5))) {
|
||||
let update_data = {
|
||||
play_style: 1,
|
||||
index: 4,
|
||||
rival_refid: data.sp_rival5,
|
||||
};
|
||||
|
||||
update_array.push(update_data);
|
||||
} else {
|
||||
await DB.Remove<rival>(data.refid,
|
||||
{
|
||||
collection: "rival",
|
||||
play_style: 1,
|
||||
index: 4,
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
if (!(_.isEmpty(data.dp_rival1))) {
|
||||
let update_data = {
|
||||
play_style: 2,
|
||||
index: 0,
|
||||
rival_refid: data.dp_rival1,
|
||||
};
|
||||
|
||||
update_array.push(update_data);
|
||||
} else {
|
||||
await DB.Remove<rival>(data.refid,
|
||||
{
|
||||
collection: "rival",
|
||||
play_style: 2,
|
||||
index: 0,
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
if (!(_.isEmpty(data.dp_rival2))) {
|
||||
let update_data = {
|
||||
play_style: 2,
|
||||
index: 1,
|
||||
rival_refid: data.dp_rival2,
|
||||
};
|
||||
|
||||
update_array.push(update_data);
|
||||
} else {
|
||||
await DB.Remove<rival>(data.refid,
|
||||
{
|
||||
collection: "rival",
|
||||
play_style: 2,
|
||||
index: 1,
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
if (!(_.isEmpty(data.dp_rival3))) {
|
||||
let update_data = {
|
||||
play_style: 2,
|
||||
index: 2,
|
||||
rival_refid: data.dp_rival3,
|
||||
};
|
||||
|
||||
update_array.push(update_data);
|
||||
} else {
|
||||
await DB.Remove<rival>(data.refid,
|
||||
{
|
||||
collection: "rival",
|
||||
play_style: 2,
|
||||
index: 2,
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
if (!(_.isEmpty(data.dp_rival4))) {
|
||||
let update_data = {
|
||||
play_style: 2,
|
||||
index: 3,
|
||||
rival_refid: data.dp_rival4,
|
||||
};
|
||||
|
||||
update_array.push(update_data);
|
||||
} else {
|
||||
await DB.Remove<rival>(data.refid,
|
||||
{
|
||||
collection: "rival",
|
||||
play_style: 2,
|
||||
index: 3,
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
if (!(_.isEmpty(data.dp_rival5))) {
|
||||
let update_data = {
|
||||
play_style: 2,
|
||||
index: 4,
|
||||
rival_refid: data.dp_rival5,
|
||||
};
|
||||
|
||||
update_array.push(update_data);
|
||||
} else {
|
||||
await DB.Remove<rival>(data.refid,
|
||||
{
|
||||
collection: "rival",
|
||||
play_style: 2,
|
||||
index: 4,
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
for (let i = 0; i < update_array.length; i++) {
|
||||
await DB.Upsert<rival>(data.refid, {
|
||||
collection: "rival",
|
||||
play_style: update_array[i].play_style,
|
||||
index: update_array[i].index,
|
||||
}, {
|
||||
$set: {
|
||||
rival_refid: update_array[i].rival_refid,
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
};
|
||||
|
||||
export const updateCustomSettings = async (data) => {
|
||||
const profile = await DB.FindOne<profile>(data.refid, {
|
||||
collection: "profile",
|
||||
});
|
||||
|
||||
let customize = {
|
||||
frame: Number(data.frame),
|
||||
turntable: Number(data.turntable),
|
||||
note_burst: Number(data.note_burst),
|
||||
menu_music: Number(data.menu_music),
|
||||
lane_cover: Number(data.lane_cover),
|
||||
category_vox: Number(data.category_vox),
|
||||
note_skin: Number(data.note_skin),
|
||||
full_combo_splash: Number(data.full_combo_splash),
|
||||
disable_musicpreview: StoB(data.disable_musicpreview),
|
||||
|
||||
note_beam: Number(data.note_beam),
|
||||
judge_font: Number(data.judge_font),
|
||||
pacemaker_cover: Number(data.pacemaker_cover),
|
||||
vefx_lock: StoB(data.vefx_lock),
|
||||
effect: Number(data.effect),
|
||||
bomb_size: Number(data.bomb_size),
|
||||
disable_hcn_color: StoB(data.disable_hcn_color),
|
||||
first_note_preview: Number(data.first_note_preview),
|
||||
|
||||
rank_folder: StoB(data.rank_folder),
|
||||
clear_folder: StoB(data.clear_folder),
|
||||
diff_folder: StoB(data.diff_folder),
|
||||
alpha_folder: StoB(data.alpha_folder),
|
||||
rival_folder: StoB(data.rival_folder),
|
||||
rival_battle_folder: StoB(data.rival_battle_folder),
|
||||
rival_info: StoB(data.rival_info),
|
||||
hide_playcount: StoB(data.hide_playcount),
|
||||
disable_graph_cutin: StoB(data.disable_graph_cutin),
|
||||
classic_hispeed: StoB(data.classic_hispeed),
|
||||
rival_played_folder: StoB(data.rival_played_folder),
|
||||
hide_iidxid: StoB(data.hide_iidxid),
|
||||
disable_beginner_option: StoB(data.disable_beginner_option),
|
||||
|
||||
qpro_head: Number(data.qpro_head),
|
||||
qpro_hair: Number(data.qpro_hair),
|
||||
qpro_face: Number(data.qpro_face),
|
||||
qpro_hand: Number(data.qpro_hand),
|
||||
qpro_body: Number(data.qpro_body),
|
||||
qpro_back: Number(data.qpro_back),
|
||||
}
|
||||
|
||||
await DB.Upsert<custom>(data.refid, {
|
||||
collection: "custom",
|
||||
version: Number(data.version)
|
||||
},
|
||||
{
|
||||
$set: customize
|
||||
});
|
||||
|
||||
if (!_.isEmpty(data.name) && data.name != profile.name) {
|
||||
// TODO:: check name is in valid format //
|
||||
await DB.Upsert<profile>(data.refid, {
|
||||
collection: "profile",
|
||||
}, {
|
||||
$set: {
|
||||
name: data.name
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (data.version > 27) {
|
||||
await DB.Upsert<lightning_custom>(data.refid, {
|
||||
collection: "lightning_custom",
|
||||
version: Number(data.version)
|
||||
},
|
||||
{
|
||||
$set: {
|
||||
premium_skin: Number(data.lm_skin),
|
||||
premium_bg: Number(data.lm_bg),
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
export const importScoreData = async (data, send: WebUISend) => {
|
||||
if (_.isEmpty(data.data)) {
|
||||
console.error("[Score Importer] Supplied data is empty");
|
||||
return send.error(400, "Empty data");
|
||||
}
|
||||
|
||||
let content = null;
|
||||
let version = 0;
|
||||
let count = 0;
|
||||
try {
|
||||
content = JSON.parse(data.data);
|
||||
version = content.version;
|
||||
count = content.count;
|
||||
}
|
||||
catch {
|
||||
console.error("[Score Importer] Invaild data has been supplied");
|
||||
return send.error(400, "Invalid data");
|
||||
}
|
||||
|
||||
switch (version) {
|
||||
case 1:
|
||||
let sd_ver1: old_score[] = content.data;
|
||||
for (let a = 0; a < count; a++) {
|
||||
let result = {
|
||||
pgArray: Array<number>(10).fill(0),
|
||||
gArray: Array<number>(10).fill(0),
|
||||
mArray: Array<number>(10).fill(-1),
|
||||
cArray: Array<number>(10).fill(0),
|
||||
rArray: Array<number>(10).fill(-1),
|
||||
esArray: Array<number>(10).fill(0),
|
||||
|
||||
optArray: Array<number>(10).fill(0),
|
||||
opt2Array: Array<number>(10).fill(0),
|
||||
}
|
||||
|
||||
if (!_.isNil(sd_ver1[a].spmArray)) {
|
||||
for (let b = 0; b < 5; b++) {
|
||||
result.cArray[b] = sd_ver1[a].spmArray[2 + b];
|
||||
result.esArray[b] = sd_ver1[a].spmArray[7 + b];
|
||||
if (sd_ver1[a].spmArray[12 + b] != -1) result.mArray[b] = sd_ver1[a].spmArray[12 + b];
|
||||
}
|
||||
}
|
||||
|
||||
if (!_.isNil(sd_ver1[a].dpmArray)) {
|
||||
for (let b = 5; b < 10; b++) {
|
||||
result.cArray[b] = sd_ver1[a].dpmArray[2 + (b - 5)];
|
||||
result.esArray[b] = sd_ver1[a].dpmArray[7 + (b - 5)];
|
||||
if (sd_ver1[a].dpmArray[12 + (b - 5)] != -1) result.mArray[b] = sd_ver1[a].dpmArray[12 + (b - 5)];
|
||||
}
|
||||
}
|
||||
|
||||
if (!_.isNil(sd_ver1[a].optArray)) {
|
||||
result.optArray = sd_ver1[a].optArray;
|
||||
}
|
||||
|
||||
if (!_.isNil(sd_ver1[a].opt2Array)) {
|
||||
result.opt2Array = sd_ver1[a].opt2Array;
|
||||
}
|
||||
|
||||
for (let b = 0; b < 10; b++) {
|
||||
if (_.isNil(sd_ver1[a][b])) continue;
|
||||
result[b] = sd_ver1[a][b];
|
||||
|
||||
if (!_.isNil(sd_ver1[a][b + 10])) {
|
||||
result[b + 10] = sd_ver1[a][b + 10];
|
||||
}
|
||||
}
|
||||
|
||||
await DB.Upsert<score>(data.refid,
|
||||
{
|
||||
collection: "score",
|
||||
mid: sd_ver1[a].music_id
|
||||
},
|
||||
{
|
||||
$set: {
|
||||
...result
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
let sd_ver2: score[] = content.data;
|
||||
for (let a = 0; a < count; a++) {
|
||||
let result = {
|
||||
pgArray: sd_ver2[a].pgArray,
|
||||
gArray: sd_ver2[a].gArray,
|
||||
mArray: sd_ver2[a].mArray,
|
||||
cArray: sd_ver2[a].cArray,
|
||||
rArray: sd_ver2[a].rArray,
|
||||
esArray: sd_ver2[a].esArray,
|
||||
|
||||
optArray: sd_ver2[a].optArray,
|
||||
opt2Array: sd_ver2[a].opt2Array,
|
||||
};
|
||||
|
||||
for (let b = 0; b < 10; b++) {
|
||||
if (_.isNil(sd_ver2[a][b])) continue;
|
||||
result[b] = sd_ver2[a][b];
|
||||
|
||||
if (!_.isNil(sd_ver2[a][b + 10])) {
|
||||
result[b + 10] = sd_ver2[a][b + 10];
|
||||
}
|
||||
}
|
||||
|
||||
await DB.Upsert<score>(data.refid,
|
||||
{
|
||||
collection: "score",
|
||||
mid: sd_ver2[a].mid
|
||||
},
|
||||
{
|
||||
$set: {
|
||||
...result,
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
console.error("[Score Importer] Unregistered score data version");
|
||||
return send.error(400, "Invalid data version");
|
||||
}
|
||||
}
|
||||
|
||||
export const exportScoreData = async (data, send: WebUISend) => {
|
||||
const score = await DB.Find<score>(data.refid, {
|
||||
collection: "score"
|
||||
});
|
||||
|
||||
if (score == null) return send.error(400, "No data");
|
||||
|
||||
let result = {
|
||||
version: 2,
|
||||
count: score.length,
|
||||
data: {
|
||||
...score,
|
||||
}
|
||||
}
|
||||
|
||||
send.json(result);
|
||||
}
|
||||
|
||||
function StoB(value: string) {
|
||||
return value == "on" ? true : false;
|
||||
};
|
||||
598
iidx@asphyxia/index.ts
Normal file
598
iidx@asphyxia/index.ts
Normal file
|
|
@ -0,0 +1,598 @@
|
|||
import { pccommon, pcreg, pcget, pcgetname, pctakeover, pcvisit, pcsave, pcoldget, pcgetlanegacha, pcdrawlanegacha, pcshopregister } from "./handlers/pc";
|
||||
import { shopgetname, shopsavename, shopgetconvention, shopsetconvention } from "./handlers/shop";
|
||||
import { musicreg, musicgetrank, musicappoint, musicarenacpu, musiccrate, musicbreg, musicgetralive } from "./handlers/music";
|
||||
import { graderaised } from "./handlers/grade";
|
||||
import { gssysteminfo } from "./handlers/gamesystem";
|
||||
import { updateRivalSettings, updateCustomSettings, importScoreData, exportScoreData } from "./handlers/webui";
|
||||
import { GetVersion } from "./util";
|
||||
import { rankingentry, rankinggetranker, rankingoentry } from "./handlers/ranking";
|
||||
|
||||
export function register() {
|
||||
if (CORE_VERSION_MAJOR <= 1 && CORE_VERSION_MINOR < 31) {
|
||||
console.error("The current version of Asphyxia Core is not supported. Requires version '1.31' or later.");
|
||||
return;
|
||||
}
|
||||
|
||||
R.Contributor("duel0213");
|
||||
|
||||
R.GameCode("GLD");
|
||||
R.GameCode("HDD");
|
||||
R.GameCode("I00");
|
||||
R.GameCode("JDJ");
|
||||
R.GameCode("JDZ");
|
||||
R.GameCode("KDZ");
|
||||
R.GameCode("LDJ");
|
||||
|
||||
// common //
|
||||
R.Config("BeatPhase", {
|
||||
name: "Beat #",
|
||||
desc: "1 / 2 / 3 / FREE", // This can be event phase on old versions //
|
||||
type: "integer",
|
||||
default: 3, // BEAT FREE //
|
||||
});
|
||||
// ~ Resort Anthem (common) / /
|
||||
R.Config("cmd_gmbl", {
|
||||
name: "G.JUDGE",
|
||||
desc: "Enable G.JUDGE Command (~ Resort Anthem)",
|
||||
type: "boolean",
|
||||
default: true,
|
||||
});
|
||||
R.Config("cmd_gmbla", {
|
||||
name: "G.JUDGE-A",
|
||||
desc: "Enable G.JUDGE-A Command (~ Resort Anthem)",
|
||||
type: "boolean",
|
||||
default: true,
|
||||
});
|
||||
R.Config("cmd_regl", {
|
||||
name: "REGUL-SPEED",
|
||||
desc: "Enable REGUL-SPEED Command (~ Resort Anthem)",
|
||||
type: "boolean",
|
||||
default: true,
|
||||
});
|
||||
R.Config("cmd_rndp", {
|
||||
name: "RANDOM+",
|
||||
desc: "Enable RANDOM+ Command (~ Resort Anthem)",
|
||||
type: "boolean",
|
||||
default: true,
|
||||
});
|
||||
R.Config("cmd_hrnd", {
|
||||
name: "H-RANDOM",
|
||||
desc: "Enable H-RANDOM Command (~ Resort Anthem)",
|
||||
type: "boolean",
|
||||
default: true,
|
||||
});
|
||||
R.Config("cmd_alls", {
|
||||
name: "ALL-SCRATCH",
|
||||
desc: "Enable ALL-SCRATCH Command (~ Resort Anthem)",
|
||||
type: "boolean",
|
||||
default: true,
|
||||
});
|
||||
// SPADA ~ (common) //
|
||||
R.Config("NewSongAnother12", {
|
||||
name: "New Song Another",
|
||||
desc: "Enables ANOTHER difficulty of current version's new songs that has Level 12",
|
||||
type: "boolean",
|
||||
default: true,
|
||||
});
|
||||
// PENDUAL ~ (common) //
|
||||
R.Config("ExpertPhase", {
|
||||
name: "Expert Phase",
|
||||
type: "integer",
|
||||
default: 2,
|
||||
});
|
||||
R.Config("ExpertRandomPhase", {
|
||||
name: "Expert Random Phase",
|
||||
type: "integer",
|
||||
default: 2,
|
||||
});
|
||||
// HEROIC VERSE ~ (common) //
|
||||
R.Config("ArenaPhase", {
|
||||
name: "ARENA Phase",
|
||||
type: "integer",
|
||||
default: 2, // ADVERTISE //
|
||||
});
|
||||
// BISTROVER ~ (common) //
|
||||
R.Config("MovieUpload", {
|
||||
name: "Movie Upload URL",
|
||||
type: "string",
|
||||
desc: "API address for play video uploading feature (JSON)",
|
||||
default: "http://localhost/"
|
||||
});
|
||||
R.Config("Eisei", {
|
||||
name: "Eisei Grade Courses",
|
||||
desc: "Enable EISEI/KIWAMI Grade Courses",
|
||||
type: "boolean",
|
||||
default: true,
|
||||
});
|
||||
// CastHour ~ RESIDENT (common) //
|
||||
R.Config("Grade", {
|
||||
name: "Grade Open Phase",
|
||||
desc: "RED / KAIDEN",
|
||||
type: "integer",
|
||||
default: 2,
|
||||
})
|
||||
|
||||
// SIRIUS //
|
||||
R.Config("sr_league", {
|
||||
name: "League Phase (SR)",
|
||||
type: "integer",
|
||||
default: 0,
|
||||
});
|
||||
|
||||
// Resort Anthem //
|
||||
R.Config("ra_league", {
|
||||
name: "League Phase (RA)",
|
||||
type: "integer",
|
||||
default: 0,
|
||||
});
|
||||
R.Config("ra_story", {
|
||||
name: "Story Phase (RA)",
|
||||
type: "integer",
|
||||
default: 0,
|
||||
});
|
||||
R.Config("ra_event", {
|
||||
name: "Tour Phase (RA)",
|
||||
type: "integer",
|
||||
default: 3,
|
||||
});
|
||||
R.Config("ra_lincle", {
|
||||
name: "Lincle LINK Phase (RA)",
|
||||
type: "integer",
|
||||
default: 1,
|
||||
});
|
||||
|
||||
// Lincle //
|
||||
R.Config("lc_lincle", {
|
||||
name: "Lincle LINK Phase (LC)",
|
||||
type: "integer",
|
||||
default: 2,
|
||||
});
|
||||
R.Config("lc_boss", {
|
||||
name: "Lincle Kingdom Phase",
|
||||
type: "integer",
|
||||
default: 2,
|
||||
});
|
||||
|
||||
// tricoro //
|
||||
R.Config("tr_limit", {
|
||||
name: "Limit Burst Phase (TR)",
|
||||
type: "integer",
|
||||
default: 24, // TODO:: verify //
|
||||
});
|
||||
R.Config("tr_boss", {
|
||||
name: "Event Phase (TR)",
|
||||
desc: "RED / BLUE / YELLOW",
|
||||
type: "integer",
|
||||
default: 3,
|
||||
});
|
||||
R.Config("tr_red", {
|
||||
name: "RED Phase",
|
||||
desc: "LEGEND CROSS Phase",
|
||||
type: "integer",
|
||||
default: 3,
|
||||
});
|
||||
R.Config("tr_yellow", {
|
||||
name: "YELLOW Phase",
|
||||
desc: "ぼくらの宇宙戦争 Phase",
|
||||
type: "integer",
|
||||
default: 3,
|
||||
});
|
||||
R.Config("tr_medal", {
|
||||
name: "Medal Phase (TR)",
|
||||
type: "integer",
|
||||
default: 3,
|
||||
});
|
||||
R.Config("tr_cafe", {
|
||||
name: "Café de Tran",
|
||||
desc: "Enable Café de Tran Event (tricoro)",
|
||||
type: "boolean",
|
||||
default: true,
|
||||
});
|
||||
R.Config("tr_tripark", {
|
||||
name: "Everyone's SPACEWAR!!",
|
||||
desc: "Enable クプロ・ミミニャミ・パステルくんのみんなで宇宙戦争!! Event (tricoro)",
|
||||
type: "boolean",
|
||||
default: true,
|
||||
});
|
||||
|
||||
// SPADA //
|
||||
R.Config("sp_limit", {
|
||||
name: "Limit Burst Phase (SP)",
|
||||
type: "integer",
|
||||
default: 24,
|
||||
});
|
||||
R.Config("sp_boss", {
|
||||
name: "Event Phase (SP)",
|
||||
desc: "Spada†leggendaria Phase",
|
||||
type: "integer",
|
||||
default: 3,
|
||||
});
|
||||
R.Config("sp_boss1", {
|
||||
name: "Qprogue Phase (SP)",
|
||||
type: "integer",
|
||||
default: 4,
|
||||
});
|
||||
R.Config("sp_cafe", {
|
||||
name: "Café de Tran",
|
||||
desc: "Enable Café de Tran Event (SPADA)",
|
||||
type: "boolean",
|
||||
default: true,
|
||||
});
|
||||
R.Config("sp_tripark", {
|
||||
name: "Everyone's SPACEWAR!!",
|
||||
desc: "Enable クプロ・ミミニャミ・パステルくんのみんなで宇宙戦争!! Event (SPADA)",
|
||||
type: "boolean",
|
||||
default: true,
|
||||
});
|
||||
R.Config("sp_triparkskip", {
|
||||
name: "Everyone's SPACEWAR!! Skip",
|
||||
desc: "Skips クプロ・ミミニャミ・パステルくんのみんなで宇宙戦争!! Event Scenes",
|
||||
type: "integer",
|
||||
default: 2,
|
||||
});
|
||||
R.Config("sp_superstar", {
|
||||
name: "SUPER STAR -MITSURU-",
|
||||
desc: "SUPER STAR 満 -MITSURU- 完全復活祭 Phase",
|
||||
type: "integer",
|
||||
default: 2,
|
||||
});
|
||||
|
||||
// PENDUAL //
|
||||
R.Config("pd_preplay", {
|
||||
name: "SUPER FUTURE 2323 Phase",
|
||||
type: "integer",
|
||||
default: 2,
|
||||
});
|
||||
R.Config("pd_tohoremix", {
|
||||
name: "BEMANI X TOHO",
|
||||
desc: "BEMANI×TOHO REITAISAI 2015 project Phase",
|
||||
type: "integer",
|
||||
default: 2,
|
||||
});
|
||||
R.Config("pd_limit", {
|
||||
name: "Chrono Chaser Phase",
|
||||
type: "integer",
|
||||
default: 9,
|
||||
});
|
||||
R.Config("pd_boss", {
|
||||
name: "Event Phase (PD)",
|
||||
desc: "Chrono Seeker / Qpronicle Chord / PENDUAL TALISMAN",
|
||||
type: "integer",
|
||||
default: 3,
|
||||
});
|
||||
R.Config("pd_chronodiver", {
|
||||
name: "Chrono Seeker",
|
||||
type: "integer",
|
||||
default: 3,
|
||||
});
|
||||
R.Config("pd_qproniclechord", {
|
||||
name: "Qpronicle Chord",
|
||||
type: "integer",
|
||||
default: 2,
|
||||
});
|
||||
R.Config("pd_cccollabo", {
|
||||
name: "Coca-Cola×BEMANI",
|
||||
desc: "Coca-Cola×BEMANI 店舗限定ロケテスト Phase",
|
||||
type: "integer",
|
||||
default: 3,
|
||||
});
|
||||
R.Config("pd_timephase", {
|
||||
name: "Time Phase",
|
||||
type: "integer",
|
||||
desc: "Default / Present / Future",
|
||||
default: 0,
|
||||
});
|
||||
|
||||
// copula //
|
||||
R.Config("cp_boss", {
|
||||
name: "Event Phase (CP)",
|
||||
desc: "開通!とことこライン / Mystery Line",
|
||||
type: "integer",
|
||||
default: 2,
|
||||
});
|
||||
R.Config("cp_event1", {
|
||||
name: "開通!とことこライン",
|
||||
desc: "開通!とことこライン Phase",
|
||||
type: "integer",
|
||||
default: 1,
|
||||
});
|
||||
R.Config("cp_event2", {
|
||||
name: "Mystery Line",
|
||||
desc: "Mystery Line Phase",
|
||||
type: "integer",
|
||||
default: 2,
|
||||
});
|
||||
R.Config("cp_extraboss",
|
||||
{
|
||||
name: "Extra Boss Phase (CP)",
|
||||
desc: "Extra Boss Phase",
|
||||
type: "integer",
|
||||
default: 30,
|
||||
});
|
||||
R.Config("cp_bemanisummer", {
|
||||
name: "BEMANI Summer 2016",
|
||||
desc: "NEW Generation 夏の流星フェスタ2016 Phase",
|
||||
type: "integer",
|
||||
default: 2,
|
||||
});
|
||||
|
||||
// SINOBUZ //
|
||||
R.Config("sb_boss", {
|
||||
name: "Event Phase (SB)",
|
||||
desc: "攻城シノバズ伝 / 忍々七鍵伝",
|
||||
type: "integer",
|
||||
default: 2,
|
||||
});
|
||||
R.Config("sb_event1", {
|
||||
name: "攻城シノバズ伝",
|
||||
desc: "攻城シノバズ伝 Phase",
|
||||
type: "integer",
|
||||
default: 2,
|
||||
});
|
||||
R.Config("sb_event2", {
|
||||
name: "忍々七鍵伝",
|
||||
desc: "忍々七鍵伝 Phase",
|
||||
type: "integer",
|
||||
default: 1,
|
||||
});
|
||||
R.Config("sb_extraboss",
|
||||
{
|
||||
name: "BUZRA ARTS",
|
||||
desc: "BUZRA ARTS Phase",
|
||||
type: "integer",
|
||||
default: 35,
|
||||
});
|
||||
|
||||
// CANNON BALLERS //
|
||||
R.Config("cb_boss", {
|
||||
name: "Event Phase (SB)",
|
||||
desc: "激走!キャノンレーサー",
|
||||
type: "integer",
|
||||
default: 1,
|
||||
});
|
||||
R.Config("cb_event1", {
|
||||
name: "激走!キャノンレーサー",
|
||||
desc: "激走!キャノンレーサー Phase",
|
||||
type: "integer",
|
||||
default: 3,
|
||||
});
|
||||
R.Config("cb_extraboss",
|
||||
{
|
||||
name: "IIDX AIR RACE",
|
||||
desc: "IIDX AIR RACE Phase",
|
||||
type: "integer",
|
||||
default: 35,
|
||||
});
|
||||
|
||||
// Rootage //
|
||||
R.Config("rt_boss", {
|
||||
name: "Event Phase (RT)",
|
||||
desc: "蜃気楼の図書館 / DELABITY LABORATORY",
|
||||
type: "integer",
|
||||
default: 2,
|
||||
});
|
||||
R.Config("rt_event1", {
|
||||
name: "蜃気楼の図書館",
|
||||
desc: "蜃気楼の図書館 Phase",
|
||||
type: "integer",
|
||||
default: 3,
|
||||
});
|
||||
R.Config("rt_event2", {
|
||||
name: "DELABITY LABORATORY",
|
||||
desc: "DELABITY LABORATORY Phase",
|
||||
type: "integer",
|
||||
default: 2,
|
||||
});
|
||||
R.Config("rt_extraboss",
|
||||
{
|
||||
name: "ARC SCORE",
|
||||
desc: "ARC SCORE Phase",
|
||||
type: "integer",
|
||||
default: 3,
|
||||
});
|
||||
|
||||
// HEROIC VERSE //
|
||||
R.Config("hv_boss", {
|
||||
name: "Event Phase (HV)",
|
||||
desc: "HEROIC WORKOUT!!",
|
||||
type: "integer",
|
||||
default: 1,
|
||||
});
|
||||
R.Config("hv_event", {
|
||||
name: "HEROIC WORKOUT!!",
|
||||
desc: "HEROIC WORKOUT!! Phase",
|
||||
type: "integer",
|
||||
default: 4,
|
||||
});
|
||||
R.Config("hv_extraboss",
|
||||
{
|
||||
name: "SHADOW REBELLION",
|
||||
desc: "SHADOW REBELLION Phase",
|
||||
type: "integer",
|
||||
default: 1,
|
||||
});
|
||||
|
||||
// BISTROVER //
|
||||
R.Config("bo_boss", {
|
||||
name: "Event Phase (BO)",
|
||||
desc: "召しませ!BISTROVER",
|
||||
type: "integer",
|
||||
default: 1,
|
||||
});
|
||||
R.Config("bo_extraboss", {
|
||||
name: "BISTRO LANDING",
|
||||
desc: "BISTRO LANDING Phase",
|
||||
type: "integer",
|
||||
default: 1,
|
||||
});
|
||||
R.Config("bo_event", {
|
||||
name: "召しませ!BISTROVER",
|
||||
desc: "召しませ!BISTROVER Phase",
|
||||
type: "integer",
|
||||
default: 1,
|
||||
});
|
||||
|
||||
// CastHour //
|
||||
R.Config("ch_event", {
|
||||
name: "CastHour Space",
|
||||
desc: "CastHour Space Phase",
|
||||
type: "integer",
|
||||
default: 5,
|
||||
});
|
||||
R.Config("ch_extraboss", {
|
||||
name: "Extra Boss Phase (CH)",
|
||||
type: "integer",
|
||||
default: 3,
|
||||
});
|
||||
|
||||
// RESIDENT //
|
||||
R.Config("rs_event", {
|
||||
name: "RESIDENT PARTY",
|
||||
desc: "RESIDENT PARTY Phase",
|
||||
type: "integer",
|
||||
default: 5,
|
||||
});
|
||||
R.Config("rs_extraboss", {
|
||||
name: "Extra Boss Phase (RS)",
|
||||
type: "integer",
|
||||
default: 3,
|
||||
});
|
||||
|
||||
// EPOLIS //
|
||||
R.Config("ep_event", {
|
||||
name: "Event Phase (EP)",
|
||||
desc: "MY POLIS DESIGNER / EPOLIS RESTORATION",
|
||||
type: "integer",
|
||||
default: 2,
|
||||
});
|
||||
R.Config("ep_event1", {
|
||||
name: "MY POLIS DESIGNER",
|
||||
desc: "MY POLIS DESIGNER Phase",
|
||||
type: "integer",
|
||||
default: 3,
|
||||
});
|
||||
R.Config("ep_event2", {
|
||||
name: "EPOLIS RESTORATION",
|
||||
desc: "EPOLIS RESTORATION Phase",
|
||||
type: "integer",
|
||||
default: 3,
|
||||
});
|
||||
R.Config("ep_extraboss", {
|
||||
name: "EPOLIS SINGULARITY",
|
||||
desc: "EPOLIS SINGULARITY Phase",
|
||||
type: "integer",
|
||||
default: 3,
|
||||
});
|
||||
|
||||
// Pinky Crush //
|
||||
R.Config("pc_event", {
|
||||
name: "Event Phase (PC)",
|
||||
desc: "ピンキージャンプアップ! / ピンキーアンダーグラウンド",
|
||||
type: "integer",
|
||||
default: 2,
|
||||
});
|
||||
R.Config("pc_event1", {
|
||||
name: "ピンキージャンプアップ!",
|
||||
desc: "ピンキージャンプアップ! Phase",
|
||||
type: "integer",
|
||||
default: 3,
|
||||
});
|
||||
R.Config("pc_event2", {
|
||||
name: "ピンキーアンダーグラウンド",
|
||||
desc: "ピンキーアンダーグラウンド Phase",
|
||||
type: "integer",
|
||||
default: 3,
|
||||
});
|
||||
R.Config("pc_extraboss", {
|
||||
name: "Extra Boss Phase (PC)",
|
||||
type: "integer",
|
||||
default: 3,
|
||||
});
|
||||
|
||||
// TODO:: Make a list of customize items //
|
||||
R.WebUIEvent("iidxGetProfile", async (data, send: WebUISend) => {
|
||||
const pcdata = await DB.FindOne(data.refid, {
|
||||
collection: "pcdata",
|
||||
version: Number(data.version),
|
||||
});
|
||||
|
||||
return send.json({
|
||||
pcdata,
|
||||
});
|
||||
});
|
||||
R.WebUIEvent("iidxGetSetting", async (data, send: WebUISend) => {
|
||||
const custom = await DB.FindOne(data.refid, {
|
||||
collection: "custom",
|
||||
version: Number(data.version),
|
||||
});
|
||||
|
||||
const lm_custom = await DB.FindOne(data.refid, {
|
||||
collection: "lightning_custom",
|
||||
version: Number(data.version),
|
||||
});
|
||||
|
||||
return send.json({
|
||||
custom,
|
||||
lm_custom,
|
||||
});
|
||||
});
|
||||
R.WebUIEvent("iidxUpdateRival", updateRivalSettings);
|
||||
R.WebUIEvent("iidxUpdateCustom", updateCustomSettings);
|
||||
R.WebUIEvent("iidxImportScoreData", importScoreData);
|
||||
R.WebUIEvent("iidxExportScoreData", exportScoreData);
|
||||
|
||||
const MultiRoute = (method: string, handler: EPR | boolean) => {
|
||||
R.Route(`${method}`, handler);
|
||||
R.Route(`IIDX21${method}`, handler);
|
||||
R.Route(`IIDX22${method}`, handler);
|
||||
R.Route(`IIDX23${method}`, handler);
|
||||
R.Route(`IIDX24${method}`, handler);
|
||||
R.Route(`IIDX25${method}`, handler);
|
||||
R.Route(`IIDX26${method}`, handler);
|
||||
R.Route(`IIDX27${method}`, handler);
|
||||
R.Route(`IIDX28${method}`, handler);
|
||||
R.Route(`IIDX29${method}`, handler);
|
||||
R.Route(`IIDX30${method}`, handler);
|
||||
R.Route(`IIDX31${method}`, handler);
|
||||
R.Route(`IIDX32${method}`, handler);
|
||||
};
|
||||
|
||||
MultiRoute("pc.common", pccommon);
|
||||
MultiRoute("pc.reg", pcreg);
|
||||
MultiRoute("pc.get", pcget);
|
||||
MultiRoute("pc.getname", pcgetname);
|
||||
MultiRoute("pc.oldget", pcoldget);
|
||||
MultiRoute("pc.takeover", pctakeover);
|
||||
MultiRoute("pc.visit", pcvisit);
|
||||
MultiRoute("pc.save", pcsave);
|
||||
MultiRoute("pc.shopregister", pcshopregister);
|
||||
MultiRoute("pc.getLaneGachaTicket", pcgetlanegacha);
|
||||
MultiRoute("pc.drawLaneGacha", pcdrawlanegacha);
|
||||
MultiRoute("pc.consumeLaneGachaTicket", true);
|
||||
|
||||
MultiRoute("shop.getname", shopgetname);
|
||||
MultiRoute("shop.savename", shopsavename);
|
||||
MultiRoute("shop.getconvention", shopgetconvention);
|
||||
MultiRoute("shop.setconvention", shopsetconvention);
|
||||
|
||||
MultiRoute("music.crate", musiccrate);
|
||||
MultiRoute("music.getrank", musicgetrank);
|
||||
MultiRoute("music.getralive", musicgetralive);
|
||||
MultiRoute("music.appoint", musicappoint);
|
||||
MultiRoute("music.reg", musicreg);
|
||||
MultiRoute("music.breg", musicbreg);
|
||||
MultiRoute("music.arenaCPU", musicarenacpu);
|
||||
|
||||
MultiRoute("grade.raised", graderaised);
|
||||
|
||||
MultiRoute("ranking.entry", rankingentry);
|
||||
MultiRoute("ranking.oentry", rankingoentry);
|
||||
MultiRoute("ranking.getranker", rankinggetranker);
|
||||
|
||||
MultiRoute("gameSystem.systemInfo", gssysteminfo);
|
||||
|
||||
R.Unhandled((req: EamuseInfo, data: any, send: EamuseSend) => {
|
||||
console.warn(`Unhandled Request : [${GetVersion(req)}], ${req.module}.${req.method}, ${JSON.stringify(data)}`);
|
||||
return send.success();
|
||||
});
|
||||
}
|
||||
50
iidx@asphyxia/models/activity.ts
Normal file
50
iidx@asphyxia/models/activity.ts
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
export interface activity {
|
||||
collection: "activity";
|
||||
version: number;
|
||||
|
||||
date: number;
|
||||
play_style: number;
|
||||
|
||||
music_num: number;
|
||||
play_time: number;
|
||||
keyboard_num: number;
|
||||
scratch_num: number;
|
||||
clear_update_num: number[];
|
||||
score_update_num: number[];
|
||||
}
|
||||
|
||||
export interface activity_mybest {
|
||||
collection: "activity_mybest";
|
||||
version: number;
|
||||
|
||||
play_style: number;
|
||||
play_side: number;
|
||||
music_id: number;
|
||||
note_id: number;
|
||||
|
||||
target_graph: number;
|
||||
target_score: number;
|
||||
pacemaker: number;
|
||||
best_clear: number;
|
||||
best_score: number;
|
||||
best_misscount: number;
|
||||
now_clear: number;
|
||||
now_score: number;
|
||||
now_misscount: number;
|
||||
now_pgreat: number;
|
||||
now_great: number;
|
||||
now_good: number;
|
||||
now_bad: number;
|
||||
now_poor: number;
|
||||
now_combo: number;
|
||||
now_fast: number;
|
||||
now_slow: number;
|
||||
option: number;
|
||||
option_2: number;
|
||||
ghost_gauge_data: string;
|
||||
gauge_type: number;
|
||||
result_type: number;
|
||||
is_special_result: number;
|
||||
|
||||
update_date: number;
|
||||
}
|
||||
46
iidx@asphyxia/models/arena.ts
Normal file
46
iidx@asphyxia/models/arena.ts
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
export const IIDX_CPUS = [
|
||||
[
|
||||
[6, 4, 5, 0],
|
||||
[7, 5, 6, 0],
|
||||
[8, 6, 6, 0],
|
||||
[9, 6, 7, 0],
|
||||
[10, 7, 7, 0],
|
||||
[10, 7, 8, 0],
|
||||
[11, 8, 8, 0],
|
||||
[11, 8, 9, 0],
|
||||
[12, 9, 9, 0],
|
||||
[12, 9, 10, 0],
|
||||
[13, 9, 10, 0],
|
||||
[13, 10, 10, 0],
|
||||
[14, 10, 11, 0],
|
||||
[14, 10, 11, 1],
|
||||
[15, 11, 11, 1],
|
||||
[15, 11, 12, 1],
|
||||
[16, 11, 12, 1],
|
||||
[16, 11, 12, 1],
|
||||
[17, 12, 12, 1],
|
||||
[18, 12, 12, 1],
|
||||
],
|
||||
[
|
||||
[6, 3, 5, 0],
|
||||
[7, 3, 5, 0],
|
||||
[8, 4, 5, 0],
|
||||
[8, 4, 5, 0],
|
||||
[9, 5, 6, 0],
|
||||
[9, 5, 6, 0],
|
||||
[10, 6, 6, 0],
|
||||
[10, 6, 7, 0],
|
||||
[11, 7, 7, 0],
|
||||
[11, 7, 8, 0],
|
||||
[12, 8, 8, 0],
|
||||
[12, 8, 9, 0],
|
||||
[13, 9, 9, 0],
|
||||
[13, 9, 10, 0],
|
||||
[14, 9, 10, 0],
|
||||
[15, 10, 10, 0],
|
||||
[15, 10, 11, 0],
|
||||
[16, 11, 11, 1],
|
||||
[17, 11, 12, 1],
|
||||
[18, 12, 12, 1],
|
||||
],
|
||||
];
|
||||
8
iidx@asphyxia/models/badge.ts
Normal file
8
iidx@asphyxia/models/badge.ts
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
export interface badge {
|
||||
collection: "badge";
|
||||
version: number;
|
||||
|
||||
category_name: string;
|
||||
flg_id: number;
|
||||
flg: number;
|
||||
}
|
||||
117
iidx@asphyxia/models/custom.ts
Normal file
117
iidx@asphyxia/models/custom.ts
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
export interface custom {
|
||||
collection: "custom";
|
||||
|
||||
version: number;
|
||||
|
||||
// skin //
|
||||
frame: number;
|
||||
turntable: number;
|
||||
note_burst: number;
|
||||
menu_music: number;
|
||||
lane_cover: number;
|
||||
category_vox: number;
|
||||
note_skin: number;
|
||||
full_combo_splash: number;
|
||||
disable_musicpreview: boolean;
|
||||
|
||||
note_beam: number;
|
||||
judge_font: number;
|
||||
pacemaker_cover: number;
|
||||
vefx_lock: boolean;
|
||||
effect: number;
|
||||
bomb_size: number;
|
||||
disable_hcn_color: boolean;
|
||||
first_note_preview: number;
|
||||
|
||||
skin_customize_flg: number[];
|
||||
|
||||
note_size: number; // epolis //
|
||||
lift_cover: number;
|
||||
note_beam_size: number;
|
||||
|
||||
// appendsettings
|
||||
rank_folder: boolean;
|
||||
clear_folder: boolean;
|
||||
diff_folder: boolean;
|
||||
alpha_folder: boolean;
|
||||
rival_folder: boolean;
|
||||
rival_battle_folder: boolean;
|
||||
rival_info: boolean;
|
||||
hide_playcount: boolean;
|
||||
disable_graph_cutin: boolean;
|
||||
classic_hispeed: boolean;
|
||||
rival_played_folder: boolean;
|
||||
hide_iidxid: boolean;
|
||||
disable_beginner_option: boolean;
|
||||
|
||||
// qpro //
|
||||
qpro_head: number;
|
||||
qpro_hair: number;
|
||||
qpro_face: number;
|
||||
qpro_hand: number;
|
||||
qpro_body: number;
|
||||
qpro_back: number; // epolis //
|
||||
|
||||
// qpro_secret (heroic verse) //
|
||||
qpro_secret_head: string[];
|
||||
qpro_secret_hair: string[];
|
||||
qpro_secret_face: string[];
|
||||
qpro_secret_hand: string[];
|
||||
qpro_secret_body: string[];
|
||||
qpro_secret_back: string[]; // epolis //
|
||||
}
|
||||
|
||||
export const default_custom = {
|
||||
frame: 0,
|
||||
turntable: 0,
|
||||
note_burst: 0,
|
||||
menu_music: 0,
|
||||
lane_cover: 0,
|
||||
category_vox: 0,
|
||||
note_skin: 0,
|
||||
full_combo_splash: 0,
|
||||
disable_musicpreview: false,
|
||||
|
||||
note_beam: 0,
|
||||
judge_font: 0,
|
||||
pacemaker_cover: 0,
|
||||
vefx_lock: false,
|
||||
effect: 0,
|
||||
bomb_size: 0,
|
||||
disable_hcn_color: false,
|
||||
first_note_preview: 0,
|
||||
|
||||
skin_customize_flg: Array<number>(3).fill(-1),
|
||||
|
||||
note_size: 0,
|
||||
lift_cover: 0,
|
||||
note_beam_size: 0,
|
||||
|
||||
rank_folder: true,
|
||||
clear_folder: true,
|
||||
diff_folder: true,
|
||||
alpha_folder: true,
|
||||
rival_folder: true,
|
||||
rival_battle_folder: true,
|
||||
rival_info: true,
|
||||
hide_playcount: false,
|
||||
disable_graph_cutin: false,
|
||||
classic_hispeed: false,
|
||||
rival_played_folder: true,
|
||||
hide_iidxid: false,
|
||||
disable_beginner_option: false,
|
||||
|
||||
qpro_head: 0,
|
||||
qpro_hair: 0,
|
||||
qpro_face: 0,
|
||||
qpro_hand: 0,
|
||||
qpro_body: 0,
|
||||
qpro_back: 0,
|
||||
|
||||
qpro_secret_head: Array<string>(7).fill("-1"),
|
||||
qpro_secret_hair: Array<string>(7).fill("-1"),
|
||||
qpro_secret_face: Array<string>(7).fill("-1"),
|
||||
qpro_secret_hand: Array<string>(7).fill("-1"),
|
||||
qpro_secret_body: Array<string>(7).fill("-1"),
|
||||
qpro_secret_back: Array<string>(7).fill("-1"),
|
||||
}
|
||||
14
iidx@asphyxia/models/event.ts
Normal file
14
iidx@asphyxia/models/event.ts
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
export interface blueboss {
|
||||
level: number;
|
||||
gauge: number;
|
||||
item: number;
|
||||
item_flg: number;
|
||||
row0: number;
|
||||
row1: number;
|
||||
column0: number;
|
||||
column1: number;
|
||||
general: number;
|
||||
first_flg: number;
|
||||
sector: number;
|
||||
durability: string;
|
||||
}
|
||||
10
iidx@asphyxia/models/extraboss.ts
Normal file
10
iidx@asphyxia/models/extraboss.ts
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
export interface extra_boss {
|
||||
collection: "extra_boss";
|
||||
version: number;
|
||||
phase: number;
|
||||
|
||||
extra: number;
|
||||
extra_b: number;
|
||||
onemore: number;
|
||||
onemore_b: number;
|
||||
}
|
||||
10
iidx@asphyxia/models/favorite.ts
Normal file
10
iidx@asphyxia/models/favorite.ts
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
export interface extra_favorite {
|
||||
collection: "extra_favorite";
|
||||
version: number;
|
||||
folder_id: number;
|
||||
|
||||
sp_mlist: string | Buffer;
|
||||
sp_clist: string | Buffer;
|
||||
dp_mlist: string | Buffer;
|
||||
dp_clist: string | Buffer;
|
||||
}
|
||||
10
iidx@asphyxia/models/grade.ts
Normal file
10
iidx@asphyxia/models/grade.ts
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
export interface grade {
|
||||
collection: "grade";
|
||||
version: number;
|
||||
|
||||
style: number;
|
||||
gradeId: number;
|
||||
|
||||
maxStage: number;
|
||||
archive: number; // typo: achieve //
|
||||
}
|
||||
171
iidx@asphyxia/models/lightning.ts
Normal file
171
iidx@asphyxia/models/lightning.ts
Normal file
|
|
@ -0,0 +1,171 @@
|
|||
export interface lightning_settings {
|
||||
collection: "lightning_settings";
|
||||
version: number;
|
||||
|
||||
headphone_vol: number;
|
||||
|
||||
resistance_sp_left: number;
|
||||
resistance_sp_right: number;
|
||||
resistance_dp_left: number;
|
||||
resistance_dp_right: number;
|
||||
|
||||
slider: number[];
|
||||
light: number[];
|
||||
concentration: number;
|
||||
|
||||
keyboard_kind: number; // epolis //
|
||||
brightness: number;
|
||||
}
|
||||
|
||||
export interface lightning_playdata {
|
||||
collection: "lightning_playdata";
|
||||
|
||||
version: number;
|
||||
|
||||
sp_num: number;
|
||||
dp_num: number;
|
||||
}
|
||||
|
||||
export interface lightning_custom {
|
||||
collection: "lightning_custom";
|
||||
version: number;
|
||||
|
||||
premium_skin: number;
|
||||
premium_bg: number;
|
||||
}
|
||||
|
||||
export interface eisei_grade {
|
||||
collection: "eisei_grade";
|
||||
version: number;
|
||||
|
||||
clear_type: number;
|
||||
grade_id: number;
|
||||
grade_type: number;
|
||||
stage_num: number;
|
||||
option: number;
|
||||
|
||||
past_achievement: number[];
|
||||
past_selected_course: number[];
|
||||
max_past_achievement: number[];
|
||||
max_past_selected_course: number[];
|
||||
}
|
||||
|
||||
export interface eisei_grade_data {
|
||||
clear_type: number;
|
||||
grade_id: number;
|
||||
grade_type: number;
|
||||
stage_num: number;
|
||||
option: number;
|
||||
|
||||
past: number[];
|
||||
selected_course: number[];
|
||||
max_past: number[];
|
||||
max_selected_course: number[];
|
||||
}
|
||||
|
||||
export interface lightning_musicmemo {
|
||||
collection: "lightning_musicmemo";
|
||||
version: number;
|
||||
|
||||
music_idx: number;
|
||||
play_style: number;
|
||||
music_id: number;
|
||||
}
|
||||
|
||||
export interface musicmemo_data {
|
||||
music_idx: number;
|
||||
play_style: number;
|
||||
music_id: number;
|
||||
}
|
||||
|
||||
export interface lightning_musicmemo_new {
|
||||
collection: "lightning_musicmemo_new";
|
||||
version: number;
|
||||
|
||||
folder_idx: number;
|
||||
folder_name: string;
|
||||
play_style: number;
|
||||
music_ids: number[];
|
||||
}
|
||||
|
||||
export interface musicmemo_data_new {
|
||||
folder_idx: number;
|
||||
folder_name: string;
|
||||
play_style: number;
|
||||
music_ids: number[];
|
||||
}
|
||||
|
||||
export interface lightning_musicfilter {
|
||||
collection: "lightning_musicfilter";
|
||||
version: number;
|
||||
|
||||
play_style: number;
|
||||
folder_id: number;
|
||||
filter_id: number;
|
||||
is_valid: boolean;
|
||||
value0: number;
|
||||
value1: number;
|
||||
}
|
||||
|
||||
export interface lightning_musicfilter_sort {
|
||||
collection: "lightning_musicfilter_sort";
|
||||
version: number;
|
||||
|
||||
play_style: number;
|
||||
folder_id: number;
|
||||
sort: number;
|
||||
}
|
||||
|
||||
export interface musicfilter_data {
|
||||
play_style: number;
|
||||
folder_id: number;
|
||||
filter_id: number;
|
||||
is_valid: number;
|
||||
value0: number;
|
||||
value1: number;
|
||||
}
|
||||
|
||||
export interface musicfilter_sort_data {
|
||||
play_style: number;
|
||||
folder_id: number;
|
||||
sort: number;
|
||||
}
|
||||
|
||||
export const lm_playdata = {
|
||||
sp_num: 0,
|
||||
dp_num: 0,
|
||||
};
|
||||
|
||||
export const lm_settings = {
|
||||
headphone_vol: 10,
|
||||
|
||||
resistance_sp_left: 4,
|
||||
resistance_sp_right: 4,
|
||||
resistance_dp_left: 4,
|
||||
resistance_dp_right: 4,
|
||||
|
||||
slider: [7, 7, 7, 7, 7, 15, 15],
|
||||
light: [1, 1, 1, 1, 1, 1],
|
||||
concentration: 0,
|
||||
};
|
||||
|
||||
export const lm_settings_new = {
|
||||
headphone_vol: 10,
|
||||
|
||||
resistance_sp_left: 4,
|
||||
resistance_sp_right: 4,
|
||||
resistance_dp_left: 4,
|
||||
resistance_dp_right: 4,
|
||||
|
||||
slider: [7, 7, 7, 7, 7, 15, 15],
|
||||
light: [1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
|
||||
concentration: 0,
|
||||
|
||||
keyboard_kind: 10, // epolis //
|
||||
brightness: 2,
|
||||
}
|
||||
|
||||
export const lm_customdata = {
|
||||
premium_skin: 0, // Icons //
|
||||
premium_bg: 0, // Background (epolis) //
|
||||
}
|
||||
1710
iidx@asphyxia/models/pcdata.ts
Normal file
1710
iidx@asphyxia/models/pcdata.ts
Normal file
File diff suppressed because it is too large
Load Diff
22
iidx@asphyxia/models/profile.ts
Normal file
22
iidx@asphyxia/models/profile.ts
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
export interface profile {
|
||||
collection: "profile";
|
||||
|
||||
refid: string;
|
||||
id: number;
|
||||
idstr: string;
|
||||
name: string;
|
||||
pid: number;
|
||||
|
||||
language: number;
|
||||
total_pc: number;
|
||||
total_kbd: number;
|
||||
total_scr: number;
|
||||
}
|
||||
|
||||
export const default_profile = {
|
||||
language: -1,
|
||||
|
||||
total_pc: 0,
|
||||
total_kbd: 0,
|
||||
total_scr: 0,
|
||||
}
|
||||
29
iidx@asphyxia/models/ranking.ts
Normal file
29
iidx@asphyxia/models/ranking.ts
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
export interface expert {
|
||||
collection: "expert";
|
||||
version: number;
|
||||
coid: number;
|
||||
|
||||
cArray: number[];
|
||||
pgArray: number[];
|
||||
gArray: number[];
|
||||
optArray: number[];
|
||||
opt2Array: number[];
|
||||
esArray: number[];
|
||||
}
|
||||
|
||||
export interface ranking {
|
||||
collection: "ranking";
|
||||
version: number;
|
||||
clid: number;
|
||||
coid: number;
|
||||
|
||||
gnum: number;
|
||||
pgnum: number;
|
||||
name: string;
|
||||
opname: string;
|
||||
pid: number;
|
||||
udate: number;
|
||||
|
||||
exscore: number; // <- for sort //
|
||||
maxStage: number;
|
||||
}
|
||||
17
iidx@asphyxia/models/rival.ts
Normal file
17
iidx@asphyxia/models/rival.ts
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
export interface rival {
|
||||
collection: "rival";
|
||||
|
||||
play_style: number;
|
||||
|
||||
index: number;
|
||||
rival_refid: string;
|
||||
};
|
||||
|
||||
export interface rival_data {
|
||||
play_style: number;
|
||||
index: number;
|
||||
|
||||
qprodata: number[];
|
||||
profile: (string | number)[];
|
||||
pcdata: number[];
|
||||
}
|
||||
39
iidx@asphyxia/models/score.ts
Normal file
39
iidx@asphyxia/models/score.ts
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
export interface score {
|
||||
collection: "score";
|
||||
|
||||
mid: number;
|
||||
|
||||
pgArray: number[];
|
||||
gArray: number[];
|
||||
mArray: number[];
|
||||
cArray: number[];
|
||||
rArray: number[];
|
||||
esArray: number[];
|
||||
|
||||
optArray: number[];
|
||||
opt2Array: number[];
|
||||
}
|
||||
|
||||
export interface score_top {
|
||||
collection: "score_top";
|
||||
|
||||
play_style: number;
|
||||
mid: number;
|
||||
|
||||
names: string[];
|
||||
scores: number[];
|
||||
clflgs: number[];
|
||||
}
|
||||
|
||||
export interface old_score {
|
||||
music_id: number;
|
||||
|
||||
spmArray: number[];
|
||||
dpmArray: number[];
|
||||
|
||||
optArray: number[];
|
||||
opt2Array: number[];
|
||||
|
||||
option_1: number;
|
||||
option_2: number;
|
||||
}
|
||||
19
iidx@asphyxia/models/shop.ts
Normal file
19
iidx@asphyxia/models/shop.ts
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
export interface shop_data {
|
||||
collection: "shop_data";
|
||||
|
||||
opname: string;
|
||||
pid: number;
|
||||
cls_opt: number;
|
||||
}
|
||||
|
||||
export interface convention_data {
|
||||
collection: "shop_convention";
|
||||
|
||||
version: number;
|
||||
|
||||
music_0: number;
|
||||
music_1: number;
|
||||
music_2: number;
|
||||
music_3: number;
|
||||
valid: boolean;
|
||||
}
|
||||
7
iidx@asphyxia/models/tutorial.ts
Normal file
7
iidx@asphyxia/models/tutorial.ts
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
export interface tutorial {
|
||||
collection: "tutorial";
|
||||
version: number;
|
||||
tid: number;
|
||||
|
||||
clr: number;
|
||||
}
|
||||
7
iidx@asphyxia/models/worldtourism.ts
Normal file
7
iidx@asphyxia/models/worldtourism.ts
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
export interface world_tourism {
|
||||
collection: "world_tourism";
|
||||
version: number;
|
||||
|
||||
tour_id: number;
|
||||
progress: number;
|
||||
}
|
||||
9
iidx@asphyxia/pug/GLD/pcget.pug
Normal file
9
iidx@asphyxia/pug/GLD/pcget.pug
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
pc(status="0")
|
||||
pcdata(id=profile.id idstr=profile.idstr name=profile.name pid=profile.pid spnum=pcdata.spnum dpnum=pcdata.dpnum sach=pcdata.sach dach=pcdata.dach sflg0=pcdata.sflg0 sflg1=pcdata.sflg1 sflg2=pcdata.sflg2 gno=pcdata.gno sdhd=pcdata.sdhd sp_opt=pcdata.sp_opt dp_opt=pcdata.dp_opt dp_opt2=pcdata.dp_opt2 mcomb=pcdata.mcomb ncomb=pcdata.ncomb mode=pcdata.mode pmode=pcdata.pmode)
|
||||
grade(sgid=pcdata.sgid dgid=pcdata.dgid __type="str") #{gradeStr}
|
||||
ex(__type="str") #{exStr}
|
||||
skin(__type="str") #{skinStr}
|
||||
rlist
|
||||
- for (let rd of rArray)
|
||||
rival(rno=rd.index id=rd.profile[2] id_str=rd.profile[3] djname=rd.profile[0] pid=rd.profile[1] sg=rd.pcdata[0] dg=rd.pcdata[1] sa=rd.pcdata[2] da=rd.pcdata[3])
|
||||
gold(now_g=pcdata.gold_now all_g=pcdata.gold_all use_g=pcdata.gold_use)
|
||||
9
iidx@asphyxia/pug/HDD/pcget.pug
Normal file
9
iidx@asphyxia/pug/HDD/pcget.pug
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
pc(status="0")
|
||||
pcdata(id=profile.id idstr=profile.idstr name=profile.name pid=profile.pid spnum=pcdata.spnum dpnum=pcdata.dpnum sach=pcdata.sach dach=pcdata.dach sflg0=pcdata.sflg0 sflg1=pcdata.sflg1 sflg2=pcdata.sflg2 gno=pcdata.gno sdhd=pcdata.sdhd sp_opt=pcdata.sp_opt dp_opt=pcdata.dp_opt dp_opt2=pcdata.dp_opt2 mcomb=pcdata.mcomb ncomb=pcdata.ncomb mode=pcdata.mode pmode=pcdata.pmode)
|
||||
grade(sgid=pcdata.sgid dgid=pcdata.dgid __type="str") #{gradeStr}
|
||||
ex(__type="str") #{exStr}
|
||||
skin(__type="str") #{skinStr}
|
||||
rlist
|
||||
- for (let rd of rArray)
|
||||
rival(spdp=rd.play_style id=rd.profile[2] id_str=rd.profile[3] djname=rd.profile[0] pid=rd.profile[1] sg=rd.pcdata[0] dg=rd.pcdata[1] sa=rd.pcdata[2] da=rd.pcdata[3])
|
||||
visitor(anum="10" snum="10" pnum="10" vs_flg="1")
|
||||
17
iidx@asphyxia/pug/I00/pcget.pug
Normal file
17
iidx@asphyxia/pug/I00/pcget.pug
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
pc(status="0")
|
||||
pcdata(id=profile.id idstr=profile.idstr name=profile.name pid=profile.pid spnum=pcdata.spnum dpnum=pcdata.dpnum sach=pcdata.sach dach=pcdata.dach sflg0=pcdata.sflg0 sflg1=pcdata.sflg1 sflg2=pcdata.sflg2 gno=pcdata.gno sdhd=pcdata.sdhd sp_opt=pcdata.sp_opt dp_opt=pcdata.dp_opt dp_opt2=pcdata.dp_opt2 mcomb=pcdata.mcomb ncomb=pcdata.ncomb mode=pcdata.mode pmode=pcdata.pmode lift_len=pcdata.liflen)
|
||||
grade(sgid=pcdata.sgid dgid=pcdata.dgid)
|
||||
- for (let d of dArray)
|
||||
g(__type="u8" __count="4") #{d[0]} #{d[1]} #{d[2]} #{d[3]}
|
||||
ex
|
||||
- for (let e of eArray)
|
||||
e(__type="u32" __count="5") #{e[0]} #{e[1]} #{e[2]} #{e[3]} #{e[4]}
|
||||
skin(__type="u16" __count="12") #{custom.frame} #{custom.turntable} #{custom.note_burst} #{custom.menu_music} #{appendsettings} #{custom.lane_cover} 0 #{custom.category_vox} 0 0 0 0
|
||||
rlist
|
||||
- for (let rd of rArray)
|
||||
rival(spdp=rd.play_style id=rd.profile[2] id_str=rd.profile[3] djname=rd.profile[0] pid=rd.profile[1] sg=rd.pcdata[0] dg=rd.pcdata[1] sa=rd.pcdata[2] da=rd.pcdata[3])
|
||||
visitor(anum="10" snum="10" pnum="10" vs_flg="1")
|
||||
fcombo(__type="s16" __count="2") #{pcdata.fcombo[0]} #{pcdata.fcombo[1]}
|
||||
jewel(rate="100")
|
||||
jnum(__type="s64") #{pcdata.jewel_num}
|
||||
bjnum(__type="s32" __count="18") #{pcdata.jewel_bnum[0]} #{pcdata.jewel_bnum[1]} #{pcdata.jewel_bnum[2]} #{pcdata.jewel_bnum[3]} #{pcdata.jewel_bnum[4]} #{pcdata.jewel_bnum[5]} #{pcdata.jewel_bnum[6]} #{pcdata.jewel_bnum[7]} #{pcdata.jewel_bnum[8]} #{pcdata.jewel_bnum[9]} #{pcdata.jewel_bnum[10]} #{pcdata.jewel_bnum[11]} #{pcdata.jewel_bnum[12]} #{pcdata.jewel_bnum[13]} #{pcdata.jewel_bnum[14]} #{pcdata.jewel_bnum[15]} #{pcdata.jewel_bnum[16]} #{pcdata.jewel_bnum[17]}
|
||||
17
iidx@asphyxia/pug/JDJ/pcget.pug
Normal file
17
iidx@asphyxia/pug/JDJ/pcget.pug
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
pc(status="0")
|
||||
pcdata(id=profile.id idstr=profile.idstr name=profile.name pid=profile.pid spnum=pcdata.spnum dpnum=pcdata.dpnum sach=pcdata.sach dach=pcdata.dach sflg0=pcdata.sflg0 sflg1=pcdata.sflg1 gno=pcdata.gno timing=pcdata.timing sdhd=pcdata.sdhd sp_opt=pcdata.sp_opt dp_opt=pcdata.dp_opt dp_opt2=pcdata.dp_opt2 mcomb=pcdata.mcomb ncomb=pcdata.ncomb mode=pcdata.mode pmode=pcdata.pmode liflen=pcdata.liflen)
|
||||
grade(sgid=pcdata.sgid dgid=pcdata.dgid)
|
||||
- for (let d of dArray)
|
||||
g(__type="u8" __count="4") #{d[0]} #{d[1]} #{d[2]} #{d[3]}
|
||||
ex
|
||||
- for (let e of eArray)
|
||||
e(__type="u32" __count="5") #{e[0]} #{e[1]} #{e[2]} #{e[3]} #{e[4]}
|
||||
skin(__type="u16" __count="12") #{custom.frame} #{custom.turntable} #{custom.note_burst} #{custom.menu_music} #{appendsettings} #{custom.lane_cover} 0 #{custom.category_vox} 0 0 0 0
|
||||
rlist
|
||||
- for (let rd of rArray)
|
||||
rival(spdp=rd.play_style id=rd.profile[2] id_str=rd.profile[3] djname=rd.profile[0] pid=rd.profile[1] sg=rd.pcdata[0] dg=rd.pcdata[1] sa=rd.pcdata[2] da=rd.pcdata[3])
|
||||
visitor(anum="10" snum="10" pnum="10" vs_flg="1")
|
||||
fcombo(__type="s16" __count="2") #{pcdata.fcombo[0]} #{pcdata.fcombo[1]}
|
||||
party
|
||||
fnum(__type="s32" __count="24") #{pcdata.party[0]} #{pcdata.party[1]} #{pcdata.party[2]} #{pcdata.party[3]} #{pcdata.party[4]} #{pcdata.party[5]} #{pcdata.party[6]} #{pcdata.party[7]} #{pcdata.party[8]} #{pcdata.party[9]} #{pcdata.party[10]} #{pcdata.party[11]} #{pcdata.party[12]} #{pcdata.party[13]} #{pcdata.party[14]} #{pcdata.party[15]} #{pcdata.party[16]} #{pcdata.party[17]} #{pcdata.party[18]} #{pcdata.party[19]} #{pcdata.party[20]} #{pcdata.party[21]} #{pcdata.party[22]} #{pcdata.party[23]}
|
||||
jubeat(jflg_0="-1" jflg_1="-1" jflg_2="-1" jflg_3="-1")
|
||||
20
iidx@asphyxia/pug/JDZ/pcget.pug
Normal file
20
iidx@asphyxia/pug/JDZ/pcget.pug
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
pc(status="0")
|
||||
pcdata(id=profile.id idstr=profile.idstr name=profile.name pid=profile.pid spnum=pcdata.spnum dpnum=pcdata.dpnum sach=pcdata.sach dach=pcdata.dach sflg0=pcdata.sflg0 sflg1=pcdata.sflg1 gno=pcdata.gno timing=pcdata.timing sdhd=pcdata.sdhd sp_opt=pcdata.sp_opt dp_opt=pcdata.dp_opt dp_opt2=pcdata.dp_opt2 mcomb=pcdata.mcomb ncomb=pcdata.ncomb mode=pcdata.mode pmode=pcdata.pmode liflen=pcdata.liflen)
|
||||
grade(sgid=pcdata.sgid dgid=pcdata.dgid)
|
||||
- for (let d of dArray)
|
||||
g(__type="u8" __count="4") #{d[0]} #{d[1]} #{d[2]} #{d[3]}
|
||||
ex
|
||||
skin(__type="u16" __count="12") #{custom.frame} #{custom.turntable} #{custom.note_burst} #{custom.menu_music} #{appendsettings} #{custom.lane_cover} 0 #{custom.category_vox} 0 0 0 0
|
||||
rlist
|
||||
- for (let rd of rArray)
|
||||
rival(spdp=rd.play_style id=rd.profile[2] id_str=rd.profile[3] djname=rd.profile[0] pid=rd.profile[1] sg=rd.pcdata[0] dg=rd.pcdata[1] sa=rd.pcdata[2] da=rd.pcdata[3])
|
||||
visitor(anum="10" snum="10" pnum="10" vs_flg="1")
|
||||
fcombo(__type="s16" __count="2") #{pcdata.fcombo[0]} #{pcdata.fcombo[1]}
|
||||
lincle(comflg="1" flg1="-1" flg2="-1" flg3="-1" flg4="-1" flg5="-1" flg6="-1" flg7="-1" refcomp="1")
|
||||
reflec(tf="1" br="1" ssc="1" sr="1" wu="1" sg="1" tb="1")
|
||||
jubeat(jflg_0="-1" jflg_1="-1" jflg_2="-1" jflg_3="-1")
|
||||
if event != null
|
||||
tour(pt=event.pt rsv=event.rsv r0=event.r0 r1=event.r1 r2=event.r2 r3=event.r3 r4=event.r4 r5=event.r5 r6=event.r6 r7=event.r7)
|
||||
cf(__type="bin") #{event.cf}
|
||||
pf(__type="bin") #{event.pf}
|
||||
mf(__type="bin") #{event.mf}
|
||||
33
iidx@asphyxia/pug/KDZ/pcget.pug
Normal file
33
iidx@asphyxia/pug/KDZ/pcget.pug
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
pc(status="0")
|
||||
pcdata(id=profile.id idstr=profile.idstr name=profile.name pid=profile.pid spnum=pcdata.spnum dpnum=pcdata.dpnum sach=pcdata.sach dach=pcdata.dach sflg0=pcdata.sflg0 sflg1=pcdata.sflg1 help=pcdata.help gno=pcdata.gno timing=pcdata.timing sdhd=pcdata.sdhd sdtype=pcdata.sdtype notes=pcdata.notes pase=pcdata.pase sp_opt=pcdata.sp_opt dp_opt=pcdata.dp_opt dp_opt2=pcdata.dp_opt2 mode=pcdata.mode pmode=pcdata.pmode liflen=pcdata.liflen)
|
||||
grade(sgid=pcdata.sgid dgid=pcdata.dgid)
|
||||
- for (let d of dArray)
|
||||
g(__type="u8" __count="4") #{d[0]} #{d[1]} #{d[2]} #{d[3]}
|
||||
ex
|
||||
skin(__type="s16" __count="14") #{custom.frame} #{custom.turntable} #{custom.note_burst} #{custom.menu_music} #{appendsettings} #{custom.lane_cover} 0 #{custom.category_vox} #{custom.note_skin} #{custom.full_combo_splash} 0 #{Number(custom.disable_musicpreview)} 0 0
|
||||
qprodata(__type="u32" __count="5") #{custom.qpro_head} #{custom.qpro_hair} #{custom.qpro_face} #{custom.qpro_hand} #{custom.qpro_body}
|
||||
rlist
|
||||
- for (let rd of rArray)
|
||||
rival(spdp=rd.play_style id=rd.profile[2] id_str=rd.profile[3] djname=rd.profile[0] pid=rd.profile[1] sg=rd.pcdata[0] dg=rd.pcdata[1] sa=rd.pcdata[2] da=rd.pcdata[3])
|
||||
qprodata(body=rd.qprodata[3] face=rd.qprodata[2] hair=rd.qprodata[0] hand=rd.qprodata[4] head=rd.qprodata[1])
|
||||
ocrs
|
||||
//-weekly(wid="-1" mid="-1")
|
||||
visitor(anum="10" snum="10" pnum="10" vs_flg="1")
|
||||
fcombo(__type="s16" __count="2") #{pcdata.fcombo[0]} #{pcdata.fcombo[1]}
|
||||
step(sp_ach=pcdata.st_sp_ach dp_ach=pcdata.st_dp_ach sp_dif=pcdata.st_sp_dif dp_dif=pcdata.st_dp_dif)
|
||||
lincle(comflg="1" flg1="-1" flg2="-1" flg3="-1" flg4="-1" flg5="-1" flg6="-1" flg7="-1")
|
||||
reflec(tf="1" br="1" ssc="1" sr="1" wu="1" sg="1" tb="1")
|
||||
jubeat(point="0" bonus="0" jbonus=pcdata.jpoint open="1")
|
||||
if event != null
|
||||
kingdom(level=event.level exp=event.exp deller=event.deller place=event.place tower=event.tower boss=event.boss combo=event.combo jewel=event.jewel generic=event.generic)
|
||||
cf(__type="bin") #{event.cf}
|
||||
qcf(__type="bin") #{event.qcf}
|
||||
piece(__type="bin") #{event.piece}
|
||||
history
|
||||
type(__type="u8" __count="30") #{pcdata.type[0]} #{pcdata.type[1]} #{pcdata.type[2]} #{pcdata.type[3]} #{pcdata.type[4]} #{pcdata.type[5]} #{pcdata.type[6]} #{pcdata.type[7]} #{pcdata.type[8]} #{pcdata.type[9]} #{pcdata.type[10]} #{pcdata.type[11]} #{pcdata.type[12]} #{pcdata.type[13]} #{pcdata.type[14]} #{pcdata.type[15]} #{pcdata.type[16]} #{pcdata.type[17]} #{pcdata.type[18]} #{pcdata.type[19]} #{pcdata.type[20]} #{pcdata.type[21]} #{pcdata.type[22]} #{pcdata.type[23]} #{pcdata.type[24]} #{pcdata.type[25]} #{pcdata.type[26]} #{pcdata.type[27]} #{pcdata.type[28]} #{pcdata.type[29]}
|
||||
time(__type="time" __count="30") #{pcdata.time[0]} #{pcdata.time[1]} #{pcdata.time[2]} #{pcdata.time[3]} #{pcdata.time[4]} #{pcdata.time[5]} #{pcdata.time[6]} #{pcdata.time[7]} #{pcdata.time[8]} #{pcdata.time[9]} #{pcdata.time[10]} #{pcdata.time[11]} #{pcdata.time[12]} #{pcdata.time[13]} #{pcdata.time[14]} #{pcdata.time[15]} #{pcdata.time[16]} #{pcdata.time[17]} #{pcdata.time[18]} #{pcdata.time[19]} #{pcdata.time[20]} #{pcdata.time[21]} #{pcdata.time[22]} #{pcdata.time[23]} #{pcdata.time[24]} #{pcdata.time[25]} #{pcdata.time[26]} #{pcdata.time[27]} #{pcdata.time[28]} #{pcdata.time[29]}
|
||||
param0(__type="s32" __count="30") #{pcdata.p0[0]} #{pcdata.p0[1]} #{pcdata.p0[2]} #{pcdata.p0[3]} #{pcdata.p0[4]} #{pcdata.p0[5]} #{pcdata.p0[6]} #{pcdata.p0[7]} #{pcdata.p0[8]} #{pcdata.p0[9]} #{pcdata.p0[10]} #{pcdata.p0[11]} #{pcdata.p0[12]} #{pcdata.p0[13]} #{pcdata.p0[14]} #{pcdata.p0[15]} #{pcdata.p0[16]} #{pcdata.p0[17]} #{pcdata.p0[18]} #{pcdata.p0[19]} #{pcdata.p0[20]} #{pcdata.p0[21]} #{pcdata.p0[22]} #{pcdata.p0[23]} #{pcdata.p0[24]} #{pcdata.p0[25]} #{pcdata.p0[26]} #{pcdata.p0[27]} #{pcdata.p0[28]} #{pcdata.p0[29]}
|
||||
param1(__type="s32" __count="30") #{pcdata.p1[0]} #{pcdata.p1[1]} #{pcdata.p1[2]} #{pcdata.p1[3]} #{pcdata.p1[4]} #{pcdata.p1[5]} #{pcdata.p1[6]} #{pcdata.p1[7]} #{pcdata.p1[8]} #{pcdata.p1[9]} #{pcdata.p1[10]} #{pcdata.p1[11]} #{pcdata.p1[12]} #{pcdata.p1[13]} #{pcdata.p1[14]} #{pcdata.p1[15]} #{pcdata.p1[16]} #{pcdata.p1[17]} #{pcdata.p1[18]} #{pcdata.p1[19]} #{pcdata.p1[20]} #{pcdata.p1[21]} #{pcdata.p1[22]} #{pcdata.p1[23]} #{pcdata.p1[24]} #{pcdata.p1[25]} #{pcdata.p1[26]} #{pcdata.p1[27]} #{pcdata.p1[28]} #{pcdata.p1[29]}
|
||||
param2(__type="s32" __count="30") #{pcdata.p2[0]} #{pcdata.p2[1]} #{pcdata.p2[2]} #{pcdata.p2[3]} #{pcdata.p2[4]} #{pcdata.p2[5]} #{pcdata.p2[6]} #{pcdata.p2[7]} #{pcdata.p2[8]} #{pcdata.p2[9]} #{pcdata.p2[10]} #{pcdata.p2[11]} #{pcdata.p2[12]} #{pcdata.p2[13]} #{pcdata.p2[14]} #{pcdata.p2[15]} #{pcdata.p2[16]} #{pcdata.p2[17]} #{pcdata.p2[18]} #{pcdata.p2[19]} #{pcdata.p2[20]} #{pcdata.p2[21]} #{pcdata.p2[22]} #{pcdata.p2[23]} #{pcdata.p2[24]} #{pcdata.p2[25]} #{pcdata.p2[26]} #{pcdata.p2[27]} #{pcdata.p2[28]} #{pcdata.p2[29]}
|
||||
param3(__type="s32" __count="30") #{pcdata.p3[0]} #{pcdata.p3[1]} #{pcdata.p3[2]} #{pcdata.p3[3]} #{pcdata.p3[4]} #{pcdata.p3[5]} #{pcdata.p3[6]} #{pcdata.p3[7]} #{pcdata.p3[8]} #{pcdata.p3[9]} #{pcdata.p3[10]} #{pcdata.p3[11]} #{pcdata.p3[12]} #{pcdata.p3[13]} #{pcdata.p3[14]} #{pcdata.p3[15]} #{pcdata.p3[16]} #{pcdata.p3[17]} #{pcdata.p3[18]} #{pcdata.p3[19]} #{pcdata.p3[20]} #{pcdata.p3[21]} #{pcdata.p3[22]} #{pcdata.p3[23]} #{pcdata.p3[24]} #{pcdata.p3[25]} #{pcdata.p3[26]} #{pcdata.p3[27]} #{pcdata.p3[28]} #{pcdata.p3[29]}
|
||||
param4(__type="s32" __count="30") #{pcdata.p4[0]} #{pcdata.p4[1]} #{pcdata.p4[2]} #{pcdata.p4[3]} #{pcdata.p4[4]} #{pcdata.p4[5]} #{pcdata.p4[6]} #{pcdata.p4[7]} #{pcdata.p4[8]} #{pcdata.p4[9]} #{pcdata.p4[10]} #{pcdata.p4[11]} #{pcdata.p4[12]} #{pcdata.p4[13]} #{pcdata.p4[14]} #{pcdata.p4[15]} #{pcdata.p4[16]} #{pcdata.p4[17]} #{pcdata.p4[18]} #{pcdata.p4[19]} #{pcdata.p4[20]} #{pcdata.p4[21]} #{pcdata.p4[22]} #{pcdata.p4[23]} #{pcdata.p4[24]} #{pcdata.p4[25]} #{pcdata.p4[26]} #{pcdata.p4[27]} #{pcdata.p4[28]} #{pcdata.p4[29]}
|
||||
56
iidx@asphyxia/pug/LDJ/21pcget.pug
Normal file
56
iidx@asphyxia/pug/LDJ/21pcget.pug
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
IIDX21pc(status="0")
|
||||
pcdata(id=profile.id idstr=profile.idstr name=profile.name pid=profile.pid spnum=pcdata.spnum dpnum=pcdata.dpnum sach=pcdata.sach dach=pcdata.dach mode=pcdata.mode pmode=pcdata.pmode rtype=pcdata.rtype sp_opt=pcdata.sp_opt dp_opt=pcdata.dp_opt dp_opt2=pcdata.dp_opt2 gpos=pcdata.gpos s_sorttype=pcdata.s_sorttype d_sorttype=pcdata.d_sorttype s_pace=pcdata.s_pace d_pace=pcdata.d_pace s_gno=pcdata.s_gno d_gno=pcdata.d_gno s_gtype=pcdata.s_gtype d_gtype=pcdata.d_gtype s_sdlen=pcdata.s_sdlen d_sdlen=pcdata.d_sdlen s_sdtype=pcdata.s_sdtype d_sdtype=pcdata.d_sdtype s_timing=pcdata.s_timing d_timing=pcdata.d_timing s_notes=pcdata.s_notes d_notes=pcdata.d_notes s_judge=pcdata.s_judge d_judge=pcdata.d_judge s_judgeAdj=pcdata.s_judgeAdj d_judgeAdj=pcdata.d_judgeAdj s_hispeed=pcdata.s_hispeed d_hispeed=pcdata.d_hispeed s_liflen=pcdata.s_liflen d_liflen=pcdata.d_liflen s_disp_judge=pcdata.s_disp_judge d_disp_judge=pcdata.d_disp_judge s_opstyle=pcdata.s_opstyle d_opstyle=pcdata.d_opstyle)
|
||||
spdp_rival(flg="-1")
|
||||
bind_eaappli
|
||||
secret
|
||||
flg1(__type="s64" __count="2") -1 -1
|
||||
flg2(__type="s64" __count="2") -1 -1
|
||||
flg3(__type="s64" __count="2") -1 -1
|
||||
if pcdata.sp_mlist != null
|
||||
favorite
|
||||
sp_mlist(__type="bin") #{pcdata.sp_mlist}
|
||||
sp_clist(__type="bin") #{pcdata.sp_clist}
|
||||
dp_mlist(__type="bin") #{pcdata.dp_mlist}
|
||||
dp_clist(__type="bin") #{pcdata.dp_clist}
|
||||
qpro_secret
|
||||
head(__type="s64" __count="3") -1 -1 -1
|
||||
hair(__type="s64" __count="3") -1 -1 -1
|
||||
face(__type="s64" __count="3") -1 -1 -1
|
||||
body(__type="s64" __count="3") -1 -1 -1
|
||||
hand(__type="s64" __count="3") -1 -1 -1
|
||||
grade(sgid=pcdata.sgid dgid=pcdata.dgid)
|
||||
- for (let d of dArray)
|
||||
g(__type="u8" __count="4") #{d[0]} #{d[1]} #{d[2]} #{d[3]}
|
||||
skin(__type="s16" __count="14") #{custom.frame} #{custom.turntable} #{custom.note_burst} #{custom.menu_music} #{appendsettings} #{custom.lane_cover} 0 #{custom.category_vox} #{custom.note_skin} #{custom.full_combo_splash} 0 #{Number(custom.disable_musicpreview)} 0 0
|
||||
qprodata(__type="u32" __count="5") #{custom.qpro_head} #{custom.qpro_hair} #{custom.qpro_face} #{custom.qpro_hand} #{custom.qpro_body}
|
||||
rlist
|
||||
- for (let rd of rArray)
|
||||
rival(spdp=rd.play_style id=rd.profile[2] id_str=rd.profile[3] djname=rd.profile[0] pid=rd.profile[1] sg=rd.pcdata[0] dg=rd.pcdata[1] sa=rd.pcdata[2] da=rd.pcdata[3])
|
||||
stepdata(step_sach=rd.pcdata[4] step_dach=rd.pcdata[5])
|
||||
qprodata(body=rd.qprodata[3] face=rd.qprodata[2] hair=rd.qprodata[0] hand=rd.qprodata[4] head=rd.qprodata[1])
|
||||
shop(name=shop_data.opname)
|
||||
join_shop(joinflg="1" join_cflg="1" join_id="ea" join_name=shop_data.opname)
|
||||
visitor(anum="10" snum="10" pnum="10" vs_flg="1")
|
||||
if pcdata.st_album != null
|
||||
step(damage=pcdata.st_damage defeat=pcdata.st_defeat progress=pcdata.st_progress round=pcdata.st_round sp_mission=pcdata.st_sp_mission dp_mission=pcdata.st_dp_mission sp_level=pcdata.st_sp_level dp_level=pcdata.st_dp_level sp_mplay=pcdata.st_sp_mplay dp_mplay=pcdata.st_dp_mplay last_select=pcdata.st_last_select)
|
||||
album(__type="bin") #{pcdata.st_album}
|
||||
//-step_assist(iidx_id iidx_id_str name hair head face body hand)
|
||||
achievements(pack=pcdata.achi_pack pack_comp=pcdata.achi_packcomp last_weekly=pcdata.achi_lastweekly weekly_num=pcdata.achi_weeklynum visit_flg=pcdata.achi_visitflg rival_crush=pcdata.achi_rivalcrush)
|
||||
trophy(__type="s64" __count="10") #{pcdata.achi_trophy[0]} #{pcdata.achi_trophy[1]} #{pcdata.achi_trophy[2]} #{pcdata.achi_trophy[3]} #{pcdata.achi_trophy[4]} #{pcdata.achi_trophy[5]} #{pcdata.achi_trophy[6]} #{pcdata.achi_trophy[7]} #{pcdata.achi_trophy[8]} #{pcdata.achi_trophy[9]}
|
||||
if link5 != null
|
||||
link5(qpro=link5.qpro glass=link5.glass treasure="0" beautiful=link5.beautiful quaver=link5.quaver castle=link5.castle flip=link5.flip titans=link5.titans exusia=link5.exusia waxing=link5.waxing sampling=link5.sampling beachside=link5.beachside cuvelia=link5.cuvelia reunion=link5.reunion bad=link5.bad turii=link5.turii anisakis=link5.anisakis second=link5.second whydidyou=link5.whydidyou china=link5.china fallen=link5.fallen broken=link5.broken summer=link5.summer sakura=link5.sakura wuv=link5.wuv survival=link5.survival thunder=link5.thunder qproflg="0" glassflg="0" reflec_data="0")
|
||||
//-cafe(food pastry rainbow beastie astraia beachimp holysnow trueblue ledvsscu service is_first)
|
||||
gakuen(music_list="-1")
|
||||
baseball(music_list="-1")
|
||||
if tricolettepark != null
|
||||
tricolettepark(open_music=tricolettepark.open_music boss0_damage=tricolettepark.boss0_damage boss1_damage=tricolettepark.boss1_damage boss2_damage=tricolettepark.boss2_damage boss3_damage=tricolettepark.boss3_damage boss0_stun=tricolettepark.boss0_stun boss1_stun=tricolettepark.boss1_stun boss2_stun=tricolettepark.boss2_stun boss3_stun=tricolettepark.boss3_stun magic_gauge="0" party="0" is_union="0" attack_rate="1")
|
||||
pyramid(music_list="-1" item_list="-1" statue_0="0" statue_1="0" statue_2="0")
|
||||
deller(deller=pcdata.deller rate="1")
|
||||
orb_data(rest_orb=pcdata.orb)
|
||||
if boss1 != null
|
||||
boss1(stamina=boss1.stamina attack=boss1.attack item_flg=boss1.item_flg item_flg2=boss1.item_flg2 pick=boss1.pick row0=boss1.row0 row1=boss1.row1 row2=boss1.row2 row3=boss1.row3 column0=boss1.column0 column1=boss1.column1 column2=boss1.column2 column3=boss1.column3 map=boss1.map job=boss1.job general=boss1.general battle=boss1.battle boss0_n=boss1.boss0_n boss0_h=boss1.boss0_h boss0_a=boss1.boss0_a boss1_n=boss1.boss1_n boss1_h=boss1.boss1_h boss1_a=boss1.boss1_a boss2_n=boss1.boss2_n boss2_h=boss1.boss2_h boss2_a=boss1.boss2_a item1="0" item2="0" item3="0" boss_scene=boss1.boss_scene boss0_damage=boss1.boss0_damage boss1_damage=boss1.boss1_damage boss2_damage=boss1.boss2_damage boss3_damage=boss1.boss3_damage boss4_damage=boss1.boss4_damage boss5_damage=boss1.boss5_damage boss6_damage=boss1.boss6_damage)
|
||||
durability(__type="bin") #{boss1.durability}
|
||||
level(__type="s32" __count="28") #{boss1.level[0]} #{boss1.level[1]} #{boss1.level[2]} #{boss1.level[3]} #{boss1.level[4]} #{boss1.level[5]} #{boss1.level[6]}
|
||||
//-boss1_phase4(map_clear_flg)
|
||||
new_durability
|
||||
//-superstar(achieve_flg)
|
||||
67
iidx@asphyxia/pug/LDJ/22pcget.pug
Normal file
67
iidx@asphyxia/pug/LDJ/22pcget.pug
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
IIDX22pc(status="0")
|
||||
pcdata(id=profile.id idstr=profile.idstr name=profile.name pid=profile.pid spnum=pcdata.spnum dpnum=pcdata.dpnum sach=pcdata.sach dach=pcdata.dach mode=pcdata.mode pmode=pcdata.pmode rtype=pcdata.rtype sp_opt=pcdata.sp_opt dp_opt=pcdata.dp_opt dp_opt2=pcdata.dp_opt2 gpos=pcdata.gpos s_sorttype=pcdata.s_sorttype d_sorttype=pcdata.d_sorttype s_pace=pcdata.s_pace d_pace=pcdata.d_pace s_gno=pcdata.s_gno d_gno=pcdata.d_gno s_gtype=pcdata.s_gtype d_gtype=pcdata.d_gtype s_sdlen=pcdata.s_sdlen d_sdlen=pcdata.d_sdlen s_sdtype=pcdata.s_sdtype d_sdtype=pcdata.d_sdtype s_timing=pcdata.s_timing d_timing=pcdata.d_timing s_notes=pcdata.s_notes d_notes=pcdata.d_notes s_judge=pcdata.s_judge d_judge=pcdata.d_judge s_judgeAdj=pcdata.s_judgeAdj d_judgeAdj=pcdata.d_judgeAdj s_hispeed=pcdata.s_hispeed d_hispeed=pcdata.d_hispeed s_liflen=pcdata.s_liflen d_liflen=pcdata.d_liflen s_disp_judge=pcdata.s_disp_judge d_disp_judge=pcdata.d_disp_judge s_opstyle=pcdata.s_opstyle d_opstyle=pcdata.d_opstyle s_exscore=pcdata.s_exscore d_exscore=pcdata.d_exscore s_largejudge=pcdata.s_largejudge d_largejudge=pcdata.d_largejudge)
|
||||
spdp_rival(flg="-1")
|
||||
bind_eaappli
|
||||
secret
|
||||
flg1(__type="s64" __count="3") -1 -1 -1
|
||||
flg2(__type="s64" __count="3") -1 -1 -1
|
||||
flg3(__type="s64" __count="3") -1 -1 -1
|
||||
if pcdata.sp_mlist != null
|
||||
favorite
|
||||
sp_mlist(__type="bin") #{pcdata.sp_mlist}
|
||||
sp_clist(__type="bin") #{pcdata.sp_clist}
|
||||
dp_mlist(__type="bin") #{pcdata.dp_mlist}
|
||||
dp_clist(__type="bin") #{pcdata.dp_clist}
|
||||
qpro_secret
|
||||
head(__type="s64" __count="4") -1 -1 -1 -1
|
||||
hair(__type="s64" __count="4") -1 -1 -1 -1
|
||||
face(__type="s64" __count="4") -1 -1 -1 -1
|
||||
body(__type="s64" __count="4") -1 -1 -1 -1
|
||||
hand(__type="s64" __count="4") -1 -1 -1 -1
|
||||
grade(sgid=pcdata.sgid dgid=pcdata.dgid)
|
||||
- for (let d of dArray)
|
||||
g(__type="u8" __count="4") #{d[0]} #{d[1]} #{d[2]} #{d[3]}
|
||||
skin(__type="s16" __count="14") #{custom.frame} #{custom.turntable} #{custom.note_burst} #{custom.menu_music} #{appendsettings} #{custom.lane_cover} 0 #{custom.category_vox} #{custom.note_skin} #{custom.full_combo_splash} 0 #{Number(custom.disable_musicpreview)} 0 0
|
||||
qprodata(__type="u32" __count="5") #{custom.qpro_head} #{custom.qpro_hair} #{custom.qpro_face} #{custom.qpro_hand} #{custom.qpro_body}
|
||||
rlist
|
||||
- for (let rd of rArray)
|
||||
rival(spdp=rd.play_style id=rd.profile[2] id_str=rd.profile[3] djname=rd.profile[0] pid=rd.profile[1] sg=rd.pcdata[0] dg=rd.pcdata[1] sa=rd.pcdata[2] da=rd.pcdata[3])
|
||||
stepdata(step_sach=rd.pcdata[4] step_dach=rd.pcdata[5])
|
||||
qprodata(body=rd.qprodata[3] face=rd.qprodata[2] hair=rd.qprodata[0] hand=rd.qprodata[4] head=rd.qprodata[1])
|
||||
shop(name=shop_data.opname)
|
||||
join_shop(joinflg="1" join_cflg="1" join_id="ea" join_name=shop_data.opname)
|
||||
visitor(anum="10" snum="10" pnum="10" vs_flg="1")
|
||||
if pcdata.st_album != null
|
||||
step(damage=pcdata.st_damage defeat=pcdata.st_defeat progress=pcdata.st_progress round=pcdata.st_round sp_mission=pcdata.st_sp_mission dp_mission=pcdata.st_dp_mission sp_level=pcdata.st_sp_level dp_level=pcdata.st_dp_level sp_mplay=pcdata.st_sp_mplay dp_mplay=pcdata.st_dp_mplay age_list=pcdata.st_age_list is_secret=pcdata.st_is_secret is_present=pcdata.st_is_present is_future=pcdata.st_is_future)
|
||||
album(__type="bin") #{pcdata.st_album}
|
||||
//-step_assist(iidx_id iidx_id_str name hair head face body hand)
|
||||
if chrono_diver != null
|
||||
chrono_diver(play_count=chrono_diver.play_count present_unlock=chrono_diver.present_unlock future_unlock=chrono_diver.future_unlock success_count_0_n=chrono_diver.success_count_0_n success_count_0_h=chrono_diver.success_count_0_h success_count_0_a=chrono_diver.success_count_0_a success_count_1_n=chrono_diver.success_count_1_n success_count_1_h=chrono_diver.success_count_1_h success_count_1_a=chrono_diver.success_count_1_a success_count_2_n=chrono_diver.success_count_2_n success_count_2_h=chrono_diver.success_count_2_h success_count_2_a=chrono_diver.success_count_2_a success_count_3_n=chrono_diver.success_count_3_n success_count_3_h=chrono_diver.success_count_3_h success_count_3_a=chrono_diver.success_count_3_a story_list=chrono_diver.story_list)
|
||||
if qpronicle_chord != null
|
||||
qpronicle_chord(is_first_select_map=qpronicle_chord.is_first_select_map last_select_map=qpronicle_chord.last_select_map story_view_list=qpronicle_chord.story_view_list is_login_bonus=qpronicle_chord.is_use_login_bonus patona_leader=qpronicle_chord.patona_leader patona_sub_1=qpronicle_chord.patona_sub_1 patona_sub_2=qpronicle_chord.patona_sub_2 rare_enemy_damage1=qpronicle_chord.rare_enemy_damage1 rare_enemy_damage2=qpronicle_chord.rare_enemy_damage2 rare_enemy_damage3=qpronicle_chord.rare_enemy_damage3 rare_enemy_damage4=qpronicle_chord.rare_enemy_damage4 rare_enemy_damage5=qpronicle_chord.rare_enemy_damage5)
|
||||
- for (let evt of qpronicle_chord_sub)
|
||||
patona_data(patona_no=evt.patona_id level=evt.level exp=evt.exp affection=evt.affection dissatisfaction=evt.dissatisfaction)
|
||||
if qpronicle_phase3 != null
|
||||
qpronicle_phase3(stairs_num=qpronicle_phase3.stairs_num flame_list=qpronicle_phase3.flame_list lane_list=qpronicle_phase3.lane_list map0_select=qpronicle_phase3.map0_select map1_select=qpronicle_phase3.map1_select map2_select=qpronicle_phase3.map2_select map3_select=qpronicle_phase3.map3_select map4_select=qpronicle_phase3.map4_select map5_select=qpronicle_phase3.map5_select map6_select=qpronicle_phase3.map6_select is_love_scene_skip="1")
|
||||
qpronicle_love(music_list="-1")
|
||||
boss_event_3(music_list="-1" bonus_point=pendual_talis.point)
|
||||
//-chaser(phase attack exist_age summon_gate success failed damage_point boss_hp)
|
||||
ues_music(__type="u32" __count="40")
|
||||
achievements(pack=pcdata.achi_pack pack_comp=pcdata.achi_packcomp last_weekly=pcdata.achi_lastweekly weekly_num=pcdata.achi_weeklynum visit_flg=pcdata.achi_visitflg rival_crush=pcdata.achi_rivalcrush)
|
||||
trophy(__type="s64" __count="10") #{pcdata.achi_trophy[0]} #{pcdata.achi_trophy[1]} #{pcdata.achi_trophy[2]} #{pcdata.achi_trophy[3]} #{pcdata.achi_trophy[4]} #{pcdata.achi_trophy[5]} #{pcdata.achi_trophy[6]} #{pcdata.achi_trophy[7]} #{pcdata.achi_trophy[8]} #{pcdata.achi_trophy[9]}
|
||||
old_linked_event(gakuen_list="-1" baseball_list="-1" tricolette_list="-1" cafedetran_list="-1")
|
||||
pyramid(music_list="-1" item_list="-1" statue_0="0" statue_1="0" statue_2="0")
|
||||
reflec_collabo(collabo_phase="2" phase1_iidx_play="10" phase2_iidx_play="10" phase1_reflec_play="10" phase2_reflec_play="10" phase1_music_list="-1" phase2_music_list="-1" phase1_iidx_item="-1" phase2_iidx_item="-1" phase1_reflec_item="-1" phase2_reflec_item="-1")
|
||||
destiny_catharsis(music_bit="-1")
|
||||
bemani_summer_collabo(music_bit="-1")
|
||||
deller(deller=pcdata.deller rate="1")
|
||||
orb_data(rest_orb=pcdata.orb)
|
||||
time_sandglass(item_num="10")
|
||||
present_time_sandglass(item_num="10")
|
||||
sound_holic(music_list="-1" announce_list="-1")
|
||||
cc_collabo_music(music_list="-1")
|
||||
cc_collabo_data(customize_list="-1" new_get_customize="1" new_open_music="1" new_consume_drink="1")
|
||||
beatstream_collabo(music_list="-1")
|
||||
konami_stytle
|
||||
is_skip(__type="bool") 1
|
||||
floor_infection(music_list="-1")
|
||||
64
iidx@asphyxia/pug/LDJ/23pcget.pug
Normal file
64
iidx@asphyxia/pug/LDJ/23pcget.pug
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
IIDX23pc(status="0")
|
||||
pcdata(id=profile.id idstr=profile.idstr name=profile.name pid=profile.pid spnum=pcdata.spnum dpnum=pcdata.dpnum sach=pcdata.sach dach=pcdata.dach mode=pcdata.mode pmode=pcdata.pmode rtype=pcdata.rtype sp_opt=pcdata.sp_opt dp_opt=pcdata.dp_opt dp_opt2=pcdata.dp_opt2 gpos=pcdata.gpos s_sorttype=pcdata.s_sorttype d_sorttype=pcdata.d_sorttype s_pace=pcdata.s_pace d_pace=pcdata.d_pace s_gno=pcdata.s_gno d_gno=pcdata.d_gno s_gtype=pcdata.s_gtype d_gtype=pcdata.d_gtype s_sdlen=pcdata.s_sdlen d_sdlen=pcdata.d_sdlen s_sdtype=pcdata.s_sdtype d_sdtype=pcdata.d_sdtype s_timing=pcdata.s_timing d_timing=pcdata.d_timing s_notes=pcdata.s_notes d_notes=pcdata.d_notes s_judge=pcdata.s_judge d_judge=pcdata.d_judge s_judgeAdj=pcdata.s_judgeAdj d_judgeAdj=pcdata.d_judgeAdj s_hispeed=pcdata.s_hispeed d_hispeed=pcdata.d_hispeed s_liflen=pcdata.s_liflen d_liflen=pcdata.d_liflen s_disp_judge=pcdata.s_disp_judge d_disp_judge=pcdata.d_disp_judge s_opstyle=pcdata.s_opstyle d_opstyle=pcdata.d_opstyle s_exscore=pcdata.s_exscore d_exscore=pcdata.d_exscore s_largejudge=pcdata.s_largejudge d_largejudge=pcdata.d_largejudge)
|
||||
spdp_rival(flg="-1")
|
||||
bind_eaappli
|
||||
ea_premium_course
|
||||
secret
|
||||
flg1(__type="s64" __count="3") -1 -1 -1
|
||||
flg2(__type="s64" __count="3") -1 -1 -1
|
||||
flg3(__type="s64" __count="3") -1 -1 -1
|
||||
if pcdata.sp_mlist != null
|
||||
favorite
|
||||
sp_mlist(__type="bin") #{pcdata.sp_mlist}
|
||||
sp_clist(__type="bin") #{pcdata.sp_clist}
|
||||
dp_mlist(__type="bin") #{pcdata.dp_mlist}
|
||||
dp_clist(__type="bin") #{pcdata.dp_clist}
|
||||
- for (let ef of efArray)
|
||||
extra_favorite(folder_id=ef.folder_id)
|
||||
sp_mlist(__type="bin") #{ef.sp_mlist}
|
||||
sp_clist(__type="bin") #{ef.sp_clist}
|
||||
dp_mlist(__type="bin") #{ef.dp_mlist}
|
||||
dp_clist(__type="bin") #{ef.dp_clist}
|
||||
qpro_secret
|
||||
head(__type="s64" __count="4") -1 -1 -1 -1
|
||||
hair(__type="s64" __count="4") -1 -1 -1 -1
|
||||
face(__type="s64" __count="4") -1 -1 -1 -1
|
||||
body(__type="s64" __count="4") -1 -1 -1 -1
|
||||
hand(__type="s64" __count="4") -1 -1 -1 -1
|
||||
grade(sgid=pcdata.sgid dgid=pcdata.dgid)
|
||||
- for (let d of dArray)
|
||||
g(__type="u8" __count="4") #{d[0]} #{d[1]} #{d[2]} #{d[3]}
|
||||
skin(__type="s16" __count="14") #{custom.frame} #{custom.turntable} #{custom.note_burst} #{custom.menu_music} #{appendsettings} #{custom.lane_cover} 0 #{custom.category_vox} #{custom.note_skin} #{custom.full_combo_splash} 0 #{Number(custom.disable_musicpreview)} 0 0
|
||||
qprodata(__type="u32" __count="5") #{custom.qpro_head} #{custom.qpro_hair} #{custom.qpro_face} #{custom.qpro_hand} #{custom.qpro_body}
|
||||
rlist
|
||||
- for (let rd of rArray)
|
||||
rival(spdp=rd.play_style id=rd.profile[2] id_str=rd.profile[3] djname=rd.profile[0] pid=rd.profile[1] sg=rd.pcdata[0] dg=rd.pcdata[1] sa=rd.pcdata[2] da=rd.pcdata[3])
|
||||
stepdata(step_sach=rd.pcdata[4] step_dach=rd.pcdata[5])
|
||||
qprodata(body=rd.qprodata[3] face=rd.qprodata[2] hair=rd.qprodata[0] hand=rd.qprodata[4] head=rd.qprodata[1])
|
||||
shop(name=shop_data.opname)
|
||||
join_shop(joinflg="1" join_cflg="1" join_id="ea" join_name=shop_data.opname)
|
||||
visitor(anum="10" snum="10" pnum="10" vs_flg="1")
|
||||
if pcdata.st_tokimeki != null
|
||||
step(friendship=pcdata.st_friendship progress=pcdata.st_progress station_clear=pcdata.st_station_clear station_play=pcdata.st_station_play sp_mission=pcdata.st_sp_mission dp_mission=pcdata.st_dp_mission sp_level=pcdata.st_sp_level dp_level=pcdata.st_dp_level sp_mplay=pcdata.st_sp_mplay dp_mplay=pcdata.st_dp_mplay mission_gauge=pcdata.st_mission_gauge)
|
||||
tokimeki(__type="bin") #{pcdata.st_tokimeki}
|
||||
//-step_assist(iidx_id iidx_id_str name hair head face body hand)
|
||||
qpronicle_love(music_list="-1")
|
||||
achievements(pack=pcdata.achi_pack pack_comp=pcdata.achi_packcomp last_weekly=pcdata.achi_lastweekly weekly_num=pcdata.achi_weeklynum visit_flg=pcdata.achi_visitflg rival_crush=pcdata.achi_rivalcrush)
|
||||
trophy(__type="s64" __count="10") #{pcdata.achi_trophy[0]} #{pcdata.achi_trophy[1]} #{pcdata.achi_trophy[2]} #{pcdata.achi_trophy[3]} #{pcdata.achi_trophy[4]} #{pcdata.achi_trophy[5]} #{pcdata.achi_trophy[6]} #{pcdata.achi_trophy[7]} #{pcdata.achi_trophy[8]} #{pcdata.achi_trophy[9]}
|
||||
if open_tokotoko != null
|
||||
event1_data(point_map_0=open_tokotoko.point_map_0 point_map_1=open_tokotoko.point_map_1 point_map_2=open_tokotoko.point_map_2 point_map_3=open_tokotoko.point_map_3 point_map_4=open_tokotoko.point_map_4 last_map=open_tokotoko.last_map hold_point=open_tokotoko.hold_point rank_point=open_tokotoko.rank_point tips_list=open_tokotoko.tips_list gift_point="0")
|
||||
//-event1_assist(iidx_id iidx_id_str name hair head face body hand)
|
||||
if mystery_line != null
|
||||
event2_data(play_num=mystery_line.play_num now_area=mystery_line.now_stay_area now_note_grade=mystery_line.now_stay_note_grade stop_area_time=mystery_line.stop_area_time)
|
||||
- for (let evt of mystery_line_sub)
|
||||
event2_area_data(area_no=evt.area_no area_play=evt.area_play_num normal_point=evt.normal_point hyper_point=evt.hyper_point another_point=evt.another_point)
|
||||
//-onemore_data(defeat_0 defeat_1 defeat_2 defeat_3 defeat_4 defeat_5 challenge_num_n challenge_num_h challenge_num_a)
|
||||
reflec_collabo(phase1_music_list="-1" phase2_music_list="-1")
|
||||
destiny_catharsis(music_bit="-1")
|
||||
bemani_summer_collabo(music_bit="-1")
|
||||
deller(deller=pcdata.deller rate="1")
|
||||
orb_data(rest_orb=pcdata.orb)
|
||||
rainbow_ticket(item_num="10")
|
||||
beatstream_collabo(music_list="-1")
|
||||
floor_infection(music_list="-1")
|
||||
reflec_volzza_collabo(iidx_music_list="-1" reflec_music_list="-1")
|
||||
70
iidx@asphyxia/pug/LDJ/24pcget.pug
Normal file
70
iidx@asphyxia/pug/LDJ/24pcget.pug
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
IIDX24pc(status="0")
|
||||
pcdata(id=profile.id idstr=profile.idstr name=profile.name pid=profile.pid spnum=pcdata.spnum dpnum=pcdata.dpnum sach=pcdata.sach dach=pcdata.dach mode=pcdata.mode pmode=pcdata.pmode rtype=pcdata.rtype sp_opt=pcdata.sp_opt dp_opt=pcdata.dp_opt dp_opt2=pcdata.dp_opt2 gpos=pcdata.gpos s_sorttype=pcdata.s_sorttype d_sorttype=pcdata.d_sorttype s_pace=pcdata.s_pace d_pace=pcdata.d_pace s_gno=pcdata.s_gno d_gno=pcdata.d_gno s_gtype=pcdata.s_gtype d_gtype=pcdata.d_gtype s_sdlen=pcdata.s_sdlen d_sdlen=pcdata.d_sdlen s_sdtype=pcdata.s_sdtype d_sdtype=pcdata.d_sdtype s_timing=pcdata.s_timing d_timing=pcdata.d_timing s_notes=pcdata.s_notes d_notes=pcdata.d_notes s_judge=pcdata.s_judge d_judge=pcdata.d_judge s_judgeAdj=pcdata.s_judgeAdj d_judgeAdj=pcdata.d_judgeAdj s_hispeed=pcdata.s_hispeed d_hispeed=pcdata.d_hispeed s_liflen=pcdata.s_liflen d_liflen=pcdata.d_liflen s_disp_judge=pcdata.s_disp_judge d_disp_judge=pcdata.d_disp_judge s_opstyle=pcdata.s_opstyle d_opstyle=pcdata.d_opstyle s_exscore=pcdata.s_exscore d_exscore=pcdata.d_exscore s_graph_score=pcdata.s_graph_score d_graph_score=pcdata.d_graph_score)
|
||||
spdp_rival(flg="0")
|
||||
bind_eaappli
|
||||
ea_premium_course
|
||||
leggendaria_open
|
||||
secret
|
||||
flg1(__type="s64" __count="3") -1 -1 -1
|
||||
flg2(__type="s64" __count="3") -1 -1 -1
|
||||
flg3(__type="s64" __count="3") -1 -1 -1
|
||||
if pcdata.sp_mlist != null
|
||||
favorite
|
||||
sp_mlist(__type="bin") #{pcdata.sp_mlist}
|
||||
sp_clist(__type="bin") #{pcdata.sp_clist}
|
||||
dp_mlist(__type="bin") #{pcdata.dp_mlist}
|
||||
dp_clist(__type="bin") #{pcdata.dp_clist}
|
||||
- for (let ef of efArray)
|
||||
extra_favorite(folder_id=ef.folder_id)
|
||||
sp_mlist(__type="bin") #{ef.sp_mlist}
|
||||
sp_clist(__type="bin") #{ef.sp_clist}
|
||||
dp_mlist(__type="bin") #{ef.dp_mlist}
|
||||
dp_clist(__type="bin") #{ef.dp_clist}
|
||||
qpro_secret
|
||||
head(__type="s64" __count="4") -1 -1 -1 -1
|
||||
hair(__type="s64" __count="4") -1 -1 -1 -1
|
||||
face(__type="s64" __count="4") -1 -1 -1 -1
|
||||
body(__type="s64" __count="4") -1 -1 -1 -1
|
||||
hand(__type="s64" __count="4") -1 -1 -1 -1
|
||||
grade(sgid=pcdata.sgid dgid=pcdata.dgid)
|
||||
- for (let d of dArray)
|
||||
g(__type="u8" __count="4") #{d[0]} #{d[1]} #{d[2]} #{d[3]}
|
||||
skin(__type="s16" __count="17") #{custom.frame} #{custom.turntable} #{custom.note_burst} #{custom.menu_music} #{appendsettings} #{custom.lane_cover} 0 #{custom.category_vox} #{custom.note_skin} #{custom.full_combo_splash} 0 #{Number(custom.disable_musicpreview)} 0 0 0 0 0
|
||||
qprodata(__type="u32" __count="5") #{custom.qpro_head} #{custom.qpro_hair} #{custom.qpro_face} #{custom.qpro_hand} #{custom.qpro_body}
|
||||
rlist
|
||||
- for (let rd of rArray)
|
||||
rival(spdp=rd.play_style id=rd.profile[2] id_str=rd.profile[3] djname=rd.profile[0] pid=rd.profile[1] sg=rd.pcdata[0] dg=rd.pcdata[1] sa=rd.pcdata[2] da=rd.pcdata[3])
|
||||
stepdata(step_sach=rd.pcdata[4] step_dach=rd.pcdata[5])
|
||||
qprodata(body=rd.qprodata[3] face=rd.qprodata[2] hair=rd.qprodata[0] hand=rd.qprodata[4] head=rd.qprodata[1])
|
||||
shop(name=shop_data.opname)
|
||||
is_robo(__type="bool") 0
|
||||
ninja_rank(style="0")
|
||||
rank(__type="s32" __count="13") #{pcdata.dr_sprank[0]} #{pcdata.dr_sprank[1]} #{pcdata.dr_sprank[2]} #{pcdata.dr_sprank[3]} #{pcdata.dr_sprank[4]} #{pcdata.dr_sprank[5]} #{pcdata.dr_sprank[6]} #{pcdata.dr_sprank[7]} #{pcdata.dr_sprank[8]} #{pcdata.dr_sprank[9]} #{pcdata.dr_sprank[10]} #{pcdata.dr_sprank[11]} #{pcdata.dr_sprank[12]}
|
||||
point(__type="s32" __count="13") #{pcdata.dr_sppoint[0]} #{pcdata.dr_sppoint[1]} #{pcdata.dr_sppoint[2]} #{pcdata.dr_sppoint[3]} #{pcdata.dr_sppoint[4]} #{pcdata.dr_sppoint[5]} #{pcdata.dr_sppoint[6]} #{pcdata.dr_sppoint[7]} #{pcdata.dr_sppoint[8]} #{pcdata.dr_sppoint[9]} #{pcdata.dr_sppoint[10]} #{pcdata.dr_sppoint[11]} #{pcdata.dr_sppoint[12]}
|
||||
ninja_rank(style="1")
|
||||
rank(__type="s32" __count="13") #{pcdata.dr_dprank[0]} #{pcdata.dr_dprank[1]} #{pcdata.dr_dprank[2]} #{pcdata.dr_dprank[3]} #{pcdata.dr_dprank[4]} #{pcdata.dr_dprank[5]} #{pcdata.dr_dprank[6]} #{pcdata.dr_dprank[7]} #{pcdata.dr_dprank[8]} #{pcdata.dr_dprank[9]} #{pcdata.dr_dprank[10]} #{pcdata.dr_dprank[11]} #{pcdata.dr_dprank[12]}
|
||||
point(__type="s32" __count="13") #{pcdata.dr_dppoint[0]} #{pcdata.dr_dppoint[1]} #{pcdata.dr_dppoint[2]} #{pcdata.dr_dppoint[3]} #{pcdata.dr_dppoint[4]} #{pcdata.dr_dppoint[5]} #{pcdata.dr_dppoint[6]} #{pcdata.dr_dppoint[7]} #{pcdata.dr_dppoint[8]} #{pcdata.dr_dppoint[9]} #{pcdata.dr_dppoint[10]} #{pcdata.dr_dppoint[11]} #{pcdata.dr_dppoint[12]}
|
||||
if siege_sinobuz != null
|
||||
event1(last_select_map=siege_sinobuz.last_select_map hold_rice=siege_sinobuz.hold_rice tax_rice=siege_sinobuz.tax_rice tips_list=siege_sinobuz.tipls_read)
|
||||
- for (let evt of siege_sinobuz_sub)
|
||||
map_data(map_id=evt.map_id play_num=evt.play_num progress=evt.progress battle_point=evt.battle_point rice_point=evt.rice_point is_clear=evt.is_clear)
|
||||
ninjyutsu(__type="bin") #{evt.ninjyutsu}
|
||||
map_card_damage(__type="bin") #{evt.card_damage}
|
||||
map_card_clear(__type="bin") #{evt.card_clear}
|
||||
if ninja_shichikyoden != null
|
||||
event2(play_num=ninja_shichikyoden.play_num chakra_point=ninja_shichikyoden.chakra_point last_select_ryuha=ninja_shichikyoden.last_select_ryuha)
|
||||
last_select_dojo(__type="bin") #{ninja_shichikyoden.last_select_dojo}
|
||||
enemy_damage(__type="bin") #{ninja_shichikyoden.enemy_damage}
|
||||
//-onemore_data(defeat_0 defeat_1 defeat_2 defeat_3 defeat_4 defeat_5 defeat_6 challenge_num_n challenge_num_h challenge_num_a)
|
||||
join_shop(joinflg="1" join_cflg="1" join_id="ea" join_name=shop_data.opname)
|
||||
visitor(anum="10" snum="10" pnum="10" vs_flg="1")
|
||||
step(enemy_damage=pcdata.st_enemy_damage progress=pcdata.st_progress enemy_defeat_flg=pcdata.st_enemy_defeat_flg sp_level=pcdata.st_sp_level dp_level=pcdata.st_dp_level sp_mplay=pcdata.st_sp_mplay dp_mplay=pcdata.st_dp_mplay)
|
||||
achievements(pack=pcdata.achi_pack pack_comp=pcdata.achi_packcomp last_weekly=pcdata.achi_lastweekly weekly_num=pcdata.achi_weeklynum visit_flg=pcdata.achi_visitflg rival_crush=pcdata.achi_rivalcrush)
|
||||
trophy(__type="s64" __count="10") #{pcdata.achi_trophy[0]} #{pcdata.achi_trophy[1]} #{pcdata.achi_trophy[2]} #{pcdata.achi_trophy[3]} #{pcdata.achi_trophy[4]} #{pcdata.achi_trophy[5]} #{pcdata.achi_trophy[6]} #{pcdata.achi_trophy[7]} #{pcdata.achi_trophy[8]} #{pcdata.achi_trophy[9]}
|
||||
deller(deller=pcdata.deller rate="1")
|
||||
orb_data(rest_orb=pcdata.orb)
|
||||
pay_per_use(item_num="5")
|
||||
present_pay_per_use(item_num="5")
|
||||
old_linkage_secret_flg(bemani_diary="-1" floor_infection="-1" beatstream="-1" destiny_catharsis="-1" reflec_gw="-1" link_track="-1" qpronicle_love="-1")
|
||||
nostalgia_open
|
||||
konami_stytle(skip_flg="0")
|
||||
70
iidx@asphyxia/pug/LDJ/25pcget.pug
Normal file
70
iidx@asphyxia/pug/LDJ/25pcget.pug
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
IIDX25pc(status="0")
|
||||
pcdata(id=profile.id idstr=profile.idstr name=profile.name pid=profile.pid spnum=pcdata.spnum dpnum=pcdata.dpnum sach=pcdata.sach dach=pcdata.dach mode=pcdata.mode pmode=pcdata.pmode rtype=pcdata.rtype sp_opt=pcdata.sp_opt dp_opt=pcdata.dp_opt dp_opt2=pcdata.dp_opt2 gpos=pcdata.gpos s_sorttype=pcdata.s_sorttype d_sorttype=pcdata.d_sorttype s_pace=pcdata.s_pace d_pace=pcdata.d_pace s_gno=pcdata.s_gno d_gno=pcdata.d_gno s_gtype=pcdata.s_gtype d_gtype=pcdata.d_gtype s_sdlen=pcdata.s_sdlen d_sdlen=pcdata.d_sdlen s_sdtype=pcdata.s_sdtype d_sdtype=pcdata.d_sdtype s_timing=pcdata.s_timing d_timing=pcdata.d_timing s_notes=pcdata.s_notes d_notes=pcdata.d_notes s_judge=pcdata.s_judge d_judge=pcdata.d_judge s_judgeAdj=pcdata.s_judgeAdj d_judgeAdj=pcdata.d_judgeAdj s_hispeed=pcdata.s_hispeed d_hispeed=pcdata.d_hispeed s_liflen=pcdata.s_liflen d_liflen=pcdata.d_liflen s_disp_judge=pcdata.s_disp_judge d_disp_judge=pcdata.d_disp_judge s_opstyle=pcdata.s_opstyle d_opstyle=pcdata.d_opstyle s_exscore=pcdata.s_exscore d_exscore=pcdata.d_exscore s_graph_score=pcdata.s_graph_score d_graph_score=pcdata.d_graph_score s_auto_scrach=pcdata.s_auto_scrach d_auto_scrach=pcdata.d_auto_scrach s_gauge_disp=pcdata.s_gauge_disp d_gauge_disp=pcdata.d_gauge_disp s_lane_brignt=pcdata.s_lane_brignt d_lane_brignt=pcdata.d_lane_brignt s_camera_layout=pcdata.s_camera_layout d_camera_layout=pcdata.d_camera_layout)
|
||||
spdp_rival(flg="0")
|
||||
bind_eaappli
|
||||
ea_premium_course
|
||||
leggendaria_open
|
||||
secret
|
||||
flg1(__type="s64" __count="3") -1 -1 -1
|
||||
flg2(__type="s64" __count="3") -1 -1 -1
|
||||
flg3(__type="s64" __count="3") -1 -1 -1
|
||||
if pcdata.sp_mlist != null
|
||||
favorite
|
||||
sp_mlist(__type="bin") #{pcdata.sp_mlist}
|
||||
sp_clist(__type="bin") #{pcdata.sp_clist}
|
||||
dp_mlist(__type="bin") #{pcdata.dp_mlist}
|
||||
dp_clist(__type="bin") #{pcdata.dp_clist}
|
||||
- for (let ef of efArray)
|
||||
extra_favorite(folder_id=ef.folder_id)
|
||||
sp_mlist(__type="bin") #{ef.sp_mlist}
|
||||
sp_clist(__type="bin") #{ef.sp_clist}
|
||||
dp_mlist(__type="bin") #{ef.dp_mlist}
|
||||
dp_clist(__type="bin") #{ef.dp_clist}
|
||||
qpro_secret
|
||||
head(__type="s64" __count="4") -1 -1 -1 -1
|
||||
hair(__type="s64" __count="4") -1 -1 -1 -1
|
||||
face(__type="s64" __count="4") -1 -1 -1 -1
|
||||
body(__type="s64" __count="4") -1 -1 -1 -1
|
||||
hand(__type="s64" __count="4") -1 -1 -1 -1
|
||||
grade(sgid=pcdata.sgid dgid=pcdata.dgid)
|
||||
- for (let d of dArray)
|
||||
g(__type="u8" __count="4") #{d[0]} #{d[1]} #{d[2]} #{d[3]}
|
||||
skin(__type="s16" __count="14") #{custom.frame} #{custom.turntable} #{custom.note_burst} #{custom.menu_music} #{appendsettings} #{custom.lane_cover} 0 #{custom.category_vox} #{custom.note_skin} #{custom.full_combo_splash} 0 #{Number(custom.disable_musicpreview)} 0 0
|
||||
qprodata(__type="u32" __count="5") #{custom.qpro_head} #{custom.qpro_hair} #{custom.qpro_face} #{custom.qpro_hand} #{custom.qpro_body}
|
||||
rlist
|
||||
- for (let rd of rArray)
|
||||
rival(spdp=rd.play_style id=rd.profile[2] id_str=rd.profile[3] djname=rd.profile[0] pid=rd.profile[1] sg=rd.pcdata[0] dg=rd.pcdata[1] sa=rd.pcdata[2] da=rd.pcdata[3])
|
||||
stepdata(step_sach=rd.pcdata[4] step_dach=rd.pcdata[5])
|
||||
qprodata(body=rd.qprodata[3] face=rd.qprodata[2] hair=rd.qprodata[0] hand=rd.qprodata[4] head=rd.qprodata[1])
|
||||
shop(name=shop_data.opname)
|
||||
is_robo(__type="bool") 0
|
||||
dj_rank(style="0")
|
||||
rank(__type="s32" __count="15") #{pcdata.dr_sprank[0]} #{pcdata.dr_sprank[1]} #{pcdata.dr_sprank[2]} #{pcdata.dr_sprank[3]} #{pcdata.dr_sprank[4]} #{pcdata.dr_sprank[5]} #{pcdata.dr_sprank[6]} #{pcdata.dr_sprank[7]} #{pcdata.dr_sprank[8]} #{pcdata.dr_sprank[9]} #{pcdata.dr_sprank[10]} #{pcdata.dr_sprank[11]} #{pcdata.dr_sprank[12]} #{pcdata.dr_sprank[13]} #{pcdata.dr_sprank[14]}
|
||||
point(__type="s32" __count="15") #{pcdata.dr_sppoint[0]} #{pcdata.dr_sppoint[1]} #{pcdata.dr_sppoint[2]} #{pcdata.dr_sppoint[3]} #{pcdata.dr_sppoint[4]} #{pcdata.dr_sppoint[5]} #{pcdata.dr_sppoint[6]} #{pcdata.dr_sppoint[7]} #{pcdata.dr_sppoint[8]} #{pcdata.dr_sppoint[9]} #{pcdata.dr_sppoint[10]} #{pcdata.dr_sppoint[11]} #{pcdata.dr_sppoint[12]} #{pcdata.dr_sppoint[13]} #{pcdata.dr_sppoint[14]}
|
||||
dj_rank(style="1")
|
||||
rank(__type="s32" __count="15") #{pcdata.dr_dprank[0]} #{pcdata.dr_dprank[1]} #{pcdata.dr_dprank[2]} #{pcdata.dr_dprank[3]} #{pcdata.dr_dprank[4]} #{pcdata.dr_dprank[5]} #{pcdata.dr_dprank[6]} #{pcdata.dr_dprank[7]} #{pcdata.dr_dprank[8]} #{pcdata.dr_dprank[9]} #{pcdata.dr_dprank[10]} #{pcdata.dr_dprank[11]} #{pcdata.dr_dprank[12]} #{pcdata.dr_dprank[13]} #{pcdata.dr_dprank[14]}
|
||||
point(__type="s32" __count="15") #{pcdata.dr_dppoint[0]} #{pcdata.dr_dppoint[1]} #{pcdata.dr_dppoint[2]} #{pcdata.dr_dppoint[3]} #{pcdata.dr_dppoint[4]} #{pcdata.dr_dppoint[5]} #{pcdata.dr_dppoint[6]} #{pcdata.dr_dppoint[7]} #{pcdata.dr_dppoint[8]} #{pcdata.dr_dppoint[9]} #{pcdata.dr_dppoint[10]} #{pcdata.dr_dppoint[11]} #{pcdata.dr_dppoint[12]} #{pcdata.dr_dppoint[13]} #{pcdata.dr_dppoint[14]}
|
||||
//-onemore_event(defeat_0-5 channelge_num_1-3_n-a)
|
||||
join_shop(joinflg="1" join_cflg="1" join_id="ea" join_name=shop_data.opname)
|
||||
visitor(anum="10" snum="10" pnum="10" vs_flg="1")
|
||||
step(enemy_damage=pcdata.st_enemy_damage progress=pcdata.st_progress point=pcdata.st_point enemy_defeat_flg=pcdata.st_enemy_defeat_flg sp_level=pcdata.st_sp_level dp_level=pcdata.st_dp_level sp_mplay=pcdata.st_sp_mplay dp_mplay=pcdata.st_dp_mplay)
|
||||
achievements(pack=pcdata.achi_pack pack_comp=pcdata.achi_packcomp last_weekly=pcdata.achi_lastweekly weekly_num=pcdata.achi_weeklynum visit_flg=pcdata.achi_visitflg rival_crush=pcdata.achi_rivalcrush)
|
||||
trophy(__type="s64" __count="10") #{pcdata.achi_trophy[0]} #{pcdata.achi_trophy[1]} #{pcdata.achi_trophy[2]} #{pcdata.achi_trophy[3]} #{pcdata.achi_trophy[4]} #{pcdata.achi_trophy[5]} #{pcdata.achi_trophy[6]} #{pcdata.achi_trophy[7]} #{pcdata.achi_trophy[8]} #{pcdata.achi_trophy[9]}
|
||||
deller(deller=pcdata.deller rate="1")
|
||||
orb_data(rest_orb=pcdata.orb)
|
||||
pay_per_use(item_num="5")
|
||||
present_pay_per_use(item_num="5")
|
||||
old_linkage_secret_flg(floor_infection="-1" link_track="-1")
|
||||
nostalgia_open
|
||||
leggendaria_semi_open(flg="-1")
|
||||
konami_stytle(skip_flg="0")
|
||||
if rush_cannonracer != null
|
||||
event1(tuneup_point=rush_cannonracer.tuneup_point body_parts_list=rush_cannonracer.body_parts_list engine_parts_list=rush_cannonracer.engine_parts_list tire_parts_list=rush_cannonracer.tire_parts_list body_equip_parts=rush_cannonracer.body_equip_parts engine_equip_parts=rush_cannonracer.engine_equip_parts tire_equip_parts=rush_cannonracer.tire_equip_parts gift_point="0")
|
||||
- for (let evt of rush_cannonracer_sub)
|
||||
map_data(map_id=evt.map_id play_num=evt.play_num progress=evt.progress boost_fuel=evt.boost_fuel is_clear=evt.is_clear rare1_appearance=evt.rare1_appearance rare2_appearance=evt.rare2_appearance rare3_appearance=evt.rare3_appearance rare4_appearance=evt.rare4_appearance rare5_appearance=evt.rare5_appearance rare6_appearance=evt.rare6_appearance rare_defeat_list=evt.rare_defeat_list)
|
||||
arena_data(play_num="2" play_num_dp="1" play_num_sp="1")
|
||||
achieve_data(arena_class="20" best_top_class_continuing="0" now_top_class_continuing="0" play_style="0" rating_value="20")
|
||||
achieve_data(arena_class="20" best_top_class_continuing="0" now_top_class_continuing="0" play_style="1" rating_value="20")
|
||||
cube_data(cube="0" season_id="0")
|
||||
floor_infection(music_list="-1")
|
||||
qma_collabo(music_list="-1")
|
||||
83
iidx@asphyxia/pug/LDJ/26pcget.pug
Normal file
83
iidx@asphyxia/pug/LDJ/26pcget.pug
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
IIDX26pc(status="0")
|
||||
pcdata(id=profile.id idstr=profile.idstr name=profile.name pid=profile.pid spnum=pcdata.spnum dpnum=pcdata.dpnum sach=pcdata.sach dach=pcdata.dach mode=pcdata.mode pmode=pcdata.pmode rtype=pcdata.rtype sp_opt=pcdata.sp_opt dp_opt=pcdata.dp_opt dp_opt2=pcdata.dp_opt2 gpos=pcdata.gpos s_sorttype=pcdata.s_sorttype d_sorttype=pcdata.d_sorttype s_pace=pcdata.s_pace d_pace=pcdata.d_pace s_gno=pcdata.s_gno d_gno=pcdata.d_gno s_gtype=pcdata.s_gtype d_gtype=pcdata.d_gtype s_sdlen=pcdata.s_sdlen d_sdlen=pcdata.d_sdlen s_sdtype=pcdata.s_sdtype d_sdtype=pcdata.d_sdtype s_timing=pcdata.s_timing d_timing=pcdata.d_timing s_notes=pcdata.s_notes d_notes=pcdata.d_notes s_judge=pcdata.s_judge d_judge=pcdata.d_judge s_judgeAdj=pcdata.s_judgeAdj d_judgeAdj=pcdata.d_judgeAdj s_hispeed=pcdata.s_hispeed d_hispeed=pcdata.d_hispeed s_liflen=pcdata.s_liflen d_liflen=pcdata.d_liflen s_disp_judge=pcdata.s_disp_judge d_disp_judge=pcdata.d_disp_judge s_opstyle=pcdata.s_opstyle d_opstyle=pcdata.d_opstyle s_graph_score=pcdata.s_graph_score d_graph_score=pcdata.d_graph_score s_auto_scrach=pcdata.s_auto_scrach d_auto_scrach=pcdata.d_auto_scrach s_gauge_disp=pcdata.s_gauge_disp d_gauge_disp=pcdata.d_gauge_disp s_lane_brignt=pcdata.s_lane_brignt d_lane_brignt=pcdata.d_lane_brignt s_camera_layout=pcdata.s_camera_layout d_camera_layout=pcdata.d_camera_layout s_ghost_score=pcdata.s_ghost_score d_ghost_score=pcdata.d_ghost_score s_tsujigiri_disp=pcdata.s_tsujigiri_disp d_tsujigiri_disp=pcdata.d_tsujigiri_disp)
|
||||
bind_eaappli
|
||||
ea_premium_course
|
||||
enable_qr_reward
|
||||
leggendaria_open
|
||||
secret
|
||||
flg1(__type="s64" __count="3") -1 -1 -1
|
||||
flg2(__type="s64" __count="3") -1 -1 -1
|
||||
flg3(__type="s64" __count="3") -1 -1 -1
|
||||
flg4(__type="s64" __count="3") -1 -1 -1
|
||||
if pcdata.sp_mlist != null
|
||||
favorite
|
||||
sp_mlist(__type="bin") #{pcdata.sp_mlist}
|
||||
sp_clist(__type="bin") #{pcdata.sp_clist}
|
||||
dp_mlist(__type="bin") #{pcdata.dp_mlist}
|
||||
dp_clist(__type="bin") #{pcdata.dp_clist}
|
||||
qpro_secret
|
||||
head(__type="s64" __count="4") -1 -1 -1 -1
|
||||
hair(__type="s64" __count="4") -1 -1 -1 -1
|
||||
face(__type="s64" __count="4") -1 -1 -1 -1
|
||||
body(__type="s64" __count="4") -1 -1 -1 -1
|
||||
hand(__type="s64" __count="4") -1 -1 -1 -1
|
||||
grade(sgid=pcdata.sgid dgid=pcdata.dgid)
|
||||
- for (let d of dArray)
|
||||
g(__type="u8" __count="4") #{d[0]} #{d[1]} #{d[2]} #{d[3]}
|
||||
skin(__type="s16" __count="14") #{custom.frame} #{custom.turntable} #{custom.note_burst} #{custom.menu_music} #{appendsettings} #{custom.lane_cover} 0 #{custom.category_vox} #{custom.note_skin} #{custom.full_combo_splash} 0 #{Number(custom.disable_musicpreview)} 0 0
|
||||
qprodata(__type="u32" __count="5") #{custom.qpro_head} #{custom.qpro_hair} #{custom.qpro_face} #{custom.qpro_hand} #{custom.qpro_body}
|
||||
rlist
|
||||
- for (let rd of rArray)
|
||||
rival(spdp=rd.play_style id=rd.profile[2] id_str=rd.profile[3] djname=rd.profile[0] pid=rd.profile[1] sg=rd.pcdata[0] dg=rd.pcdata[1] sa=rd.pcdata[2] da=rd.pcdata[3])
|
||||
stepdata(step_sach=rd.pcdata[4] step_dach=rd.pcdata[5])
|
||||
qprodata(body=rd.qprodata[3] face=rd.qprodata[2] hair=rd.qprodata[0] hand=rd.qprodata[4] head=rd.qprodata[1])
|
||||
shop(name=shop_data.opname)
|
||||
is_robo(__type="bool") 0
|
||||
dj_rank(style="0")
|
||||
rank(__type="s32" __count="15") #{pcdata.dr_sprank[0]} #{pcdata.dr_sprank[1]} #{pcdata.dr_sprank[2]} #{pcdata.dr_sprank[3]} #{pcdata.dr_sprank[4]} #{pcdata.dr_sprank[5]} #{pcdata.dr_sprank[6]} #{pcdata.dr_sprank[7]} #{pcdata.dr_sprank[8]} #{pcdata.dr_sprank[9]} #{pcdata.dr_sprank[10]} #{pcdata.dr_sprank[11]} #{pcdata.dr_sprank[12]} #{pcdata.dr_sprank[13]} #{pcdata.dr_sprank[14]}
|
||||
point(__type="s32" __count="15") #{pcdata.dr_sppoint[0]} #{pcdata.dr_sppoint[1]} #{pcdata.dr_sppoint[2]} #{pcdata.dr_sppoint[3]} #{pcdata.dr_sppoint[4]} #{pcdata.dr_sppoint[5]} #{pcdata.dr_sppoint[6]} #{pcdata.dr_sppoint[7]} #{pcdata.dr_sppoint[8]} #{pcdata.dr_sppoint[9]} #{pcdata.dr_sppoint[10]} #{pcdata.dr_sppoint[11]} #{pcdata.dr_sppoint[12]} #{pcdata.dr_sppoint[13]} #{pcdata.dr_sppoint[14]}
|
||||
dj_rank(style="1")
|
||||
rank(__type="s32" __count="15") #{pcdata.dr_dprank[0]} #{pcdata.dr_dprank[1]} #{pcdata.dr_dprank[2]} #{pcdata.dr_dprank[3]} #{pcdata.dr_dprank[4]} #{pcdata.dr_dprank[5]} #{pcdata.dr_dprank[6]} #{pcdata.dr_dprank[7]} #{pcdata.dr_dprank[8]} #{pcdata.dr_dprank[9]} #{pcdata.dr_dprank[10]} #{pcdata.dr_dprank[11]} #{pcdata.dr_dprank[12]} #{pcdata.dr_dprank[13]} #{pcdata.dr_dprank[14]}
|
||||
point(__type="s32" __count="15") #{pcdata.dr_dppoint[0]} #{pcdata.dr_dppoint[1]} #{pcdata.dr_dppoint[2]} #{pcdata.dr_dppoint[3]} #{pcdata.dr_dppoint[4]} #{pcdata.dr_dppoint[5]} #{pcdata.dr_dppoint[6]} #{pcdata.dr_dppoint[7]} #{pcdata.dr_dppoint[8]} #{pcdata.dr_dppoint[9]} #{pcdata.dr_dppoint[10]} #{pcdata.dr_dppoint[11]} #{pcdata.dr_dppoint[12]} #{pcdata.dr_dppoint[13]} #{pcdata.dr_dppoint[14]}
|
||||
extra_boss_event(orb_0=pcdata.eb_bossorb0 orb_1=pcdata.eb_bossorb1 orb_2=pcdata.eb_bossorb2 orb_3=pcdata.eb_bossorb3 orb_4=pcdata.eb_bossorb4 orb_5=pcdata.eb_bossorb5 orb_6=pcdata.eb_bossorb6 orb_7=pcdata.eb_bossorb7 orb_8=pcdata.eb_bossorb8)
|
||||
join_shop(joinflg="1" join_cflg="1" join_id="ea" join_name=shop_data.opname)
|
||||
visitor(anum="10" snum="10" pnum="10" vs_flg="1")
|
||||
step(enemy_damage=pcdata.st_enemy_damage progress=pcdata.st_progress sp_level=pcdata.st_sp_level dp_level=pcdata.st_dp_level sp_mission_point=pcdata.st_sp_mission_point dp_mission_point=pcdata.st_dp_mission_point sp_dj_mission_level=pcdata.st_sp_dj_mission_level dp_dj_mission_level=pcdata.st_dp_dj_mission_level sp_clear_mission_level=pcdata.st_sp_clear_mission_level dp_clear_mission_level=pcdata.st_dp_clear_mission_level sp_dj_mission_clear=pcdata.st_sp_dj_mission_clear dp_dj_mission_clear=pcdata.st_dp_dj_mission_clear sp_clear_mission_clear=pcdata.st_sp_clear_mission_clear dp_clear_mission_clear=pcdata.st_dp_clear_mission_clear sp_mplay=pcdata.st_sp_mplay dp_mplay=pcdata.st_dp_mplay tips_read_list=pcdata.st_tips_read_list)
|
||||
is_track_ticket(__type="bool") #{pcdata.st_is_track_ticket}
|
||||
achievements(pack=pcdata.achi_pack pack_comp=pcdata.achi_packcomp last_weekly=pcdata.achi_lastweekly weekly_num=pcdata.achi_weeklynum visit_flg=pcdata.achi_visitflg rival_crush=pcdata.achi_rivalcrush)
|
||||
trophy(__type="s64" __count="20") #{pcdata.achi_trophy[0]} #{pcdata.achi_trophy[1]} #{pcdata.achi_trophy[2]} #{pcdata.achi_trophy[3]} #{pcdata.achi_trophy[4]} #{pcdata.achi_trophy[5]} #{pcdata.achi_trophy[6]} #{pcdata.achi_trophy[7]} #{pcdata.achi_trophy[8]} #{pcdata.achi_trophy[9]} #{pcdata.achi_trophy[10]} #{pcdata.achi_trophy[11]} #{pcdata.achi_trophy[12]} #{pcdata.achi_trophy[13]} #{pcdata.achi_trophy[14]} #{pcdata.achi_trophy[15]} #{pcdata.achi_trophy[16]} #{pcdata.achi_trophy[17]} #{pcdata.achi_trophy[18]} #{pcdata.achi_trophy[19]}
|
||||
deller(deller=pcdata.deller rate="1")
|
||||
orb_data(rest_orb=pcdata.orb present_orb=pcdata.present_orb)
|
||||
pay_per_use_item(item_num="5")
|
||||
present_pay_per_use_item(item_num="5")
|
||||
qpro_ticket(ticket_num="10" total_ticket_num="10")
|
||||
old_linkage_secret_flg(floor_infection="-1" floor_infection2="-1" qma_collabo_music="-1")
|
||||
is_nostalgia(__type="bool") 1
|
||||
is_kac(__type="bool") 1
|
||||
leggendaria_semi_open(flg="-1")
|
||||
konami_stytle(skip_flg="0")
|
||||
arena_data(play_num="2" play_num_dp="1" play_num_sp="1")
|
||||
achieve_data(arena_class="20" best_top_class_continuing="0" now_top_class_continuing="0" play_style="0" rating_value="20")
|
||||
achieve_data(arena_class="20" best_top_class_continuing="0" now_top_class_continuing="0" play_style="1" rating_value="20")
|
||||
cube_data(cube="0" season_id="0")
|
||||
chat_data(chat_type_0="CHAT CUSTOM 1" chat_type_1="CHAT CUSTOM 2" chat_type_2="CHAT CUSTOM 3" chat_type_3="CHAT CUSTOM 4")
|
||||
is_chat_0(__type="bool") 1
|
||||
is_chat_1(__type="bool") 1
|
||||
is_chat_2(__type="bool") 1
|
||||
is_chat_3(__type="bool") 1
|
||||
skin_customize_flg(skin_frame_flg="-1" skin_bgm_flg="-1")
|
||||
if mirage_lib != null
|
||||
event1(event_play_num=pcdata.event_play_num fragment_num=mirage_lib.fragment_num last_select_map_id=mirage_lib.last_select_map_id read_tips_list=mirage_lib.read_tips_list continuous_correct=mirage_lib.continuous_correct bookshelf_release_num=mirage_lib.bookshelf_release_num)
|
||||
quiz_control_list(__type="bin") #{mirage_lib.quiz_control_list}
|
||||
- for (let evt of mirage_lib_sub)
|
||||
map_data(map_id=evt.map_id play_num=evt.play_num last_select_route_id=evt.last_select_route_id bookshelf_release_num=evt.bookshelf_release_num)
|
||||
map_route_damage(__type="bin") #{evt.map_route_damage}
|
||||
is_clear(__type="bool") #{evt.is_clear}
|
||||
if delabity_lab != null
|
||||
event2(play_num=delabity_lab.play_num last_select_floor=delabity_lab.last_select_floor delabity=delabity_lab.delabity tips_list=delabity_lab.tips_list floor_clear_flg_list=delabity_lab.floor_clear_flg_list floor_0_last_area=delabity_lab.floor_0_last_area floor_1_last_area=delabity_lab.floor_1_last_area floor_2_last_area=delabity_lab.floor_2_last_area floor_3_last_area=delabity_lab.floor_3_last_area floor_4_last_area=delabity_lab.floor_4_last_area)
|
||||
- for (let evt of delabity_lab_sub)
|
||||
area_data(floor_id=evt.floor_id area_id=evt.area_id last_select_note=evt.last_select_note normal_play_num=evt.normal_play_num hyper_play_num=evt.hyper_play_num another_play_num=evt.another_play_num area_clear_flg_list=evt.area_clear_flg_list normal_grade_point=evt.normal_grade_point hyper_grade_point=evt.hyper_grade_point another_grade_point=evt.another_grade_point)
|
||||
floor_infection3(music_list="-1")
|
||||
if anniv20 != null
|
||||
anniv20_event(damage_0=anniv20.damage_0 damage_1=anniv20.damage_1 damage_2=anniv20.damage_2 challenge_0=anniv20.challenge_0 challenge_1=anniv20.challenge_1 challenge_2=anniv20.challenge_2)
|
||||
bemani_vote(music_list="-1")
|
||||
79
iidx@asphyxia/pug/LDJ/27pcget.pug
Normal file
79
iidx@asphyxia/pug/LDJ/27pcget.pug
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
IIDX27pc(status="0")
|
||||
pcdata(id=profile.id idstr=profile.idstr name=profile.name pid=profile.pid spnum=pcdata.spnum dpnum=pcdata.dpnum sach=pcdata.sach dach=pcdata.dach mode=pcdata.mode pmode=pcdata.pmode rtype=pcdata.rtype sp_opt=pcdata.sp_opt dp_opt=pcdata.dp_opt dp_opt2=pcdata.dp_opt2 gpos=pcdata.gpos s_sorttype=pcdata.s_sorttype d_sorttype=pcdata.d_sorttype s_pace=pcdata.s_pace d_pace=pcdata.d_pace s_gno=pcdata.s_gno d_gno=pcdata.d_gno s_sub_gno=pcdata.s_sub_gno d_sub_gno=pcdata.d_sub_gno s_gtype=pcdata.s_gtype d_gtype=pcdata.d_gtype s_sdlen=pcdata.s_sdlen d_sdlen=pcdata.d_sdlen s_sdtype=pcdata.s_sdtype d_sdtype=pcdata.d_sdtype s_timing=pcdata.s_timing d_timing=pcdata.d_timing s_notes=pcdata.s_notes d_notes=pcdata.d_notes s_judge=pcdata.s_judge d_judge=pcdata.d_judge s_judgeAdj=pcdata.s_judgeAdj d_judgeAdj=pcdata.d_judgeAdj s_hispeed=pcdata.s_hispeed d_hispeed=pcdata.d_hispeed s_liflen=pcdata.s_liflen d_liflen=pcdata.d_liflen s_disp_judge=pcdata.s_disp_judge d_disp_judge=pcdata.d_disp_judge s_opstyle=pcdata.s_opstyle d_opstyle=pcdata.d_opstyle s_graph_score=pcdata.s_graph_score d_graph_score=pcdata.d_graph_score s_auto_scrach=pcdata.s_auto_scrach d_auto_scrach=pcdata.d_auto_scrach s_gauge_disp=pcdata.s_gauge_disp d_gauge_disp=pcdata.d_gauge_disp s_lane_brignt=pcdata.s_lane_brignt d_lane_brignt=pcdata.d_lane_brignt s_camera_layout=pcdata.s_camera_layout d_camera_layout=pcdata.d_camera_layout s_ghost_score=pcdata.s_ghost_score d_ghost_score=pcdata.d_ghost_score s_tsujigiri_disp=pcdata.s_tsujigiri_disp d_tsujigiri_disp=pcdata.d_tsujigiri_disp)
|
||||
lightning_play_data(dpnum=lm_playdata.dp_num spnum=lm_playdata.sp_num)
|
||||
lightning_setting(headphone_vol=lm_settings.headphone_vol resistance_dp_left=lm_settings.resistance_dp_left resistance_dp_right=lm_settings.resistance_dp_right resistance_sp_left=lm_settings.resistance_sp_left resistance_sp_right=lm_settings.resistance_sp_right)
|
||||
slider(__type="s32" __count="7") #{lm_settings.slider[0]} #{lm_settings.slider[1]} #{lm_settings.slider[2]} #{lm_settings.slider[3]} #{lm_settings.slider[4]} #{lm_settings.slider[5]} #{lm_settings.slider[6]}
|
||||
light(__type="bool" __count="6") #{lm_settings.light[0]} #{lm_settings.light[1]} #{lm_settings.light[2]} #{lm_settings.light[3]} #{lm_settings.light[4]} #{lm_settings.light[5]}
|
||||
concentration(__type="bool") #{lm_settings.concentration}
|
||||
bind_eaappli
|
||||
ea_premium_course
|
||||
enable_qr_reward
|
||||
leggendaria_open
|
||||
qpro_secret
|
||||
head(__type="s64" __count="7") #{custom.qpro_secret_head[0]} #{custom.qpro_secret_head[1]} #{custom.qpro_secret_head[2]} #{custom.qpro_secret_head[3]} #{custom.qpro_secret_head[4]} #{custom.qpro_secret_head[5]} #{custom.qpro_secret_head[6]}
|
||||
hair(__type="s64" __count="7") #{custom.qpro_secret_hair[0]} #{custom.qpro_secret_hair[1]} #{custom.qpro_secret_hair[2]} #{custom.qpro_secret_hair[3]} #{custom.qpro_secret_hair[4]} #{custom.qpro_secret_hair[5]} #{custom.qpro_secret_hair[6]}
|
||||
face(__type="s64" __count="7") #{custom.qpro_secret_face[0]} #{custom.qpro_secret_face[1]} #{custom.qpro_secret_face[2]} #{custom.qpro_secret_face[3]} #{custom.qpro_secret_face[4]} #{custom.qpro_secret_face[5]} #{custom.qpro_secret_face[6]}
|
||||
body(__type="s64" __count="7") #{custom.qpro_secret_body[0]} #{custom.qpro_secret_body[1]} #{custom.qpro_secret_body[2]} #{custom.qpro_secret_body[3]} #{custom.qpro_secret_body[4]} #{custom.qpro_secret_body[5]} #{custom.qpro_secret_body[6]}
|
||||
hand(__type="s64" __count="7") #{custom.qpro_secret_hand[0]} #{custom.qpro_secret_hand[1]} #{custom.qpro_secret_hand[2]} #{custom.qpro_secret_hand[3]} #{custom.qpro_secret_hand[4]} #{custom.qpro_secret_hand[5]} #{custom.qpro_secret_hand[6]}
|
||||
secret
|
||||
flg1(__type="s64" __count="3") -1 -1 -1
|
||||
flg2(__type="s64" __count="3") -1 -1 -1
|
||||
flg3(__type="s64" __count="3") -1 -1 -1
|
||||
flg4(__type="s64" __count="3") -1 -1 -1
|
||||
grade(sgid=pcdata.sgid dgid=pcdata.dgid)
|
||||
- for (let d of dArray)
|
||||
g(__type="u8" __count="4") #{d[0]} #{d[1]} #{d[2]} #{d[3]}
|
||||
eisei_grade
|
||||
- for (let ed of eArray)
|
||||
detail(grade_type=ed.grade_type grade_id=ed.grade_id stage_num=ed.stage_num clear_type=ed.clear_type)
|
||||
past(__type="s32" __count="5") #{ed.past[0]} #{ed.past[1]} #{ed.past[2]} #{ed.past[3]} #{ed.past[4]}
|
||||
max_past(__type="s32" __count="5") #{ed.max_past[0]} #{ed.max_past[1]} #{ed.max_past[2]} #{ed.max_past[3]} #{ed.max_past[4]}
|
||||
skin(__type="s16" __count="20") #{custom.frame} #{custom.turntable} #{custom.note_burst} #{custom.menu_music} #{appendsettings} #{custom.lane_cover} 0 #{custom.category_vox} #{custom.note_skin} #{custom.full_combo_splash} #{custom.note_beam} #{custom.judge_font} 0 #{Number(custom.disable_musicpreview)} #{custom.pacemaker_cover} #{Number(custom.vefx_lock)} #{custom.effect} #{custom.bomb_size} #{Number(custom.disable_hcn_color)} #{custom.first_note_preview}
|
||||
qprodata(__type="u32" __count="5") #{custom.qpro_head} #{custom.qpro_hair} #{custom.qpro_face} #{custom.qpro_hand} #{custom.qpro_body}
|
||||
rlist
|
||||
- for (let rd of rArray)
|
||||
rival(spdp=rd.play_style id=rd.profile[2] id_str=rd.profile[3] djname=rd.profile[0] pid=rd.profile[1] sg=rd.pcdata[0] dg=rd.pcdata[1] sa=rd.pcdata[2] da=rd.pcdata[3])
|
||||
is_robo(__type="bool") 0
|
||||
qprodata(body=rd.qprodata[3] face=rd.qprodata[2] hair=rd.qprodata[0] hand=rd.qprodata[4] head=rd.qprodata[1])
|
||||
shop(name=shop_data.opname)
|
||||
dj_rank(style="0")
|
||||
rank(__type="s32" __count="15") #{pcdata.dr_sprank[0]} #{pcdata.dr_sprank[1]} #{pcdata.dr_sprank[2]} #{pcdata.dr_sprank[3]} #{pcdata.dr_sprank[4]} #{pcdata.dr_sprank[5]} #{pcdata.dr_sprank[6]} #{pcdata.dr_sprank[7]} #{pcdata.dr_sprank[8]} #{pcdata.dr_sprank[9]} #{pcdata.dr_sprank[10]} #{pcdata.dr_sprank[11]} #{pcdata.dr_sprank[12]} #{pcdata.dr_sprank[13]} #{pcdata.dr_sprank[14]}
|
||||
point(__type="s32" __count="15") #{pcdata.dr_sppoint[0]} #{pcdata.dr_sppoint[1]} #{pcdata.dr_sppoint[2]} #{pcdata.dr_sppoint[3]} #{pcdata.dr_sppoint[4]} #{pcdata.dr_sppoint[5]} #{pcdata.dr_sppoint[6]} #{pcdata.dr_sppoint[7]} #{pcdata.dr_sppoint[8]} #{pcdata.dr_sppoint[9]} #{pcdata.dr_sppoint[10]} #{pcdata.dr_sppoint[11]} #{pcdata.dr_sppoint[12]} #{pcdata.dr_sppoint[13]} #{pcdata.dr_sppoint[14]}
|
||||
dj_rank(style="1")
|
||||
rank(__type="s32" __count="15") #{pcdata.dr_dprank[0]} #{pcdata.dr_dprank[1]} #{pcdata.dr_dprank[2]} #{pcdata.dr_dprank[3]} #{pcdata.dr_dprank[4]} #{pcdata.dr_dprank[5]} #{pcdata.dr_dprank[6]} #{pcdata.dr_dprank[7]} #{pcdata.dr_dprank[8]} #{pcdata.dr_dprank[9]} #{pcdata.dr_dprank[10]} #{pcdata.dr_dprank[11]} #{pcdata.dr_dprank[12]} #{pcdata.dr_dprank[13]} #{pcdata.dr_dprank[14]}
|
||||
point(__type="s32" __count="15") #{pcdata.dr_dppoint[0]} #{pcdata.dr_dppoint[1]} #{pcdata.dr_dppoint[2]} #{pcdata.dr_dppoint[3]} #{pcdata.dr_dppoint[4]} #{pcdata.dr_dppoint[5]} #{pcdata.dr_dppoint[6]} #{pcdata.dr_dppoint[7]} #{pcdata.dr_dppoint[8]} #{pcdata.dr_dppoint[9]} #{pcdata.dr_dppoint[10]} #{pcdata.dr_dppoint[11]} #{pcdata.dr_dppoint[12]} #{pcdata.dr_dppoint[13]} #{pcdata.dr_dppoint[14]}
|
||||
notes_radar(style="0")
|
||||
radar_score(__type="s32" __count="6") #{pcdata.nr_spradar[0]} #{pcdata.nr_spradar[1]} #{pcdata.nr_spradar[2]} #{pcdata.nr_spradar[3]} #{pcdata.nr_spradar[4]} #{pcdata.nr_spradar[5]}
|
||||
notes_radar(style="1")
|
||||
radar_score(__type="s32" __count="6") #{pcdata.nr_dpradar[0]} #{pcdata.nr_dpradar[1]} #{pcdata.nr_dpradar[2]} #{pcdata.nr_dpradar[3]} #{pcdata.nr_dpradar[4]} #{pcdata.nr_dpradar[5]}
|
||||
visitor(anum="10" snum="10" pnum="10" vs_flg="1")
|
||||
step(dp_clear_mission_clear=pcdata.st_dp_clear_mission_clear dp_clear_mission_level=pcdata.st_dp_clear_mission_level dp_dj_mission_clear=pcdata.st_dp_dj_mission_clear dp_dj_mission_level=pcdata.st_dp_dj_mission_level dp_level=pcdata.st_dp_level dp_mission_point=pcdata.st_dp_mission_point dp_mplay=pcdata.st_dp_mplay enemy_damage=pcdata.st_enemy_damage progress=pcdata.st_progress sp_clear_mission_clear=pcdata.st_sp_clear_mission_clear sp_clear_mission_level=pcdata.st_sp_clear_mission_level sp_dj_mission_clear=pcdata.st_sp_dj_mission_clear sp_dj_mission_level=pcdata.st_sp_dj_mission_level sp_level=pcdata.st_sp_level sp_mission_point=pcdata.st_sp_mission_point sp_mplay=pcdata.st_sp_mplay tips_read_list=pcdata.st_tips_read_list)
|
||||
is_track_ticket(__type="bool") #{pcdata.st_is_track_ticket}
|
||||
achievements(last_weekly=pcdata.achi_lastweekly pack=pcdata.achi_pack pack_comp=pcdata.achi_packcomp rival_crush=pcdata.achi_rivalcrush visit_flg=pcdata.achi_visitflg weekly_num=pcdata.achi_weeklynum)
|
||||
trophy(__type="s64" __count="20") #{pcdata.achi_trophy[0]} #{pcdata.achi_trophy[1]} #{pcdata.achi_trophy[2]} #{pcdata.achi_trophy[3]} #{pcdata.achi_trophy[4]} #{pcdata.achi_trophy[5]} #{pcdata.achi_trophy[6]} #{pcdata.achi_trophy[7]} #{pcdata.achi_trophy[8]} #{pcdata.achi_trophy[9]} #{pcdata.achi_trophy[10]} #{pcdata.achi_trophy[11]} #{pcdata.achi_trophy[12]} #{pcdata.achi_trophy[13]} #{pcdata.achi_trophy[14]} #{pcdata.achi_trophy[15]} #{pcdata.achi_trophy[16]} #{pcdata.achi_trophy[17]} #{pcdata.achi_trophy[18]} #{pcdata.achi_trophy[19]}
|
||||
deller(deller=pcdata.deller rate="1")
|
||||
orb_data(rest_orb=pcdata.orb present_orb=pcdata.present_orb)
|
||||
leggendaria_semi_open(flg="-1")
|
||||
arena_data(play_num="2" play_num_dp="1" play_num_sp="1")
|
||||
achieve_data(arena_class="20" best_top_class_continuing="0" now_top_class_continuing="0" play_style="0" rating_value="20")
|
||||
achieve_data(arena_class="20" best_top_class_continuing="0" now_top_class_continuing="0" play_style="1" rating_value="20")
|
||||
cube_data(cube="0" season_id="0")
|
||||
chat_data(chat_type_0="CHAT CUSTOM 1" chat_type_1="CHAT CUSTOM 2" chat_type_2="CHAT CUSTOM 3" chat_type_3="CHAT CUSTOM 4")
|
||||
is_chat_0(__type="bool") 1
|
||||
is_chat_1(__type="bool") 1
|
||||
is_chat_2(__type="bool") 1
|
||||
is_chat_3(__type="bool") 1
|
||||
skin_customize_flg(skin_frame_flg="-1" skin_bgm_flg="-1")
|
||||
event1(event_play_num=pcdata.event_play_num last_select_gym_id=pcdata.event_last_select_id)
|
||||
- for (let evt of evtArray)
|
||||
gym_data(gym_id=evt.gym_id play_num=evt.play_num gauge_spirit=evt.gauge_spirit gauge_technique=evt.gauge_technique gauge_body=evt.gauge_body boss_attack_num=evt.boss_attack_num boss_damage=evt.boss_damage disp_lounge_list=evt.disp_lounge_list stb_type=evt.stb_type)
|
||||
is_complete(__type="bool") #{evt.is_complete}
|
||||
is_gauge_max(__type="bool") #{evt.is_gauge_max}
|
||||
floor_infection4(music_list="-1")
|
||||
bemani_vote(music_list="-1")
|
||||
bemani_janken_meeting(music_list="-1")
|
||||
bemani_rush(music_list_ichika="-1" music_list_nono="-1")
|
||||
ultimate_mobile_link(music_list="-1")
|
||||
language_setting(language=profile.language)
|
||||
movie_agreement(agreement_version="1")
|
||||
extra_boss_event(key_orb="0" boss_orb_0="0" boss_orb_1="0" boss_orb_2="0" boss_orb_3="0" boss_orb_4="0" boss_orb_5="0" boss_orb_6="0" boss_orb_7="0")
|
||||
94
iidx@asphyxia/pug/LDJ/28pcget.pug
Normal file
94
iidx@asphyxia/pug/LDJ/28pcget.pug
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
IIDX28pc(status="0")
|
||||
pcdata(id=profile.id idstr=profile.idstr name=profile.name pid=profile.pid spnum=pcdata.spnum dpnum=pcdata.dpnum sach=pcdata.sach dach=pcdata.dach mode=pcdata.mode pmode=pcdata.pmode ngrade=pcdata.ngrade rtype=pcdata.rtype sp_opt=pcdata.sp_opt dp_opt=pcdata.dp_opt dp_opt2=pcdata.dp_opt2 gpos=pcdata.gpos s_sorttype=pcdata.s_sorttype d_sorttype=pcdata.d_sorttype s_pace=pcdata.s_pace d_pace=pcdata.d_pace s_gno=pcdata.s_gno d_gno=pcdata.d_gno s_sub_gno=pcdata.s_sub_gno d_sub_gno=pcdata.d_sub_gno s_gtype=pcdata.s_gtype d_gtype=pcdata.d_gtype s_sdlen=pcdata.s_sdlen d_sdlen=pcdata.d_sdlen s_sdtype=pcdata.s_sdtype d_sdtype=pcdata.d_sdtype s_timing=pcdata.s_timing d_timing=pcdata.d_timing s_notes=pcdata.s_notes d_notes=pcdata.d_notes s_judge=pcdata.s_judge d_judge=pcdata.d_judge s_judgeAdj=pcdata.s_judgeAdj d_judgeAdj=pcdata.d_judgeAdj s_hispeed=pcdata.s_hispeed d_hispeed=pcdata.d_hispeed s_liflen=pcdata.s_liflen d_liflen=pcdata.d_liflen s_disp_judge=pcdata.s_disp_judge d_disp_judge=pcdata.d_disp_judge s_opstyle=pcdata.s_opstyle d_opstyle=pcdata.d_opstyle s_graph_score=pcdata.s_graph_score d_graph_score=pcdata.d_graph_score s_auto_scrach=pcdata.s_auto_scrach d_auto_scrach=pcdata.d_auto_scrach s_gauge_disp=pcdata.s_gauge_disp d_gauge_disp=pcdata.d_gauge_disp s_lane_brignt=pcdata.s_lane_brignt d_lane_brignt=pcdata.d_lane_brignt s_camera_layout=pcdata.s_camera_layout d_camera_layout=pcdata.d_camera_layout s_ghost_score=pcdata.s_ghost_score d_ghost_score=pcdata.d_ghost_score s_tsujigiri_disp=pcdata.s_tsujigiri_disp d_tsujigiri_disp=pcdata.d_tsujigiri_disp)
|
||||
lightning_play_data(dpnum=lm_playdata.dp_num spnum=lm_playdata.sp_num)
|
||||
lightning_setting(headphone_vol=lm_settings.headphone_vol resistance_dp_left=lm_settings.resistance_dp_left resistance_dp_right=lm_settings.resistance_dp_right resistance_sp_left=lm_settings.resistance_sp_left resistance_sp_right=lm_settings.resistance_sp_right skin_0=lm_custom.premium_skin flg_skin_0="-1")
|
||||
slider(__type="s32" __count="7") #{lm_settings.slider[0]} #{lm_settings.slider[1]} #{lm_settings.slider[2]} #{lm_settings.slider[3]} #{lm_settings.slider[4]} #{lm_settings.slider[5]} #{lm_settings.slider[6]}
|
||||
light(__type="bool" __count="6") #{lm_settings.light[0]} #{lm_settings.light[1]} #{lm_settings.light[2]} #{lm_settings.light[3]} #{lm_settings.light[4]} #{lm_settings.light[5]}
|
||||
concentration(__type="bool") #{lm_settings.concentration}
|
||||
spdp_rival(flg="-1")
|
||||
bind_eaappli
|
||||
ea_premium_course
|
||||
enable_qr_reward
|
||||
secret
|
||||
flg1(__type="s64" __count="3") -1 -1 -1
|
||||
flg2(__type="s64" __count="3") -1 -1 -1
|
||||
flg3(__type="s64" __count="3") -1 -1 -1
|
||||
flg4(__type="s64" __count="3") -1 -1 -1
|
||||
leggendaria
|
||||
flg1(__type="s64" __count="3") -1 -1 -1
|
||||
music_memo
|
||||
- for (let m of mArray)
|
||||
music(index=m.music_idx play_style=m.play_style music_id=m.music_id)
|
||||
qpro_secret
|
||||
head(__type="s64" __count="7") #{custom.qpro_secret_head[0]} #{custom.qpro_secret_head[1]} #{custom.qpro_secret_head[2]} #{custom.qpro_secret_head[3]} #{custom.qpro_secret_head[4]} #{custom.qpro_secret_head[5]} #{custom.qpro_secret_head[6]}
|
||||
hair(__type="s64" __count="7") #{custom.qpro_secret_hair[0]} #{custom.qpro_secret_hair[1]} #{custom.qpro_secret_hair[2]} #{custom.qpro_secret_hair[3]} #{custom.qpro_secret_hair[4]} #{custom.qpro_secret_hair[5]} #{custom.qpro_secret_hair[6]}
|
||||
face(__type="s64" __count="7") #{custom.qpro_secret_face[0]} #{custom.qpro_secret_face[1]} #{custom.qpro_secret_face[2]} #{custom.qpro_secret_face[3]} #{custom.qpro_secret_face[4]} #{custom.qpro_secret_face[5]} #{custom.qpro_secret_face[6]}
|
||||
body(__type="s64" __count="7") #{custom.qpro_secret_body[0]} #{custom.qpro_secret_body[1]} #{custom.qpro_secret_body[2]} #{custom.qpro_secret_body[3]} #{custom.qpro_secret_body[4]} #{custom.qpro_secret_body[5]} #{custom.qpro_secret_body[6]}
|
||||
hand(__type="s64" __count="7") #{custom.qpro_secret_hand[0]} #{custom.qpro_secret_hand[1]} #{custom.qpro_secret_hand[2]} #{custom.qpro_secret_hand[3]} #{custom.qpro_secret_hand[4]} #{custom.qpro_secret_hand[5]} #{custom.qpro_secret_hand[6]}
|
||||
grade(sgid=pcdata.sgid dgid=pcdata.dgid)
|
||||
- for (let d of dArray)
|
||||
g(__type="u8" __count="4") #{d[0]} #{d[1]} #{d[2]} #{d[3]}
|
||||
eisei_grade_data
|
||||
- for (let ed of eArray)
|
||||
detail(grade_type=ed.grade_type grade_id=ed.grade_id stage_num=ed.stage_num clear_type=ed.clear_type)
|
||||
past(__type="s32" __count="5") #{ed.past[0]} #{ed.past[1]} #{ed.past[2]} #{ed.past[3]} #{ed.past[4]}
|
||||
selected_course(__type="s32" __count="5") #{ed.selected_course[0]} #{ed.selected_course[1]} #{ed.selected_course[2]} #{ed.selected_course[3]} #{ed.selected_course[4]}
|
||||
max_past(__type="s32" __count="5") #{ed.max_past[0]} #{ed.max_past[1]} #{ed.max_past[2]} #{ed.max_past[3]} #{ed.max_past[4]}
|
||||
max_selected_course(__type="s32" __count="5") #{ed.max_selected_course[0]} #{ed.max_selected_course[1]} #{ed.max_selected_course[2]} #{ed.max_selected_course[3]} #{ed.max_selected_course[4]}
|
||||
skin(__type="s16" __count="20") #{custom.frame} #{custom.turntable} #{custom.note_burst} #{custom.menu_music} #{appendsettings} #{custom.lane_cover} 0 #{custom.category_vox} #{custom.note_skin} #{custom.full_combo_splash} #{custom.note_beam} #{custom.judge_font} 0 #{Number(custom.disable_musicpreview)} #{custom.pacemaker_cover} #{Number(custom.vefx_lock)} #{custom.effect} #{custom.bomb_size} #{Number(custom.disable_hcn_color)} #{custom.first_note_preview}
|
||||
qprodata(__type="u32" __count="5") #{custom.qpro_head} #{custom.qpro_hair} #{custom.qpro_face} #{custom.qpro_hand} #{custom.qpro_body}
|
||||
rlist
|
||||
- for (let rd of rArray)
|
||||
rival(spdp=rd.play_style id=rd.profile[2] id_str=rd.profile[3] djname=rd.profile[0] pid=rd.profile[1] sg=rd.pcdata[0] dg=rd.pcdata[1] sa=rd.pcdata[2] da=rd.pcdata[3])
|
||||
is_robo(__type="bool") 0
|
||||
qprodata(body=rd.qprodata[3] face=rd.qprodata[2] hair=rd.qprodata[0] hand=rd.qprodata[4] head=rd.qprodata[1])
|
||||
shop(name=shop_data.opname)
|
||||
dj_rank(style="0")
|
||||
rank(__type="s32" __count="15") #{pcdata.dr_sprank[0]} #{pcdata.dr_sprank[1]} #{pcdata.dr_sprank[2]} #{pcdata.dr_sprank[3]} #{pcdata.dr_sprank[4]} #{pcdata.dr_sprank[5]} #{pcdata.dr_sprank[6]} #{pcdata.dr_sprank[7]} #{pcdata.dr_sprank[8]} #{pcdata.dr_sprank[9]} #{pcdata.dr_sprank[10]} #{pcdata.dr_sprank[11]} #{pcdata.dr_sprank[12]} #{pcdata.dr_sprank[13]} #{pcdata.dr_sprank[14]}
|
||||
point(__type="s32" __count="15") #{pcdata.dr_sppoint[0]} #{pcdata.dr_sppoint[1]} #{pcdata.dr_sppoint[2]} #{pcdata.dr_sppoint[3]} #{pcdata.dr_sppoint[4]} #{pcdata.dr_sppoint[5]} #{pcdata.dr_sppoint[6]} #{pcdata.dr_sppoint[7]} #{pcdata.dr_sppoint[8]} #{pcdata.dr_sppoint[9]} #{pcdata.dr_sppoint[10]} #{pcdata.dr_sppoint[11]} #{pcdata.dr_sppoint[12]} #{pcdata.dr_sppoint[13]} #{pcdata.dr_sppoint[14]}
|
||||
dj_rank(style="1")
|
||||
rank(__type="s32" __count="15") #{pcdata.dr_dprank[0]} #{pcdata.dr_dprank[1]} #{pcdata.dr_dprank[2]} #{pcdata.dr_dprank[3]} #{pcdata.dr_dprank[4]} #{pcdata.dr_dprank[5]} #{pcdata.dr_dprank[6]} #{pcdata.dr_dprank[7]} #{pcdata.dr_dprank[8]} #{pcdata.dr_dprank[9]} #{pcdata.dr_dprank[10]} #{pcdata.dr_dprank[11]} #{pcdata.dr_dprank[12]} #{pcdata.dr_dprank[13]} #{pcdata.dr_dprank[14]}
|
||||
point(__type="s32" __count="15") #{pcdata.dr_dppoint[0]} #{pcdata.dr_dppoint[1]} #{pcdata.dr_dppoint[2]} #{pcdata.dr_dppoint[3]} #{pcdata.dr_dppoint[4]} #{pcdata.dr_dppoint[5]} #{pcdata.dr_dppoint[6]} #{pcdata.dr_dppoint[7]} #{pcdata.dr_dppoint[8]} #{pcdata.dr_dppoint[9]} #{pcdata.dr_dppoint[10]} #{pcdata.dr_dppoint[11]} #{pcdata.dr_dppoint[12]} #{pcdata.dr_dppoint[13]} #{pcdata.dr_dppoint[14]}
|
||||
notes_radar(style="0")
|
||||
radar_score(__type="s32" __count="6") #{pcdata.nr_spradar[0]} #{pcdata.nr_spradar[1]} #{pcdata.nr_spradar[2]} #{pcdata.nr_spradar[3]} #{pcdata.nr_spradar[4]} #{pcdata.nr_spradar[5]}
|
||||
notes_radar(style="1")
|
||||
radar_score(__type="s32" __count="6") #{pcdata.nr_dpradar[0]} #{pcdata.nr_dpradar[1]} #{pcdata.nr_dpradar[2]} #{pcdata.nr_dpradar[3]} #{pcdata.nr_dpradar[4]} #{pcdata.nr_dpradar[5]}
|
||||
visitor(anum="10" snum="10" pnum="10" vs_flg="1")
|
||||
step(dp_clear_mission_clear=pcdata.st_dp_clear_mission_clear dp_clear_mission_level=pcdata.st_dp_clear_mission_level dp_dj_mission_clear=pcdata.st_dp_dj_mission_clear dp_dj_mission_level=pcdata.st_dp_dj_mission_level dp_level=pcdata.st_dp_level dp_mission_point=pcdata.st_dp_mission_point dp_mplay=pcdata.st_dp_mplay enemy_damage=pcdata.st_enemy_damage progress=pcdata.st_progress sp_clear_mission_clear=pcdata.st_sp_clear_mission_clear sp_clear_mission_level=pcdata.st_sp_clear_mission_level sp_dj_mission_clear=pcdata.st_sp_dj_mission_clear sp_dj_mission_level=pcdata.st_sp_dj_mission_level sp_level=pcdata.st_sp_level sp_mission_point=pcdata.st_sp_mission_point sp_mplay=pcdata.st_sp_mplay tips_read_list=pcdata.st_tips_read_list)
|
||||
is_track_ticket(__type="bool") #{pcdata.st_is_track_ticket}
|
||||
achievements(last_weekly=pcdata.achi_lastweekly pack=pcdata.achi_pack pack_comp=pcdata.achi_packcomp rival_crush=pcdata.achi_rivalcrush visit_flg=pcdata.achi_visitflg weekly_num=pcdata.achi_weeklynum)
|
||||
trophy(__type="s64" __count="20") #{pcdata.achi_trophy[0]} #{pcdata.achi_trophy[1]} #{pcdata.achi_trophy[2]} #{pcdata.achi_trophy[3]} #{pcdata.achi_trophy[4]} #{pcdata.achi_trophy[5]} #{pcdata.achi_trophy[6]} #{pcdata.achi_trophy[7]} #{pcdata.achi_trophy[8]} #{pcdata.achi_trophy[9]} #{pcdata.achi_trophy[10]} #{pcdata.achi_trophy[11]} #{pcdata.achi_trophy[12]} #{pcdata.achi_trophy[13]} #{pcdata.achi_trophy[14]} #{pcdata.achi_trophy[15]} #{pcdata.achi_trophy[16]} #{pcdata.achi_trophy[17]} #{pcdata.achi_trophy[18]} #{pcdata.achi_trophy[19]}
|
||||
deller(deller=pcdata.deller rate="1")
|
||||
orb_data(rest_orb=pcdata.orb present_orb=pcdata.present_orb)
|
||||
arena_data(play_num="2" play_num_dp="1" play_num_sp="1" prev_best_class_sp="20" prev_best_class_dp="20")
|
||||
achieve_data(arena_class="20" best_top_class_continuing="0" now_top_class_continuing="0" counterattack_num="0" play_style="0" rating_value="20")
|
||||
achieve_data(arena_class="20" best_top_class_continuing="0" now_top_class_continuing="0" counterattack_num="0" play_style="1" rating_value="20")
|
||||
cube_data(cube="0" season_id="0")
|
||||
chat_data(chat_type_0="CHAT CUSTOM 1" chat_type_1="CHAT CUSTOM 2" chat_type_2="CHAT CUSTOM 3" chat_type_3="CHAT CUSTOM 4")
|
||||
is_chat_0(__type="bool") 1
|
||||
is_chat_1(__type="bool") 1
|
||||
is_chat_2(__type="bool") 1
|
||||
is_chat_3(__type="bool") 1
|
||||
skin_customize_flg(skin_frame_flg="-1" skin_bgm_flg="-1")
|
||||
event_1(event_play_num=pcdata.event_play_num story_prog=pcdata.event_story_prog last_select_area_id=pcdata.event_last_select_id failed_num=pcdata.event_failed_num)
|
||||
- for (let evt of evtArray)
|
||||
area_data(area_id=evt.area_id play_num=evt.play_num recipe_prog0=evt.recipe_prog0 recipe_prog1=evt.recipe_prog1 recipe_prog2=evt.recipe_prog2 recipe_prog3=evt.recipe_prog3 recipe_prog4=evt.recipe_prog4 operation_num=evt.operation_num operation_prog=evt.operation_prog last_select_recipe=evt.last_select_recipe area_prog=evt.area_prog)
|
||||
is_complete(__type="bool") #{evt.is_complete}
|
||||
floor_infection4(music_list="-1")
|
||||
bemani_vote(music_list="-1")
|
||||
bemani_janken_meeting(music_list="-1")
|
||||
bemani_rush(music_list_ichika="-1" music_list_nono="-1")
|
||||
ultimate_mobile_link(music_list="-1")
|
||||
link_flag
|
||||
bemani_musiq_fes(music_list="-1")
|
||||
busou_linkage(music_list="-1")
|
||||
busou_linkage_2(music_list="-1")
|
||||
valkyrie_linkage_data(progress="100")
|
||||
bemani_song_battle(music_list="-1")
|
||||
language_setting(language=profile.language)
|
||||
movie_agreement(agreement_version="1")
|
||||
extra_boss_event(key_orb="0" boss_orb_0="0" boss_orb_1="0" boss_orb_2="0" boss_orb_3="0" boss_orb_4="0" boss_orb_5="0" boss_orb_6="0" boss_orb_7="0")
|
||||
world_tourism
|
||||
- for (let wd of wArray)
|
||||
tour_data(tour_id=wd.tour_id progress=wd.progress)
|
||||
world_tourism_secret(music_list="-1")
|
||||
99
iidx@asphyxia/pug/LDJ/29pcget.pug
Normal file
99
iidx@asphyxia/pug/LDJ/29pcget.pug
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
IIDX29pc(status="0")
|
||||
pcdata(id=profile.id idstr=profile.idstr name=profile.name pid=profile.pid spnum=pcdata.spnum dpnum=pcdata.dpnum sach=pcdata.sach dach=pcdata.dach mode=pcdata.mode pmode=pcdata.pmode ngrade=pcdata.ngrade rtype=pcdata.rtype sp_opt=pcdata.sp_opt dp_opt=pcdata.dp_opt dp_opt2=pcdata.dp_opt2 gpos=pcdata.gpos s_sorttype=pcdata.s_sorttype d_sorttype=pcdata.d_sorttype s_pace=pcdata.s_pace d_pace=pcdata.d_pace s_gno=pcdata.s_gno d_gno=pcdata.d_gno s_sub_gno=pcdata.s_sub_gno d_sub_gno=pcdata.d_sub_gno s_gtype=pcdata.s_gtype d_gtype=pcdata.d_gtype s_sdlen=pcdata.s_sdlen d_sdlen=pcdata.d_sdlen s_sdtype=pcdata.s_sdtype d_sdtype=pcdata.d_sdtype s_timing=pcdata.s_timing d_timing=pcdata.d_timing s_notes=pcdata.s_notes d_notes=pcdata.d_notes s_judge=pcdata.s_judge d_judge=pcdata.d_judge s_judgeAdj=pcdata.s_judgeAdj d_judgeAdj=pcdata.d_judgeAdj s_hispeed=pcdata.s_hispeed d_hispeed=pcdata.d_hispeed s_liflen=pcdata.s_liflen d_liflen=pcdata.d_liflen s_disp_judge=pcdata.s_disp_judge d_disp_judge=pcdata.d_disp_judge s_opstyle=pcdata.s_opstyle d_opstyle=pcdata.d_opstyle s_graph_score=pcdata.s_graph_score d_graph_score=pcdata.d_graph_score s_auto_scrach=pcdata.s_auto_scrach d_auto_scrach=pcdata.d_auto_scrach s_gauge_disp=pcdata.s_gauge_disp d_gauge_disp=pcdata.d_gauge_disp s_lane_brignt=pcdata.s_lane_brignt d_lane_brignt=pcdata.d_lane_brignt s_camera_layout=pcdata.s_camera_layout d_camera_layout=pcdata.d_camera_layout s_ghost_score=pcdata.s_ghost_score d_ghost_score=pcdata.d_ghost_score s_tsujigiri_disp=pcdata.s_tsujigiri_disp d_tsujigiri_disp=pcdata.d_tsujigiri_disp s_auto_adjust=pcdata.s_auto_adjust d_auto_adjust=pcdata.d_auto_adjust)
|
||||
lightning_play_data(dpnum=lm_playdata.dp_num spnum=lm_playdata.sp_num)
|
||||
lightning_setting(headphone_vol=lm_settings.headphone_vol resistance_dp_left=lm_settings.resistance_dp_left resistance_dp_right=lm_settings.resistance_dp_right resistance_sp_left=lm_settings.resistance_sp_left resistance_sp_right=lm_settings.resistance_sp_right skin_0=lm_custom.premium_skin flg_skin_0="-1")
|
||||
slider(__type="s32" __count="7") #{lm_settings.slider[0]} #{lm_settings.slider[1]} #{lm_settings.slider[2]} #{lm_settings.slider[3]} #{lm_settings.slider[4]} #{lm_settings.slider[5]} #{lm_settings.slider[6]}
|
||||
light(__type="bool" __count="10") #{lm_settings.light[0]} #{lm_settings.light[1]} #{lm_settings.light[2]} #{lm_settings.light[3]} #{lm_settings.light[4]} #{lm_settings.light[5]} #{lm_settings.light[6]} #{lm_settings.light[7]} #{lm_settings.light[8]} #{lm_settings.light[9]}
|
||||
concentration(__type="bool") #{lm_settings.concentration}
|
||||
spdp_rival(flg="-1")
|
||||
bind_eaappli
|
||||
ea_premium_course
|
||||
enable_qr_reward
|
||||
secret
|
||||
flg1(__type="s64" __count="3") -1 -1 -1
|
||||
flg2(__type="s64" __count="3") -1 -1 -1
|
||||
flg3(__type="s64" __count="3") -1 -1 -1
|
||||
flg4(__type="s64" __count="3") -1 -1 -1
|
||||
leggendaria
|
||||
flg1(__type="s64" __count="3") -1 -1 -1
|
||||
music_memo
|
||||
- for (let m of mArray)
|
||||
music(index=m.music_idx play_style=m.play_style music_id=m.music_id)
|
||||
qpro_secret
|
||||
head(__type="s64" __count="7") #{custom.qpro_secret_head[0]} #{custom.qpro_secret_head[1]} #{custom.qpro_secret_head[2]} #{custom.qpro_secret_head[3]} #{custom.qpro_secret_head[4]} #{custom.qpro_secret_head[5]} #{custom.qpro_secret_head[6]}
|
||||
hair(__type="s64" __count="7") #{custom.qpro_secret_hair[0]} #{custom.qpro_secret_hair[1]} #{custom.qpro_secret_hair[2]} #{custom.qpro_secret_hair[3]} #{custom.qpro_secret_hair[4]} #{custom.qpro_secret_hair[5]} #{custom.qpro_secret_hair[6]}
|
||||
face(__type="s64" __count="7") #{custom.qpro_secret_face[0]} #{custom.qpro_secret_face[1]} #{custom.qpro_secret_face[2]} #{custom.qpro_secret_face[3]} #{custom.qpro_secret_face[4]} #{custom.qpro_secret_face[5]} #{custom.qpro_secret_face[6]}
|
||||
body(__type="s64" __count="7") #{custom.qpro_secret_body[0]} #{custom.qpro_secret_body[1]} #{custom.qpro_secret_body[2]} #{custom.qpro_secret_body[3]} #{custom.qpro_secret_body[4]} #{custom.qpro_secret_body[5]} #{custom.qpro_secret_body[6]}
|
||||
hand(__type="s64" __count="7") #{custom.qpro_secret_hand[0]} #{custom.qpro_secret_hand[1]} #{custom.qpro_secret_hand[2]} #{custom.qpro_secret_hand[3]} #{custom.qpro_secret_hand[4]} #{custom.qpro_secret_hand[5]} #{custom.qpro_secret_hand[6]}
|
||||
grade(sgid=pcdata.sgid dgid=pcdata.dgid)
|
||||
- for (let d of dArray)
|
||||
g(__type="u8" __count="4") #{d[0]} #{d[1]} #{d[2]} #{d[3]}
|
||||
eisei_grade_data
|
||||
- for (let ed of eArray)
|
||||
detail(grade_type=ed.grade_type grade_id=ed.grade_id stage_num=ed.stage_num clear_type=ed.clear_type)
|
||||
past(__type="s32" __count="3") #{ed.past[0]} #{ed.past[1]} #{ed.past[2]}
|
||||
selected_course(__type="s32" __count="3") #{ed.selected_course[0]} #{ed.selected_course[1]} #{ed.selected_course[2]}
|
||||
max_past(__type="s32" __count="3") #{ed.max_past[0]} #{ed.max_past[1]} #{ed.max_past[2]}
|
||||
max_selected_course(__type="s32" __count="3") #{ed.max_selected_course[0]} #{ed.max_selected_course[1]} #{ed.max_selected_course[2]}
|
||||
skin(__type="s16" __count="20") #{custom.frame} #{custom.turntable} #{custom.note_burst} #{custom.menu_music} #{appendsettings} #{custom.lane_cover} 0 #{custom.category_vox} #{custom.note_skin} #{custom.full_combo_splash} #{custom.note_beam} #{custom.judge_font} 0 #{Number(custom.disable_musicpreview)} #{custom.pacemaker_cover} #{Number(custom.vefx_lock)} #{custom.effect} #{custom.bomb_size} #{Number(custom.disable_hcn_color)} #{custom.first_note_preview}
|
||||
qprodata(__type="u32" __count="5") #{custom.qpro_head} #{custom.qpro_hair} #{custom.qpro_face} #{custom.qpro_hand} #{custom.qpro_body}
|
||||
rlist
|
||||
- for (let rd of rArray)
|
||||
rival(spdp=rd.play_style id=rd.profile[2] id_str=rd.profile[3] djname=rd.profile[0] pid=rd.profile[1] sg=rd.pcdata[0] dg=rd.pcdata[1] sa=rd.pcdata[2] da=rd.pcdata[3])
|
||||
is_robo(__type="bool") 0
|
||||
qprodata(body=rd.qprodata[3] face=rd.qprodata[2] hair=rd.qprodata[0] hand=rd.qprodata[4] head=rd.qprodata[1])
|
||||
shop(name=shop_data.opname)
|
||||
dj_rank(style="0")
|
||||
rank(__type="s32" __count="15") #{pcdata.dr_sprank[0]} #{pcdata.dr_sprank[1]} #{pcdata.dr_sprank[2]} #{pcdata.dr_sprank[3]} #{pcdata.dr_sprank[4]} #{pcdata.dr_sprank[5]} #{pcdata.dr_sprank[6]} #{pcdata.dr_sprank[7]} #{pcdata.dr_sprank[8]} #{pcdata.dr_sprank[9]} #{pcdata.dr_sprank[10]} #{pcdata.dr_sprank[11]} #{pcdata.dr_sprank[12]} #{pcdata.dr_sprank[13]} #{pcdata.dr_sprank[14]}
|
||||
point(__type="s32" __count="15") #{pcdata.dr_sppoint[0]} #{pcdata.dr_sppoint[1]} #{pcdata.dr_sppoint[2]} #{pcdata.dr_sppoint[3]} #{pcdata.dr_sppoint[4]} #{pcdata.dr_sppoint[5]} #{pcdata.dr_sppoint[6]} #{pcdata.dr_sppoint[7]} #{pcdata.dr_sppoint[8]} #{pcdata.dr_sppoint[9]} #{pcdata.dr_sppoint[10]} #{pcdata.dr_sppoint[11]} #{pcdata.dr_sppoint[12]} #{pcdata.dr_sppoint[13]} #{pcdata.dr_sppoint[14]}
|
||||
dj_rank(style="1")
|
||||
rank(__type="s32" __count="15") #{pcdata.dr_dprank[0]} #{pcdata.dr_dprank[1]} #{pcdata.dr_dprank[2]} #{pcdata.dr_dprank[3]} #{pcdata.dr_dprank[4]} #{pcdata.dr_dprank[5]} #{pcdata.dr_dprank[6]} #{pcdata.dr_dprank[7]} #{pcdata.dr_dprank[8]} #{pcdata.dr_dprank[9]} #{pcdata.dr_dprank[10]} #{pcdata.dr_dprank[11]} #{pcdata.dr_dprank[12]} #{pcdata.dr_dprank[13]} #{pcdata.dr_dprank[14]}
|
||||
point(__type="s32" __count="15") #{pcdata.dr_dppoint[0]} #{pcdata.dr_dppoint[1]} #{pcdata.dr_dppoint[2]} #{pcdata.dr_dppoint[3]} #{pcdata.dr_dppoint[4]} #{pcdata.dr_dppoint[5]} #{pcdata.dr_dppoint[6]} #{pcdata.dr_dppoint[7]} #{pcdata.dr_dppoint[8]} #{pcdata.dr_dppoint[9]} #{pcdata.dr_dppoint[10]} #{pcdata.dr_dppoint[11]} #{pcdata.dr_dppoint[12]} #{pcdata.dr_dppoint[13]} #{pcdata.dr_dppoint[14]}
|
||||
notes_radar(style="0")
|
||||
radar_score(__type="s32" __count="6") #{pcdata.nr_spradar[0]} #{pcdata.nr_spradar[1]} #{pcdata.nr_spradar[2]} #{pcdata.nr_spradar[3]} #{pcdata.nr_spradar[4]} #{pcdata.nr_spradar[5]}
|
||||
notes_radar(style="1")
|
||||
radar_score(__type="s32" __count="6") #{pcdata.nr_dpradar[0]} #{pcdata.nr_dpradar[1]} #{pcdata.nr_dpradar[2]} #{pcdata.nr_dpradar[3]} #{pcdata.nr_dpradar[4]} #{pcdata.nr_dpradar[5]}
|
||||
visitor(anum="10" snum="10" pnum="10" vs_flg="1")
|
||||
step(enemy_damage=pcdata.st_enemy_damage progress=pcdata.st_progress total_point=pcdata.st_total_point enemy_defeat_flg=pcdata.st_enemy_defeat_flg sp_level=pcdata.st_sp_level dp_level=pcdata.st_dp_level mission_clear_num=pcdata.st_mission_clear_num sp_mplay=pcdata.st_sp_mplay dp_mplay=pcdata.st_dp_mplay tips_read_list=pcdata.st_tips_read_list)
|
||||
is_track_ticket(__type="bool") #{pcdata.st_is_track_ticket}
|
||||
achievements(last_weekly=pcdata.achi_lastweekly pack=pcdata.achi_pack pack_comp=pcdata.achi_packcomp rival_crush=pcdata.achi_rivalcrush visit_flg=pcdata.achi_visitflg weekly_num=pcdata.achi_weeklynum)
|
||||
trophy(__type="s64" __count="20") #{pcdata.achi_trophy[0]} #{pcdata.achi_trophy[1]} #{pcdata.achi_trophy[2]} #{pcdata.achi_trophy[3]} #{pcdata.achi_trophy[4]} #{pcdata.achi_trophy[5]} #{pcdata.achi_trophy[6]} #{pcdata.achi_trophy[7]} #{pcdata.achi_trophy[8]} #{pcdata.achi_trophy[9]} #{pcdata.achi_trophy[10]} #{pcdata.achi_trophy[11]} #{pcdata.achi_trophy[12]} #{pcdata.achi_trophy[13]} #{pcdata.achi_trophy[14]} #{pcdata.achi_trophy[15]} #{pcdata.achi_trophy[16]} #{pcdata.achi_trophy[17]} #{pcdata.achi_trophy[18]} #{pcdata.achi_trophy[19]}
|
||||
deller(deller=pcdata.deller rate="1")
|
||||
orb_data(rest_orb=pcdata.orb present_orb=pcdata.present_orb)
|
||||
arena_data(play_num="2" play_num_dp="1" play_num_sp="1" prev_best_class_sp="20" prev_best_class_dp="20")
|
||||
achieve_data(arena_class="20" best_top_class_continuing="0" now_top_class_continuing="0" counterattack_num="0" play_style="0" rating_value="20")
|
||||
achieve_data(arena_class="20" best_top_class_continuing="0" now_top_class_continuing="0" counterattack_num="0" play_style="1" rating_value="20")
|
||||
cube_data(cube="0" season_id="0")
|
||||
chat_data(chat_type_0="CHAT CUSTOM 1" chat_type_1="CHAT CUSTOM 2" chat_type_2="CHAT CUSTOM 3" chat_type_3="CHAT CUSTOM 4")
|
||||
is_chat_0(__type="bool") 1
|
||||
is_chat_1(__type="bool") 1
|
||||
is_chat_2(__type="bool") 1
|
||||
is_chat_3(__type="bool") 1
|
||||
skin_customize_flg(skin_frame_flg="-1" skin_bgm_flg="-1" skin_lane_flg3="-1")
|
||||
event_1(event_play_num=pcdata.event_play_num last_select_platform_type=pcdata.event_last_select_type last_select_platform_id=pcdata.event_last_select_id)
|
||||
- for (let evt of evtArray)
|
||||
plat_watch_data(platform_id=evt.platform_id play_num=evt.play_num last_select_channel=evt.last_select_channel platform_prog=evt.platform_prog)
|
||||
- for (let evt2 of evtArray2)
|
||||
ch_watch_data(platform_id=evt2.platform_id channel_id=evt2.channel_id play_num=evt2.channel_play_num gauge=evt2.gauge)
|
||||
is_complete(__type="bool") #{evt2.is_complete}
|
||||
floor_infection4(music_list="-1")
|
||||
bemani_vote(music_list="-1")
|
||||
bemani_janken_meeting(music_list="-1")
|
||||
bemani_rush(music_list_ichika="-1" music_list_nono="-1")
|
||||
ultimate_mobile_link(music_list="-1")
|
||||
link_flag
|
||||
bemani_musiq_fes(music_list="-1")
|
||||
busou_linkage(music_list="-1")
|
||||
busou_linkage_2(music_list="-1")
|
||||
valkyrie_linkage_2_data(progress="100")
|
||||
bemani_song_battle(music_list="-1")
|
||||
language_setting(language=profile.language)
|
||||
movie_agreement(agreement_version="1")
|
||||
movie_setting
|
||||
hide_name(__type="bool") 0
|
||||
world_tourism
|
||||
- for (let wd of wArray)
|
||||
tour_data(tour_id=wd.tour_id progress=wd.progress)
|
||||
world_tourism_secrfet_flg
|
||||
flg1(__type="s64" __count="3") -1 -1 -1
|
||||
flg2(__type="s64" __count="3") -1 -1 -1
|
||||
101
iidx@asphyxia/pug/LDJ/30pcget.pug
Normal file
101
iidx@asphyxia/pug/LDJ/30pcget.pug
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
IIDX30pc(status="0")
|
||||
pcdata(id=profile.id idstr=profile.idstr name=profile.name pid=profile.pid spnum=pcdata.spnum dpnum=pcdata.dpnum sach=pcdata.sach dach=pcdata.dach mode=pcdata.mode pmode=pcdata.pmode ngrade=pcdata.ngrade rtype=pcdata.rtype sp_opt=pcdata.sp_opt dp_opt=pcdata.dp_opt dp_opt2=pcdata.dp_opt2 gpos=pcdata.gpos s_sorttype=pcdata.s_sorttype d_sorttype=pcdata.d_sorttype s_pace=pcdata.s_pace d_pace=pcdata.d_pace s_gno=pcdata.s_gno d_gno=pcdata.d_gno s_sub_gno=pcdata.s_sub_gno d_sub_gno=pcdata.d_sub_gno s_gtype=pcdata.s_gtype d_gtype=pcdata.d_gtype s_sdlen=pcdata.s_sdlen d_sdlen=pcdata.d_sdlen s_sdtype=pcdata.s_sdtype d_sdtype=pcdata.d_sdtype s_timing=pcdata.s_timing d_timing=pcdata.d_timing s_notes=pcdata.s_notes d_notes=pcdata.d_notes s_judge=pcdata.s_judge d_judge=pcdata.d_judge s_judgeAdj=pcdata.s_judgeAdj d_judgeAdj=pcdata.d_judgeAdj s_hispeed=pcdata.s_hispeed d_hispeed=pcdata.d_hispeed s_liflen=pcdata.s_liflen d_liflen=pcdata.d_liflen s_disp_judge=pcdata.s_disp_judge d_disp_judge=pcdata.d_disp_judge s_opstyle=pcdata.s_opstyle d_opstyle=pcdata.d_opstyle s_graph_score=pcdata.s_graph_score d_graph_score=pcdata.d_graph_score s_auto_scrach=pcdata.s_auto_scrach d_auto_scrach=pcdata.d_auto_scrach s_gauge_disp=pcdata.s_gauge_disp d_gauge_disp=pcdata.d_gauge_disp s_lane_brignt=pcdata.s_lane_brignt d_lane_brignt=pcdata.d_lane_brignt s_camera_layout=pcdata.s_camera_layout d_camera_layout=pcdata.d_camera_layout s_ghost_score=pcdata.s_ghost_score d_ghost_score=pcdata.d_ghost_score s_tsujigiri_disp=pcdata.s_tsujigiri_disp d_tsujigiri_disp=pcdata.d_tsujigiri_disp s_auto_adjust=pcdata.s_auto_adjust d_auto_adjust=pcdata.d_auto_adjust s_timing_split=pcdata.s_timing_split d_timing_split=pcdata.d_timing_split s_visualization=pcdata.s_visualization d_visualization=pcdata.d_visualization)
|
||||
lightning_play_data(dpnum=lm_playdata.dp_num spnum=lm_playdata.sp_num)
|
||||
lightning_setting(headphone_vol=lm_settings.headphone_vol resistance_dp_left=lm_settings.resistance_dp_left resistance_dp_right=lm_settings.resistance_dp_right resistance_sp_left=lm_settings.resistance_sp_left resistance_sp_right=lm_settings.resistance_sp_right skin_0=lm_custom.premium_skin flg_skin_0="-1")
|
||||
slider(__type="s32" __count="7") #{lm_settings.slider[0]} #{lm_settings.slider[1]} #{lm_settings.slider[2]} #{lm_settings.slider[3]} #{lm_settings.slider[4]} #{lm_settings.slider[5]} #{lm_settings.slider[6]}
|
||||
light(__type="bool" __count="10") #{lm_settings.light[0]} #{lm_settings.light[1]} #{lm_settings.light[2]} #{lm_settings.light[3]} #{lm_settings.light[4]} #{lm_settings.light[5]} #{lm_settings.light[6]} #{lm_settings.light[7]} #{lm_settings.light[8]} #{lm_settings.light[9]}
|
||||
concentration(__type="bool") #{lm_settings.concentration}
|
||||
spdp_rival(flg="-1")
|
||||
bind_eaappli
|
||||
ea_premium_course
|
||||
secret
|
||||
flg1(__type="s64" __count="3") -1 -1 -1
|
||||
flg2(__type="s64" __count="3") -1 -1 -1
|
||||
flg3(__type="s64" __count="3") -1 -1 -1
|
||||
flg4(__type="s64" __count="3") -1 -1 -1
|
||||
leggendaria
|
||||
flg1(__type="s64" __count="3") -1 -1 -1
|
||||
music_memo
|
||||
- for (let m of mArray)
|
||||
folder(play_style=m.play_style folder_id=m.folder_idx name=m.folder_name)
|
||||
music_id(__type="s32" __count="10") #{m.music_ids[0]} #{m.music_ids[1]} #{m.music_ids[2]} #{m.music_ids[3]} #{m.music_ids[4]} #{m.music_ids[5]} #{m.music_ids[6]} #{m.music_ids[7]} #{m.music_ids[8]} #{m.music_ids[9]}
|
||||
qpro_secret
|
||||
head(__type="s64" __count="7") #{custom.qpro_secret_head[0]} #{custom.qpro_secret_head[1]} #{custom.qpro_secret_head[2]} #{custom.qpro_secret_head[3]} #{custom.qpro_secret_head[4]} #{custom.qpro_secret_head[5]} #{custom.qpro_secret_head[6]}
|
||||
hair(__type="s64" __count="7") #{custom.qpro_secret_hair[0]} #{custom.qpro_secret_hair[1]} #{custom.qpro_secret_hair[2]} #{custom.qpro_secret_hair[3]} #{custom.qpro_secret_hair[4]} #{custom.qpro_secret_hair[5]} #{custom.qpro_secret_hair[6]}
|
||||
face(__type="s64" __count="7") #{custom.qpro_secret_face[0]} #{custom.qpro_secret_face[1]} #{custom.qpro_secret_face[2]} #{custom.qpro_secret_face[3]} #{custom.qpro_secret_face[4]} #{custom.qpro_secret_face[5]} #{custom.qpro_secret_face[6]}
|
||||
body(__type="s64" __count="7") #{custom.qpro_secret_body[0]} #{custom.qpro_secret_body[1]} #{custom.qpro_secret_body[2]} #{custom.qpro_secret_body[3]} #{custom.qpro_secret_body[4]} #{custom.qpro_secret_body[5]} #{custom.qpro_secret_body[6]}
|
||||
hand(__type="s64" __count="7") #{custom.qpro_secret_hand[0]} #{custom.qpro_secret_hand[1]} #{custom.qpro_secret_hand[2]} #{custom.qpro_secret_hand[3]} #{custom.qpro_secret_hand[4]} #{custom.qpro_secret_hand[5]} #{custom.qpro_secret_hand[6]}
|
||||
grade(sgid=pcdata.sgid dgid=pcdata.dgid)
|
||||
- for (let d of dArray)
|
||||
g(__type="u8" __count="4") #{d[0]} #{d[1]} #{d[2]} #{d[3]}
|
||||
eisei_data
|
||||
- for (let ed of eArray)
|
||||
detail(grade_type=ed.grade_type grade_id=ed.grade_id stage_num=ed.stage_num clear_type=ed.clear_type option=ed.option)
|
||||
past(__type="s32" __count="3") #{ed.past[0]} #{ed.past[1]} #{ed.past[2]}
|
||||
selected_course(__type="s32" __count="3") #{ed.selected_course[0]} #{ed.selected_course[1]} #{ed.selected_course[2]}
|
||||
max_past(__type="s32" __count="3") #{ed.max_past[0]} #{ed.max_past[1]} #{ed.max_past[2]}
|
||||
max_selected_course(__type="s32" __count="3") #{ed.max_selected_course[0]} #{ed.max_selected_course[1]} #{ed.max_selected_course[2]}
|
||||
skin(__type="s16" __count="20") #{custom.frame} #{custom.turntable} #{custom.note_burst} #{custom.menu_music} #{appendsettings} #{custom.lane_cover} 0 #{custom.category_vox} #{custom.note_skin} #{custom.full_combo_splash} #{custom.note_beam} #{custom.judge_font} 0 #{Number(custom.disable_musicpreview)} #{custom.pacemaker_cover} #{Number(custom.vefx_lock)} #{custom.effect} #{custom.bomb_size} #{Number(custom.disable_hcn_color)} #{custom.first_note_preview}
|
||||
qprodata(__type="u32" __count="5") #{custom.qpro_head} #{custom.qpro_hair} #{custom.qpro_face} #{custom.qpro_hand} #{custom.qpro_body}
|
||||
rlist
|
||||
- for (let rd of rArray)
|
||||
rival(spdp=rd.play_style id=rd.profile[2] id_str=rd.profile[3] djname=rd.profile[0] pid=rd.profile[1] sg=rd.pcdata[0] dg=rd.pcdata[1] sa=rd.pcdata[2] da=rd.pcdata[3])
|
||||
is_robo(__type="bool") 0
|
||||
qprodata(body=rd.qprodata[3] face=rd.qprodata[2] hair=rd.qprodata[0] hand=rd.qprodata[4] head=rd.qprodata[1])
|
||||
shop(name=shop_data.opname)
|
||||
notes_radar(style="0")
|
||||
radar_score(__type="s32" __count="6") #{pcdata.nr_spradar[0]} #{pcdata.nr_spradar[1]} #{pcdata.nr_spradar[2]} #{pcdata.nr_spradar[3]} #{pcdata.nr_spradar[4]} #{pcdata.nr_spradar[5]}
|
||||
notes_radar(style="1")
|
||||
radar_score(__type="s32" __count="6") #{pcdata.nr_dpradar[0]} #{pcdata.nr_dpradar[1]} #{pcdata.nr_dpradar[2]} #{pcdata.nr_dpradar[3]} #{pcdata.nr_dpradar[4]} #{pcdata.nr_dpradar[5]}
|
||||
visitor(anum="10" snum="10" pnum="10" vs_flg="1")
|
||||
step(enemy_damage=pcdata.st_enemy_damage progress=pcdata.st_progress total_point=pcdata.st_total_point enemy_defeat_flg=pcdata.st_enemy_defeat_flg sp_level=pcdata.st_sp_level dp_level=pcdata.st_dp_level sp_fluctuation=pcdata.st_sp_fluctuation dp_fluctuation=pcdata.st_dp_fluctuation mission_clear_num=pcdata.st_mission_clear_num sp_mplay=pcdata.st_sp_mplay dp_mplay=pcdata.st_dp_mplay tips_read_list=pcdata.st_tips_read_list)
|
||||
is_track_ticket(__type="bool") #{pcdata.st_is_track_ticket}
|
||||
achievements(last_weekly=pcdata.achi_lastweekly pack=pcdata.achi_pack pack_comp=pcdata.achi_packcomp rival_crush=pcdata.achi_rivalcrush visit_flg=pcdata.achi_visitflg weekly_num=pcdata.achi_weeklynum)
|
||||
//- i have no idea why this now needs to be 10 instead of 20
|
||||
trophy(__type="s64" __count="10") #{pcdata.achi_trophy[0]} #{pcdata.achi_trophy[1]} #{pcdata.achi_trophy[2]} #{pcdata.achi_trophy[3]} #{pcdata.achi_trophy[4]} #{pcdata.achi_trophy[5]} #{pcdata.achi_trophy[6]} #{pcdata.achi_trophy[7]} #{pcdata.achi_trophy[8]} #{pcdata.achi_trophy[9]}
|
||||
deller(deller=pcdata.deller rate="1")
|
||||
orb_data(rest_orb=pcdata.orb present_orb=pcdata.present_orb)
|
||||
old_linkage_secret_flg(song_battle="-1")
|
||||
arena_data(play_num="2" play_num_dp="1" play_num_sp="1" prev_best_class_sp="20" prev_best_class_dp="20")
|
||||
achieve_data(play_style="0" arena_class="20" rating_value="20" win_count="0" now_winning_streak_count="0" best_winning_streak_count="0" perfect_win_count="0" counterattack_num="0" mission_clear_num="0")
|
||||
achieve_data(play_style="1" arena_class="20" rating_value="20" win_count="0" now_winning_streak_count="0" best_winning_streak_count="0" perfect_win_count="0" counterattack_num="0" mission_clear_num="0")
|
||||
cube_data(cube="0" season_id="0")
|
||||
chat_data(chat_type_0="CHAT CUSTOM 1" chat_type_1="CHAT CUSTOM 2" chat_type_2="CHAT CUSTOM 3" chat_type_3="CHAT CUSTOM 4")
|
||||
is_chat_0(__type="bool") 1
|
||||
is_chat_1(__type="bool") 1
|
||||
is_chat_2(__type="bool") 1
|
||||
is_chat_3(__type="bool") 1
|
||||
skin_customize_flg(skin_frame_flg="-1" skin_bgm_flg="-1" skin_lane_flg3="-1")
|
||||
event_1(event_play_num=pcdata.event_play_num last_select_flyer_id=pcdata.event_last_select_id)
|
||||
- for (let evt of evtArray)
|
||||
flyer_data(flyer_id=evt.flyer_id play_num=evt.play_num last_select_genre=evt.last_select_genre flyer_prog=evt.flyer_prog skill_param=evt.skill_param)
|
||||
- for (let evt2 of evtArray2)
|
||||
genre_data(flyer_id=evt2.flyer_id genre_id=evt2.genre_id play_num=evt2.genre_playnum gauge=evt2.gauge)
|
||||
is_complete(__type="bool") #{evt2.is_complete}
|
||||
floor_infection4(music_list="-1")
|
||||
bemani_vote(music_list="-1")
|
||||
bemani_janken_meeting(music_list="-1")
|
||||
bemani_rush(music_list_ichika="-1" music_list_nono="-1")
|
||||
ultimate_mobile_link(music_list="-1")
|
||||
link_flag
|
||||
bemani_musiq_fes(music_list="-1")
|
||||
busou_linkage(music_list="-1")
|
||||
busou_linkage_2(music_list="-1")
|
||||
valkyrie_linkage(music_list_1="-1" music_list_2="-1" music_list_3="-1")
|
||||
bemani_song_battle(music_list="-1")
|
||||
bemani_mixup(music_list="-1")
|
||||
ccj_linkage(music_list="-1")
|
||||
triple_tribe(music_list="-1")
|
||||
language_setting(language=profile.language)
|
||||
movie_agreement(agreement_version="1")
|
||||
movie_setting
|
||||
hide_name(__type="bool") 0
|
||||
world_tourism
|
||||
- for (let wd of wArray)
|
||||
tour_data(tour_id=wd.tour_id progress=wd.progress)
|
||||
world_tourism_secret_flg
|
||||
flg1(__type="s64" __count="3") -1 -1 -1
|
||||
flg2(__type="s64" __count="3") -1 -1 -1
|
||||
badge
|
||||
- for (let b of bArray)
|
||||
badge_data(category_id=b.id badge_flg_id=b.flg_id badge_flg=b.flg)
|
||||
108
iidx@asphyxia/pug/LDJ/31pcget.pug
Normal file
108
iidx@asphyxia/pug/LDJ/31pcget.pug
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
IIDX31pc(status="0" qproback=custom.qpro_back)
|
||||
pcdata(id=profile.id idstr=profile.idstr name=profile.name pid=profile.pid spnum=pcdata.spnum dpnum=pcdata.dpnum sach=pcdata.sach dach=pcdata.dach mode=pcdata.mode pmode=pcdata.pmode ngrade=pcdata.ngrade rtype=pcdata.rtype player_kind=pcdata.player_kind sp_opt=pcdata.sp_opt dp_opt=pcdata.dp_opt dp_opt2=pcdata.dp_opt2 gpos=pcdata.gpos s_sorttype=pcdata.s_sorttype d_sorttype=pcdata.d_sorttype s_pace=pcdata.s_pace d_pace=pcdata.d_pace s_gno=pcdata.s_gno d_gno=pcdata.d_gno s_sub_gno=pcdata.s_sub_gno d_sub_gno=pcdata.d_sub_gno s_gtype=pcdata.s_gtype d_gtype=pcdata.d_gtype s_sdlen=pcdata.s_sdlen d_sdlen=pcdata.d_sdlen s_sdtype=pcdata.s_sdtype d_sdtype=pcdata.d_sdtype s_timing=pcdata.s_timing d_timing=pcdata.d_timing s_notes=pcdata.s_notes d_notes=pcdata.d_notes s_judge=pcdata.s_judge d_judge=pcdata.d_judge s_judgeAdj=pcdata.s_judgeAdj d_judgeAdj=pcdata.d_judgeAdj s_hispeed=pcdata.s_hispeed d_hispeed=pcdata.d_hispeed s_liflen=pcdata.s_liflen d_liflen=pcdata.d_liflen s_disp_judge=pcdata.s_disp_judge d_disp_judge=pcdata.d_disp_judge s_opstyle=pcdata.s_opstyle d_opstyle=pcdata.d_opstyle s_graph_score=pcdata.s_graph_score d_graph_score=pcdata.d_graph_score s_auto_scrach=pcdata.s_auto_scrach d_auto_scrach=pcdata.d_auto_scrach s_gauge_disp=pcdata.s_gauge_disp d_gauge_disp=pcdata.d_gauge_disp s_lane_brignt=pcdata.s_lane_brignt d_lane_brignt=pcdata.d_lane_brignt s_camera_layout=pcdata.s_camera_layout d_camera_layout=pcdata.d_camera_layout s_ghost_score=pcdata.s_ghost_score d_ghost_score=pcdata.d_ghost_score s_tsujigiri_disp=pcdata.s_tsujigiri_disp d_tsujigiri_disp=pcdata.d_tsujigiri_disp s_auto_adjust=pcdata.s_auto_adjust d_auto_adjust=pcdata.d_auto_adjust s_timing_split=pcdata.s_timing_split d_timing_split=pcdata.d_timing_split s_visualization=pcdata.s_visualization d_visualization=pcdata.d_visualization s_classic_hispeed=pcdata.s_classic_hispeed d_classic_hispeed=pcdata.d_classic_hispeed)
|
||||
lightning_play_data(dpnum=lm_playdata.dp_num spnum=lm_playdata.sp_num)
|
||||
lightning_setting(headphone_vol=lm_settings.headphone_vol resistance_dp_left=lm_settings.resistance_dp_left resistance_dp_right=lm_settings.resistance_dp_right resistance_sp_left=lm_settings.resistance_sp_left resistance_sp_right=lm_settings.resistance_sp_right keyboard_kind=lm_settings.keyboard_kind brightness=lm_settings.brightness)
|
||||
slider(__type="s32" __count="7") #{lm_settings.slider[0]} #{lm_settings.slider[1]} #{lm_settings.slider[2]} #{lm_settings.slider[3]} #{lm_settings.slider[4]} #{lm_settings.slider[5]} #{lm_settings.slider[6]}
|
||||
light(__type="bool" __count="10") #{lm_settings.light[0]} #{lm_settings.light[1]} #{lm_settings.light[2]} #{lm_settings.light[3]} #{lm_settings.light[4]} #{lm_settings.light[5]} #{lm_settings.light[6]} #{lm_settings.light[7]} #{lm_settings.light[8]} #{lm_settings.light[9]}
|
||||
concentration(__type="bool") #{lm_settings.concentration}
|
||||
spdp_rival(flg="-1")
|
||||
bind_eaappli
|
||||
ea_premium_course
|
||||
secret
|
||||
flg1(__type="s64" __count="3") -1 -1 -1
|
||||
flg2(__type="s64" __count="3") -1 -1 -1
|
||||
flg3(__type="s64" __count="3") -1 -1 -1
|
||||
flg4(__type="s64" __count="3") -1 -1 -1
|
||||
leggendaria
|
||||
flg1(__type="s64" __count="3") -1 -1 -1
|
||||
music_memo
|
||||
- for (let m of mArray)
|
||||
folder(play_style=m.play_style folder_id=m.folder_idx name=m.folder_name)
|
||||
music_id(__type="s32" __count="10") #{m.music_ids[0]} #{m.music_ids[1]} #{m.music_ids[2]} #{m.music_ids[3]} #{m.music_ids[4]} #{m.music_ids[5]} #{m.music_ids[6]} #{m.music_ids[7]} #{m.music_ids[8]} #{m.music_ids[9]}
|
||||
music_filter
|
||||
- for (let f of fArray)
|
||||
folder(play_style=f.play_style folder_id=f.folder_id filter_id=f.filter_id value0=f.value0 value1=f.value1)
|
||||
is_valid(__type="bool") #{f.is_valid}
|
||||
qpro_secret
|
||||
head(__type="s64" __count="7") #{custom.qpro_secret_head[0]} #{custom.qpro_secret_head[1]} #{custom.qpro_secret_head[2]} #{custom.qpro_secret_head[3]} #{custom.qpro_secret_head[4]} #{custom.qpro_secret_head[5]} #{custom.qpro_secret_head[6]}
|
||||
hair(__type="s64" __count="7") #{custom.qpro_secret_hair[0]} #{custom.qpro_secret_hair[1]} #{custom.qpro_secret_hair[2]} #{custom.qpro_secret_hair[3]} #{custom.qpro_secret_hair[4]} #{custom.qpro_secret_hair[5]} #{custom.qpro_secret_hair[6]}
|
||||
face(__type="s64" __count="7") #{custom.qpro_secret_face[0]} #{custom.qpro_secret_face[1]} #{custom.qpro_secret_face[2]} #{custom.qpro_secret_face[3]} #{custom.qpro_secret_face[4]} #{custom.qpro_secret_face[5]} #{custom.qpro_secret_face[6]}
|
||||
body(__type="s64" __count="7") #{custom.qpro_secret_body[0]} #{custom.qpro_secret_body[1]} #{custom.qpro_secret_body[2]} #{custom.qpro_secret_body[3]} #{custom.qpro_secret_body[4]} #{custom.qpro_secret_body[5]} #{custom.qpro_secret_body[6]}
|
||||
hand(__type="s64" __count="7") #{custom.qpro_secret_hand[0]} #{custom.qpro_secret_hand[1]} #{custom.qpro_secret_hand[2]} #{custom.qpro_secret_hand[3]} #{custom.qpro_secret_hand[4]} #{custom.qpro_secret_hand[5]} #{custom.qpro_secret_hand[6]}
|
||||
back(__type="s64" __count="7") #{custom.qpro_secret_back[0]} #{custom.qpro_secret_back[1]} #{custom.qpro_secret_back[2]} #{custom.qpro_secret_back[3]} #{custom.qpro_secret_back[4]} #{custom.qpro_secret_back[5]} #{custom.qpro_secret_back[6]}
|
||||
grade(sgid=pcdata.sgid dgid=pcdata.dgid)
|
||||
- for (let d of dArray)
|
||||
g(__type="u8" __count="4") #{d[0]} #{d[1]} #{d[2]} #{d[3]}
|
||||
kiwami_data
|
||||
- for (let ed of eArray)
|
||||
detail(grade_type=ed.grade_type grade_id=ed.grade_id option=ed.option stage_num=ed.stage_num clear_type=ed.clear_type)
|
||||
past(__type="s32" __count="3") #{ed.past[0]} #{ed.past[1]} #{ed.past[2]}
|
||||
selected_course(__type="s32" __count="3") #{ed.selected_course[0]} #{ed.selected_course[1]} #{ed.selected_course[2]}
|
||||
max_past(__type="s32" __count="3") #{ed.max_past[0]} #{ed.max_past[1]} #{ed.max_past[2]}
|
||||
max_selected_course(__type="s32" __count="3") #{ed.max_selected_course[0]} #{ed.max_selected_course[1]} #{ed.max_selected_course[2]}
|
||||
skin(__type="s32" __count="20") #{appendsettings} #{custom.note_burst} #{custom.bomb_size} #{custom.turntable} #{custom.judge_font} #{custom.note_skin} #{custom.note_size} #{Number(custom.disable_musicpreview)} #{Number(custom.vefx_lock)} #{custom.effect} #{custom.menu_music} #{Number(custom.disable_hcn_color)} #{custom.first_note_preview} #{custom.lane_cover} #{custom.pacemaker_cover} #{custom.lift_cover} #{custom.note_beam} #{custom.note_beam_size} #{custom.full_combo_splash} #{custom.frame}
|
||||
tdjskin(__type="s16" __count="4") #{lm_custom.premium_skin} #{lm_custom.premium_bg} 0 0
|
||||
qprodata(__type="u32" __count="5") #{custom.qpro_head} #{custom.qpro_hair} #{custom.qpro_face} #{custom.qpro_hand} #{custom.qpro_body}
|
||||
rlist
|
||||
- for (let rd of rArray)
|
||||
rival(spdp=rd.play_style id=rd.profile[2] id_str=rd.profile[3] djname=rd.profile[0] pid=rd.profile[1] sg=rd.pcdata[0] dg=rd.pcdata[1] sa=rd.pcdata[2] da=rd.pcdata[3])
|
||||
is_robo(__type="bool") 0
|
||||
qprodata(body=rd.qprodata[3] face=rd.qprodata[2] hair=rd.qprodata[0] hand=rd.qprodata[4] head=rd.qprodata[1] back=rd.qprodata[5])
|
||||
shop(name=shop_data.opname)
|
||||
notes_radar(style="0")
|
||||
radar_score(__type="s32" __count="6") #{pcdata.nr_spradar[0]} #{pcdata.nr_spradar[1]} #{pcdata.nr_spradar[2]} #{pcdata.nr_spradar[3]} #{pcdata.nr_spradar[4]} #{pcdata.nr_spradar[5]}
|
||||
notes_radar(style="1")
|
||||
radar_score(__type="s32" __count="6") #{pcdata.nr_dpradar[0]} #{pcdata.nr_dpradar[1]} #{pcdata.nr_dpradar[2]} #{pcdata.nr_dpradar[3]} #{pcdata.nr_dpradar[4]} #{pcdata.nr_dpradar[5]}
|
||||
visitor(anum="10" snum="10" pnum="10" vs_flg="1")
|
||||
step(enemy_damage=pcdata.st_enemy_damage progress=pcdata.st_progress total_point=pcdata.st_total_point enemy_defeat_flg=pcdata.st_enemy_defeat_flg sp_level=pcdata.st_sp_level dp_level=pcdata.st_dp_level sp_fluctuation=pcdata.st_sp_fluctuation dp_fluctuation=pcdata.st_dp_fluctuation mission_clear_num=pcdata.st_mission_clear_num sp_mplay=pcdata.st_sp_mplay dp_mplay=pcdata.st_dp_mplay tips_read_list=pcdata.st_tips_read_list)
|
||||
is_track_ticket(__type="bool") #{pcdata.st_is_track_ticket}
|
||||
packinfo(music_0="-1" music_1="-1" music_2="-1" pack_id="1")
|
||||
achievements(last_weekly=pcdata.achi_lastweekly pack=pcdata.achi_pack pack_comp=pcdata.achi_packcomp rival_crush=pcdata.achi_rivalcrush visit_flg=pcdata.achi_visitflg weekly_num=pcdata.achi_weeklynum)
|
||||
deller(deller=pcdata.deller rate="1")
|
||||
orb_data(rest_orb=pcdata.orb present_orb=pcdata.present_orb)
|
||||
old_linkage_secret_flg(bemani_mixup="-1" ccj_linkage="-1" triple_tribe="-1")
|
||||
arena_data(play_num="2" play_num_dp="1" play_num_sp="1" prev_best_class_sp="20" prev_best_class_dp="20")
|
||||
achieve_data(play_style="0" arena_class="20" rating_value="20" now_top_class_continuing="0" best_top_class_continuing="0" win_count="0" now_winning_streak_count="0" best_winning_streak_count="0" perfect_win_count="0" counterattack_num="0" mission_clear_num="0")
|
||||
achieve_data(play_style="1" arena_class="20" rating_value="20" now_top_class_continuing="0" best_top_class_continuing="0" win_count="0" now_winning_streak_count="0" best_winning_streak_count="0" perfect_win_count="0" counterattack_num="0" mission_clear_num="0")
|
||||
cube_data(cube="0" season_id="0")
|
||||
chat_data(chat_type_0="CHAT CUSTOM 1" chat_type_1="CHAT CUSTOM 2" chat_type_2="CHAT CUSTOM 3" chat_type_3="CHAT CUSTOM 4")
|
||||
is_chat_0(__type="bool") 1
|
||||
is_chat_1(__type="bool") 1
|
||||
is_chat_2(__type="bool") 1
|
||||
is_chat_3(__type="bool") 1
|
||||
skin_customize_flg(skin_frame_flg="-1" skin_turntable_flg="-1" skin_bomb_flg="-1" skin_bgm_flg="-1" skin_lane_flg0="-1" skin_lane_flg1="-1" skin_lane_flg2="-1" skin_lane_flg3="-1" skin_lane_flg4="-1" skin_lane_flg5="-1" skin_notes_flg="-1" skin_fullcombo_flg="-1" skin_keybeam_flg="-1" skin_judgestring_flg="-1")
|
||||
tdjskin_customize_flg(skin_submonitor_flg="-1" skin_subbg_flg="-1")
|
||||
event_1(event_play_num=pcdata.event_play_num last_select_map_id=pcdata.event_last_select_id)
|
||||
if pcdata.event_skip == true
|
||||
is_skip
|
||||
- for (let evt of evtArray)
|
||||
map_data(map_id=evt.map_id play_num=evt.play_num play_num_uc=evt.play_num_uc last_select_pos=evt.last_select_pos map_prog=evt.map_prog gauge=evt.gauge tile_num=evt.tile_num metron_total_get=evt.metron_total_get metron_total_use=evt.metron_total_use bank_date=evt.bank_date grade_bonus=evt.grade_bonus end_bonus=evt.end_bonus carryover_use=evt.carryover_use)
|
||||
- for (let evt2 of evtArray2)
|
||||
building_data(map_id=evt2.map_id pos=evt2.pos building=evt2.building use_tile=evt2.use_tile)
|
||||
- for (let evt3 of evtArray3)
|
||||
shop_data(map_id=evt3.map_id reward_id=evt3.reward_id prog=evt3.prog)
|
||||
if epo_res != null
|
||||
event_2(event_play_num=epo_res.event_play_num after_play_num=epo_res.after_play_num last_select_system_id=epo_res.last_select_system_id gate_key=epo_res.gate_key after_gauge=epo_res.after_gauge last_select_erosion_level=epo_res.last_select_erosion_level pack="-1" erosion_play_num="10" erosion5_clear12_num="10")
|
||||
- for (let data of epo_res_sub)
|
||||
system_data(system_id=data.system_id play_num=data.play_num unlock_prog=data.unlock_prog system_prog=data.system_prog gauge=data.gauge)
|
||||
ultimate_mobile_link(music_list="-1")
|
||||
link_flag
|
||||
valkyrie_linkage(music_list_1="-1" music_list_2="-1" music_list_3="-1")
|
||||
ccj_linkage(music_list="-1")
|
||||
triple_tribe_2(music_list="-1")
|
||||
language_setting(language=profile.language)
|
||||
movie_agreement(agreement_version="1")
|
||||
movie_setting
|
||||
hide_name(__type="bool") 0
|
||||
world_tourism
|
||||
- for (let wd of wArray)
|
||||
tour_data(tour_id=wd.tour_id progress=wd.progress)
|
||||
world_tourism_secret_flg
|
||||
flg1(__type="s64" __count="3") -1 -1 -1
|
||||
flg2(__type="s64" __count="3") -1 -1 -1
|
||||
world_tourism_setting
|
||||
booster(__type="bool") 1
|
||||
bpl_s4_music_unlock
|
||||
badge
|
||||
- for (let b of bArray)
|
||||
badge_data(category_id=b.id badge_flg_id=b.flg_id badge_flg=b.flg)
|
||||
155
iidx@asphyxia/pug/LDJ/32pcget.pug
Normal file
155
iidx@asphyxia/pug/LDJ/32pcget.pug
Normal file
|
|
@ -0,0 +1,155 @@
|
|||
IIDX32pc(status="0")
|
||||
pcdata(id=profile.id idstr=profile.idstr name=profile.name pid=profile.pid spnum=pcdata.spnum dpnum=pcdata.dpnum sach=pcdata.sach dach=pcdata.dach mode=pcdata.mode category=pcdata.category pmode=pcdata.pmode ngrade=pcdata.ngrade rtype=pcdata.rtype bgnflg=pcdata.bgnflg player_kind=pcdata.player_kind sp_opt=pcdata.sp_opt dp_opt=pcdata.dp_opt dp_opt2=pcdata.dp_opt2 gpos=pcdata.gpos s_sorttype=pcdata.s_sorttype d_sorttype=pcdata.d_sorttype s_pace=pcdata.s_pace d_pace=pcdata.d_pace s_gno=pcdata.s_gno d_gno=pcdata.d_gno s_sub_gno=pcdata.s_sub_gno d_sub_gno=pcdata.d_sub_gno s_gtype=pcdata.s_gtype d_gtype=pcdata.d_gtype s_sdlen=pcdata.s_sdlen d_sdlen=pcdata.d_sdlen s_sdtype=pcdata.s_sdtype d_sdtype=pcdata.d_sdtype s_timing=pcdata.s_timing d_timing=pcdata.d_timing s_notes=pcdata.s_notes d_notes=pcdata.d_notes s_judge=pcdata.s_judge d_judge=pcdata.d_judge s_judgeAdj=pcdata.s_judgeAdj d_judgeAdj=pcdata.d_judgeAdj s_hispeed=pcdata.s_hispeed d_hispeed=pcdata.d_hispeed s_liflen=pcdata.s_liflen d_liflen=pcdata.d_liflen s_disp_judge=pcdata.s_disp_judge d_disp_judge=pcdata.d_disp_judge s_opstyle=pcdata.s_opstyle d_opstyle=pcdata.d_opstyle s_graph_score=pcdata.s_graph_score d_graph_score=pcdata.d_graph_score s_auto_scrach=pcdata.s_auto_scrach d_auto_scrach=pcdata.d_auto_scrach s_gauge_disp=pcdata.s_gauge_disp d_gauge_disp=pcdata.d_gauge_disp s_lane_brignt=pcdata.s_lane_brignt d_lane_brignt=pcdata.d_lane_brignt s_camera_layout=pcdata.s_camera_layout d_camera_layout=pcdata.d_camera_layout s_ghost_score=pcdata.s_ghost_score d_ghost_score=pcdata.d_ghost_score s_tsujigiri_disp=pcdata.s_tsujigiri_disp d_tsujigiri_disp=pcdata.d_tsujigiri_disp s_auto_adjust=pcdata.s_auto_adjust d_auto_adjust=pcdata.d_auto_adjust s_timing_split=pcdata.s_timing_split d_timing_split=pcdata.d_timing_split s_visualization=pcdata.s_visualization d_visualization=pcdata.d_visualization s_classic_hispeed=pcdata.s_classic_hispeed d_classic_hispeed=pcdata.d_classic_hispeed movie_thumbnail=pcdata.movie_thumbnail)
|
||||
lightning_play_data(dpnum=lm_playdata.dp_num spnum=lm_playdata.sp_num)
|
||||
lightning_setting(headphone_vol=lm_settings.headphone_vol resistance_dp_left=lm_settings.resistance_dp_left resistance_dp_right=lm_settings.resistance_dp_right resistance_sp_left=lm_settings.resistance_sp_left resistance_sp_right=lm_settings.resistance_sp_right keyboard_kind=lm_settings.keyboard_kind brightness=lm_settings.brightness)
|
||||
slider(__type="s32" __count="7") #{lm_settings.slider[0]} #{lm_settings.slider[1]} #{lm_settings.slider[2]} #{lm_settings.slider[3]} #{lm_settings.slider[4]} #{lm_settings.slider[5]} #{lm_settings.slider[6]}
|
||||
light(__type="bool" __count="10") #{lm_settings.light[0]} #{lm_settings.light[1]} #{lm_settings.light[2]} #{lm_settings.light[3]} #{lm_settings.light[4]} #{lm_settings.light[5]} #{lm_settings.light[6]} #{lm_settings.light[7]} #{lm_settings.light[8]} #{lm_settings.light[9]}
|
||||
concentration(__type="bool") #{lm_settings.concentration}
|
||||
spdp_rival(flg="-1")
|
||||
bind_eaappli
|
||||
ea_premium_course
|
||||
dellar_bonus(rate="100")
|
||||
secret
|
||||
flg1(__type="s64" __count="3") -1 -1 -1
|
||||
flg2(__type="s64" __count="3") -1 -1 -1
|
||||
flg3(__type="s64" __count="3") -1 -1 -1
|
||||
flg4(__type="s64" __count="3") -1 -1 -1
|
||||
flg5(__type="s64" __count="3") -1 -1 -1
|
||||
leggendaria
|
||||
flg1(__type="s64" __count="3") -1 -1 -1
|
||||
flg2(__type="s64" __count="3") -1 -1 -1
|
||||
music_memo
|
||||
- for (let m of mArray)
|
||||
folder(play_style=m.play_style folder_id=m.folder_idx name=m.folder_name)
|
||||
music_id(__type="s32" __count="10") #{m.music_ids[0]} #{m.music_ids[1]} #{m.music_ids[2]} #{m.music_ids[3]} #{m.music_ids[4]} #{m.music_ids[5]} #{m.music_ids[6]} #{m.music_ids[7]} #{m.music_ids[8]} #{m.music_ids[9]}
|
||||
music_filter
|
||||
- for (let f of fArray)
|
||||
folder(play_style=f.play_style folder_id=f.folder_id filter_id=f.filter_id value0=f.value0 value1=f.value1)
|
||||
is_valid(__type="bool") #{f.is_valid}
|
||||
- for (let fs of fsArray)
|
||||
sort(play_style=fs.play_style folder_id=fs.folder_id sort=fs.sort)
|
||||
qpro_secret
|
||||
head(__type="s64" __count="7") #{custom.qpro_secret_head[0]} #{custom.qpro_secret_head[1]} #{custom.qpro_secret_head[2]} #{custom.qpro_secret_head[3]} #{custom.qpro_secret_head[4]} #{custom.qpro_secret_head[5]} #{custom.qpro_secret_head[6]}
|
||||
hair(__type="s64" __count="7") #{custom.qpro_secret_hair[0]} #{custom.qpro_secret_hair[1]} #{custom.qpro_secret_hair[2]} #{custom.qpro_secret_hair[3]} #{custom.qpro_secret_hair[4]} #{custom.qpro_secret_hair[5]} #{custom.qpro_secret_hair[6]}
|
||||
face(__type="s64" __count="7") #{custom.qpro_secret_face[0]} #{custom.qpro_secret_face[1]} #{custom.qpro_secret_face[2]} #{custom.qpro_secret_face[3]} #{custom.qpro_secret_face[4]} #{custom.qpro_secret_face[5]} #{custom.qpro_secret_face[6]}
|
||||
body(__type="s64" __count="7") #{custom.qpro_secret_body[0]} #{custom.qpro_secret_body[1]} #{custom.qpro_secret_body[2]} #{custom.qpro_secret_body[3]} #{custom.qpro_secret_body[4]} #{custom.qpro_secret_body[5]} #{custom.qpro_secret_body[6]}
|
||||
hand(__type="s64" __count="7") #{custom.qpro_secret_hand[0]} #{custom.qpro_secret_hand[1]} #{custom.qpro_secret_hand[2]} #{custom.qpro_secret_hand[3]} #{custom.qpro_secret_hand[4]} #{custom.qpro_secret_hand[5]} #{custom.qpro_secret_hand[6]}
|
||||
back(__type="s64" __count="7") #{custom.qpro_secret_back[0]} #{custom.qpro_secret_back[1]} #{custom.qpro_secret_back[2]} #{custom.qpro_secret_back[3]} #{custom.qpro_secret_back[4]} #{custom.qpro_secret_back[5]} #{custom.qpro_secret_back[6]}
|
||||
grade(sgid=pcdata.sgid dgid=pcdata.dgid)
|
||||
- for (let d of dArray)
|
||||
g(__type="u8" __count="4") #{d[0]} #{d[1]} #{d[2]} #{d[3]}
|
||||
kiwami_data
|
||||
- for (let ed of eArray)
|
||||
detail(grade_type=ed.grade_type grade_id=ed.grade_id option=ed.option stage_num=ed.stage_num clear_type=ed.clear_type)
|
||||
past(__type="s32" __count="3") #{ed.past[0]} #{ed.past[1]} #{ed.past[2]}
|
||||
selected_course(__type="s32" __count="3") #{ed.selected_course[0]} #{ed.selected_course[1]} #{ed.selected_course[2]}
|
||||
max_past(__type="s32" __count="3") #{ed.max_past[0]} #{ed.max_past[1]} #{ed.max_past[2]}
|
||||
max_selected_course(__type="s32" __count="3") #{ed.max_selected_course[0]} #{ed.max_selected_course[1]} #{ed.max_selected_course[2]}
|
||||
skin(__type="s32" __count="20") #{appendsettings} #{custom.note_burst} #{custom.bomb_size} #{custom.turntable} #{custom.judge_font} #{custom.note_skin} #{custom.note_size} #{Number(custom.disable_musicpreview)} #{Number(custom.vefx_lock)} #{custom.effect} #{custom.menu_music} #{Number(custom.disable_hcn_color)} #{custom.first_note_preview} #{custom.lane_cover} #{custom.pacemaker_cover} #{custom.lift_cover} #{custom.note_beam} #{custom.note_beam_size} #{custom.full_combo_splash} #{custom.frame}
|
||||
tdjskin(__type="s32" __count="4") #{lm_custom.premium_skin} #{lm_custom.premium_bg} 0 0
|
||||
qprodata(__type="u32" __count="6") #{custom.qpro_head} #{custom.qpro_hair} #{custom.qpro_face} #{custom.qpro_hand} #{custom.qpro_body} #{custom.qpro_back}
|
||||
rlist
|
||||
- for (let rd of rArray)
|
||||
rival(spdp=rd.play_style id=rd.profile[2] id_str=rd.profile[3] djname=rd.profile[0] pid=rd.profile[1] sg=rd.pcdata[0] dg=rd.pcdata[1] sa=rd.pcdata[2] da=rd.pcdata[3])
|
||||
is_robo(__type="bool") 0
|
||||
qprodata(body=rd.qprodata[3] face=rd.qprodata[2] hair=rd.qprodata[0] hand=rd.qprodata[4] head=rd.qprodata[1] back=rd.qprodata[5])
|
||||
shop(name=shop_data.opname)
|
||||
rlist_sub
|
||||
notes_radar(style="0")
|
||||
radar_score(__type="s32" __count="6") #{pcdata.nr_spradar[0]} #{pcdata.nr_spradar[1]} #{pcdata.nr_spradar[2]} #{pcdata.nr_spradar[3]} #{pcdata.nr_spradar[4]} #{pcdata.nr_spradar[5]}
|
||||
notes_radar(style="1")
|
||||
radar_score(__type="s32" __count="6") #{pcdata.nr_dpradar[0]} #{pcdata.nr_dpradar[1]} #{pcdata.nr_dpradar[2]} #{pcdata.nr_dpradar[3]} #{pcdata.nr_dpradar[4]} #{pcdata.nr_dpradar[5]}
|
||||
visitor(anum="10" snum="10" pnum="10" vs_flg="1")
|
||||
step(enemy_damage=pcdata.st_enemy_damage progress=pcdata.st_progress total_point=pcdata.st_total_point enemy_defeat_flg=pcdata.st_enemy_defeat_flg sp_level=pcdata.st_sp_level dp_level=pcdata.st_dp_level sp_level_h=pcdata.st_sp_level_h dp_level_h=pcdata.st_dp_level_h sp_level_exh=pcdata.st_sp_level_exh dp_level_exh=pcdata.st_dp_level_exh sp_fluctuation=pcdata.st_sp_fluctuation dp_fluctuation=pcdata.st_dp_fluctuation mission_clear_num=pcdata.st_mission_clear_num sp_mplay=pcdata.st_sp_mplay dp_mplay=pcdata.st_dp_mplay tips_read_list=pcdata.st_tips_read_list)
|
||||
is_track_ticket(__type="bool") #{pcdata.st_is_track_ticket}
|
||||
packinfo(music_0="-1" music_1="-1" music_2="-1" pack_id="1")
|
||||
achievements(pack=pcdata.achi_pack pack_comp=pcdata.achi_packcomp last_weekly=pcdata.achi_lastweekly weekly_num=pcdata.achi_weeklynum visit_flg=pcdata.achi_visitflg rival_crush=pcdata.achi_rivalcrush)
|
||||
deller(deller=pcdata.deller)
|
||||
orb_data(rest_orb=pcdata.orb present_orb=pcdata.present_orb)
|
||||
old_linkage_secret_flg(triple_tribe="-1" triple_tribe_2="-1")
|
||||
arena_data(play_num="2" play_num_dp="1" play_num_sp="1" prev_best_class_sp="20" prev_best_class_dp="20")
|
||||
achieve_data(play_style="0" arena_class="20" rating_value="20" now_top_class_continuing="0" best_top_class_continuing="0" win_count="0" now_winning_streak_count="0" best_winning_streak_count="0" perfect_win_count="0" counterattack_num="0" mission_clear_num="0")
|
||||
achieve_data(play_style="1" arena_class="20" rating_value="20" now_top_class_continuing="0" best_top_class_continuing="0" win_count="0" now_winning_streak_count="0" best_winning_streak_count="0" perfect_win_count="0" counterattack_num="0" mission_clear_num="0")
|
||||
cube_data(cube="0" season_id="0")
|
||||
//-chat_data(chat_type_0="CHAT CUSTOM 1" chat_type_1="CHAT CUSTOM 2" chat_type_2="CHAT CUSTOM 3" chat_type_3="CHAT CUSTOM 4")
|
||||
is_chat_0(__type="bool") 1
|
||||
is_chat_1(__type="bool") 1
|
||||
is_chat_2(__type="bool") 1
|
||||
is_chat_3(__type="bool") 1
|
||||
default_chat
|
||||
skin_customize_flg(skin_frame_flg="-1" skin_turntable_flg="-1" skin_bomb_flg="-1" skin_bgm_flg="-1" skin_lane_flg0="-1" skin_lane_flg1="-1" skin_lane_flg2="-1" skin_lane_flg3="-1" skin_lane_flg4="-1" skin_lane_flg5="-1" skin_notes_flg="-1" skin_fullcombo_flg="-1" skin_keybeam_flg="-1" skin_judgestring_flg="-1")
|
||||
tdjskin_customize_flg(skin_submonitor_flg="-1" skin_subbg_flg="-1")
|
||||
event_1(event_play_num=pcdata.event_play_num last_select_booth_id=pcdata.event_last_select_id)
|
||||
if pcdata.event_skip == true
|
||||
is_skip
|
||||
- for (let evt of evtArray)
|
||||
booth_data(booth_id=evt.booth_id play_num=evt.play_num play_num_uc=evt.play_num_uc success_num=evt.success_num last_select_qpro_index=evt.last_select_qpro_index booth_prog=evt.booth_prog customer_n=evt.customer_n customer_h=evt.customer_h customer_a=evt.customer_a customer_l=evt.customer_l hire_num=evt.hire_num)
|
||||
flg_l(__type="bool") #{evt.flg_l}
|
||||
- for (let evt2 of evtArray2)
|
||||
booth_qpro_data(booth_id=evt2.booth_id index=evt2.index head_parts=evt2.head_parts hair_parts=evt2.hair_parts face_parts=evt2.face_parts body_parts=evt2.body_parts hand_parts=evt2.hand_parts param_n=evt2.param_n param_h=evt2.param_h param_a=evt2.param_a param_l=evt2.param_l exp=evt2.exp performance_date=evt2.performance_date)
|
||||
- for (let evtRival of evtArray3)
|
||||
rival(index=evtRival.index name=evtRival.name iidx_id=evtRival.iidx_id head=evtRival.head hair=evtRival.hair face=evtRival.face body=evtRival.body hand=evtRival.hand back=evtRival.back)
|
||||
if pinky_ug != null
|
||||
event_2(event_play_num=pinky_ug.event_play_num last_select_hall_id=pinky_ug.last_select_hall_id)
|
||||
- for (let evt4 of pinky_ug_hall)
|
||||
hall_data(hall_id=evt4.hall_id play_num=evt4.play_num last_select_skill_index=evt4.last_select_skill_index hall_prog=evt4.hall_prog defeat_num=evt4.defeat_num pp_0=evt4.pp_0 pp_1=evt4.pp_1 pp_2=evt4.pp_2 pp_3=evt4.pp_3 pp_4=evt4.pp_4 pp_5=evt4.pp_5 skill_1=evt4.skill_1 skill_2=evt4.skill_2 skill_3=evt4.skill_3 cool_1=evt4.cool_1 cool_2=evt4.cool_2 cool_3=evt4.cool_3 param_1=evt4.param_1 param_2=evt4.param_2 param_3=evt4.param_3)
|
||||
- for (let evt5 of pinky_ug_qpro)
|
||||
hall_qpro_data(hall_id=evt5.hall_id index=evt5.index head_parts=evt5.head_parts hair_parts=evt5.hair_parts face_parts=evt5.face_parts body_parts=evt5.body_parts hand_parts=evt5.hand_parts)
|
||||
- for (let evtRival of evtArray3)
|
||||
rival(index=evtRival.index name=evtRival.name iidx_id=evtRival.iidx_id head=evtRival.head hair=evtRival.hair face=evtRival.face body=evtRival.body hand=evtRival.hand back=evtRival.back)
|
||||
ultimate_mobile_link(music_list="-1")
|
||||
link_flag
|
||||
valkyrie_linkage(music_list_1="-1" music_list_2="-1" music_list_3="-1")
|
||||
ccj_linkage(music_list="-1")
|
||||
triple_tribe_3(music_list="-1")
|
||||
triple_tribe_4(music_list="-1")
|
||||
//-reflecbeat_event(music_list="-1")
|
||||
//-beatstream_event(music_list="-1")
|
||||
//-museca_event(music_list="-1")
|
||||
//-pawapuro(prog="" power="")
|
||||
language_setting(language=profile.language)
|
||||
movie_agreement(agreement_version="1")
|
||||
movie_setting
|
||||
hide_name(__type="bool") 0
|
||||
- for (let ebe of ebeArray)
|
||||
extra_boss_event(phase=ebe.phase extra=ebe.extra extra_b=ebe.extra_b onemore=ebe.onemore onemore_b=ebe.onemore_b)
|
||||
world_tourism
|
||||
- for (let wd of wArray)
|
||||
tour_data(tour_id=wd.tour_id progress=wd.progress)
|
||||
world_tourism_secret_flg
|
||||
flg1(__type="s64" __count="3") -1 -1 -1
|
||||
flg2(__type="s64" __count="3") -1 -1 -1
|
||||
world_tourism_setting
|
||||
booster(__type="bool") 1
|
||||
badge
|
||||
- for (let b of bArray)
|
||||
badge_data(category_id=b.id badge_flg_id=b.flg_id badge_flg=b.flg)
|
||||
activity
|
||||
today(day_id=activityDayId date=activityTimestamp)
|
||||
if activityTodaySP != null
|
||||
today_data(play_style=activityTodaySP.play_style music_num=activityTodaySP.music_num play_time=activityTodaySP.play_time keyboard_num=activityTodaySP.keyboard_num scratch_num=activityTodaySP.scratch_num)
|
||||
clear_update_num(__type="s32" __count="13") #{activityTodaySP.clear_update_num[0]} #{activityTodaySP.clear_update_num[1]} #{activityTodaySP.clear_update_num[2]} #{activityTodaySP.clear_update_num[3]} #{activityTodaySP.clear_update_num[4]} #{activityTodaySP.clear_update_num[5]} #{activityTodaySP.clear_update_num[6]} #{activityTodaySP.clear_update_num[7]} #{activityTodaySP.clear_update_num[8]} #{activityTodaySP.clear_update_num[9]} #{activityTodaySP.clear_update_num[10]} #{activityTodaySP.clear_update_num[11]} #{activityTodaySP.clear_update_num[12]}
|
||||
score_update_num(__type="s32" __count="13") #{activityTodaySP.score_update_num[0]} #{activityTodaySP.score_update_num[1]} #{activityTodaySP.score_update_num[2]} #{activityTodaySP.score_update_num[3]} #{activityTodaySP.score_update_num[4]} #{activityTodaySP.score_update_num[5]} #{activityTodaySP.score_update_num[6]} #{activityTodaySP.score_update_num[7]} #{activityTodaySP.score_update_num[8]} #{activityTodaySP.score_update_num[9]} #{activityTodaySP.score_update_num[10]} #{activityTodaySP.score_update_num[11]} #{activityTodaySP.score_update_num[12]}
|
||||
if activityTodayDP != null
|
||||
today_data(play_style=activityTodayDP.play_style music_num=activityTodayDP.music_num play_time=activityTodayDP.play_time keyboard_num=activityTodayDP.keyboard_num scratch_num=activityTodayDP.scratch_num)
|
||||
clear_update_num(__type="s32" __count="13") #{activityTodayDP.clear_update_num[0]} #{activityTodayDP.clear_update_num[1]} #{activityTodayDP.clear_update_num[2]} #{activityTodayDP.clear_update_num[3]} #{activityTodayDP.clear_update_num[4]} #{activityTodayDP.clear_update_num[5]} #{activityTodayDP.clear_update_num[6]} #{activityTodayDP.clear_update_num[7]} #{activityTodayDP.clear_update_num[8]} #{activityTodayDP.clear_update_num[9]} #{activityTodayDP.clear_update_num[10]} #{activityTodayDP.clear_update_num[11]} #{activityTodayDP.clear_update_num[12]}
|
||||
score_update_num(__type="s32" __count="13") #{activityTodayDP.score_update_num[0]} #{activityTodayDP.score_update_num[1]} #{activityTodayDP.score_update_num[2]} #{activityTodayDP.score_update_num[3]} #{activityTodayDP.score_update_num[4]} #{activityTodayDP.score_update_num[5]} #{activityTodayDP.score_update_num[6]} #{activityTodayDP.score_update_num[7]} #{activityTodayDP.score_update_num[8]} #{activityTodayDP.score_update_num[9]} #{activityTodayDP.score_update_num[10]} #{activityTodayDP.score_update_num[11]} #{activityTodayDP.score_update_num[12]}
|
||||
weekly
|
||||
week_data(play_style="0")
|
||||
- for (let a of activityWeekSP)
|
||||
week(week_index=a.week_index week_id=a.week_id date=a.date music_num=a.music_num play_time=a.play_time keyboard_num=a.keyboard_num scratch_num=a.scratch_num)
|
||||
clear_update_num(__type="s32" __count="13") #{a.clear_update_num[0]} #{a.clear_update_num[1]} #{a.clear_update_num[2]} #{a.clear_update_num[3]} #{a.clear_update_num[4]} #{a.clear_update_num[5]} #{a.clear_update_num[6]} #{a.clear_update_num[7]} #{a.clear_update_num[8]} #{a.clear_update_num[9]} #{a.clear_update_num[10]} #{a.clear_update_num[11]} #{a.clear_update_num[12]}
|
||||
score_update_num(__type="s32" __count="13") #{a.score_update_num[0]} #{a.score_update_num[1]} #{a.score_update_num[2]} #{a.score_update_num[3]} #{a.score_update_num[4]} #{a.score_update_num[5]} #{a.score_update_num[6]} #{a.score_update_num[7]} #{a.score_update_num[8]} #{a.score_update_num[9]} #{a.score_update_num[10]} #{a.score_update_num[11]} #{a.score_update_num[12]}
|
||||
week_data(play_style="1")
|
||||
- for (let b of activityWeekDP)
|
||||
week(week_index=b.week_index week_id=b.week_id date=b.date music_num=b.music_num play_time=b.play_time keyboard_num=b.keyboard_num scratch_num=b.scratch_num)
|
||||
clear_update_num(__type="s32" __count="13") #{b.clear_update_num[0]} #{b.clear_update_num[1]} #{b.clear_update_num[2]} #{b.clear_update_num[3]} #{b.clear_update_num[4]} #{b.clear_update_num[5]} #{b.clear_update_num[6]} #{b.clear_update_num[7]} #{b.clear_update_num[8]} #{b.clear_update_num[9]} #{b.clear_update_num[10]} #{b.clear_update_num[11]} #{b.clear_update_num[12]}
|
||||
score_update_num(__type="s32" __count="13") #{b.score_update_num[0]} #{b.score_update_num[1]} #{b.score_update_num[2]} #{b.score_update_num[3]} #{b.score_update_num[4]} #{b.score_update_num[5]} #{b.score_update_num[6]} #{b.score_update_num[7]} #{b.score_update_num[8]} #{b.score_update_num[9]} #{b.score_update_num[10]} #{b.score_update_num[11]} #{b.score_update_num[12]}
|
||||
mynews
|
||||
- for (let a of activityMynews)
|
||||
detail(play_style=a.play_style kind=a.kind news_no=a.news_no index=a.index day_id=a.day_id music_id=a.music_id note_id=a.note_id best_score=a.best_score now_score=a.now_score now_clear=a.now_clear news_time=a.news_time)
|
||||
best_result
|
||||
- for (let a of activityMybest)
|
||||
best_data(play_style=a.play_style kind=a.kind play_side=a.play_side music_id=a.music_id note_id=a.note_id target_graph=a.target_graph target_score=a.target_score pacemaker=a.pacemaker best_clear=a.best_clear best_score=a.best_score best_misscount=a.best_misscount now_clear=a.now_clear now_score=a.now_score now_misscount=a.now_misscount now_pgreat=a.now_pgreat now_great=a.now_great now_good=a.now_good now_bad=a.now_bad now_poor=a.now_poor now_combo=a.now_combo now_fast=a.now_fast now_slow=a.now_slow option=a.option option2=a.option_2 gauge_type=a.gauge_type result_type=a.result_type update_date=a.update_date)
|
||||
ghost_gauge_data(__type="bin") #{a.ghost_gauge_data}
|
||||
is_special_result(__type="bool") #{a.is_special_result}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user