layaair-example

This commit is contained in:
King Wang 2021-07-21 23:11:13 +08:00
parent c3aa1f918e
commit 4bfe797a89
203 changed files with 257823 additions and 0 deletions

View File

@ -0,0 +1,30 @@
{
"configurations": [
{
"type": "node",
"request": "launch",
"name": "mocha current file",
"program": "${workspaceFolder}/node_modules/mocha/bin/_mocha",
"args": [
"${file}"
],
"internalConsoleOptions": "openOnSessionStart",
"cwd": "${workspaceFolder}"
},
{
"type": "node",
"request": "launch",
"name": "ts-node current file",
"protocol": "inspector",
"args": [
"${relativeFile}"
],
"cwd": "${workspaceRoot}",
"runtimeArgs": [
"-r",
"ts-node/register"
],
"internalConsoleOptions": "openOnSessionStart"
}
]
}

View File

@ -0,0 +1,3 @@
{
"typescript.tsdk": "node_modules\\typescript\\lib"
}

View File

@ -0,0 +1,35 @@
# TSRPC Server
## Run
### Local Dev Server
```
npm run dev
```
### Build
```
npm run build
```
---
## Files
### Generate ServiceProto
```
npm run proto
```
### Generate API templates
```
npm run api
```
### Sync shared code to client
```
npm run sync
```
> If you chose symlink when using `create-tsrpc-app`, it would re-create the symlink instead of copy files.

View File

@ -0,0 +1,23 @@
{
"name": "tsrpc-app-backend",
"version": "0.1.0",
"main": "index.js",
"private": true,
"scripts": {
"proto": "tsrpc proto -i src/shared/protocols -o src/shared/protocols/serviceProto.ts",
"sync": "tsrpc sync --from src/shared --to ../frontend/src/shared",
"api": "tsrpc api -i src/shared/protocols/serviceProto.ts -o src/api",
"dev": "onchange \"src/**/*.ts\" -i -k -- ts-node \"src/index.ts\"",
"build": "tsrpc build"
},
"devDependencies": {
"@types/node": "^15.14.1",
"onchange": "^7.1.0",
"ts-node": "^10.0.0",
"tsrpc-cli": "^2.0.3",
"typescript": "^4.3.5"
},
"dependencies": {
"tsrpc": "^3.0.4"
}
}

View File

@ -0,0 +1,26 @@
import { ApiCall } from "tsrpc";
import { ReqAddData, ResAddData } from "../shared/protocols/PtlAddData";
import { AllData } from "./ApiGetData";
// This is a demo code file
// Feel free to delete it
export async function ApiAddData(call: ApiCall<ReqAddData, ResAddData>) {
// Error
if (call.req.content === '') {
call.error('Content is empty');
return;
}
let time = new Date();
AllData.unshift({
content: call.req.content,
time: time
})
console.log('AllData', AllData)
// Success
call.succ({
time: time
});
}

View File

@ -0,0 +1,13 @@
import { ApiCall } from "tsrpc";
import { ReqGetData, ResGetData } from "../shared/protocols/PtlGetData";
// This is a demo code file
// Feel free to delete it
export async function ApiGetData(call: ApiCall<ReqGetData, ResGetData>) {
call.succ({
data: AllData
})
}
export const AllData: { content: string, time: Date }[] = [];

View File

@ -0,0 +1,60 @@
import { IncomingMessage } from "http";
import * as path from "path";
import { Counter, HttpConnection, HttpServer } from "tsrpc";
import { serviceProto, ServiceType } from "./shared/protocols/serviceProto";
// Create the Server
const server = new HttpServer(serviceProto, {
port: 3000,
cors: '*'
});
// Init
export async function init(context: any, callback: (err: Error | null, data: any) => void) {
// Auto implement APIs
await server.autoImplementApi(path.resolve(__dirname, 'api'));
callback(null, '');
}
const connCounter = new Counter(1);
// Handler
export function handler(httpReq: IncomingMessage, httpRes: {
setStatusCode: (code: number) => void,
setHeader: (key: string, value: string) => void,
deleteHeader: (key: string) => void,
send: (body: Buffer | string) => void
}, context: any) {
httpRes.setStatusCode(200);
httpRes.setHeader('X-Powered-By', `TSRPC`);
httpRes.setHeader('Access-Control-Allow-Origin', '*');
httpRes.setHeader('Access-Control-Allow-Headers', 'Content-Type,*');
if (httpReq.method === 'OPTIONS') {
httpRes.send('');
return;
}
let chunks: Buffer[] = [];
httpReq.on('data', data => {
chunks.push(data);
});
let conn: HttpConnection<ServiceType> | undefined;
httpReq.on('end', async () => {
let isJSON = false;
conn = new HttpConnection({
server: 'FAAS' as any,
id: '' + connCounter.getNext(),
ip: '???',
httpReq: httpReq,
httpRes: { end: httpRes.send.bind(httpRes) } as any,
isJSON: isJSON
});
await server.flows.postConnectFlow.exec(conn, conn.logger);
let buf = chunks.length === 1 ? chunks[0] : Buffer.concat(chunks);
server['_onRecvBuffer'](conn, buf);
});
}

View File

@ -0,0 +1,38 @@
import * as path from "path";
import { HttpConnection, HttpServer } from "tsrpc";
import { serviceProto } from "./shared/protocols/serviceProto";
// Create the Server
const server = new HttpServer(serviceProto, {
port: 3000,
cors: '*',
socketTimeout: 0,
keepAliveTimeout: 0
});
server.flows.preRecvBufferFlow.push(v => {
let conn = v.conn as HttpConnection;
if (conn.httpReq.method === 'GET') {
conn.httpRes.end('TSRPC Server');
return undefined;
}
return v;
})
// Entry function
async function main() {
// Auto implement APIs
await server.autoImplementApi(path.resolve(__dirname, 'api'));
// TODO
// Prepare something... (e.g. connect the db)
await server.start();
};
main().catch(e => {
// Exit if any error during the startup
server.logger.error(e);
process.exit(-1);
});

View File

@ -0,0 +1,10 @@
// This is a demo code file
// Feel free to delete it
export interface ReqAddData {
content: string;
}
export interface ResAddData {
time: Date
}

View File

@ -0,0 +1,13 @@
// This is a demo code file
// Feel free to delete it
export interface ReqGetData {
}
export interface ResGetData {
data: {
content: string,
time: Date
}[]
}

View File

@ -0,0 +1,98 @@
import { ServiceProto } from 'tsrpc-proto';
import { ReqAddData, ResAddData } from './PtlAddData';
import { ReqGetData, ResGetData } from './PtlGetData';
// This is a demo service proto file (auto generated)
// Feel free to delete it
export interface ServiceType {
api: {
"AddData": {
req: ReqAddData,
res: ResAddData
},
"GetData": {
req: ReqGetData,
res: ResGetData
}
},
msg: {
}
}
export const serviceProto: ServiceProto<ServiceType> = {
"version": 1,
"services": [
{
"id": 0,
"name": "AddData",
"type": "api"
},
{
"id": 1,
"name": "GetData",
"type": "api"
}
],
"types": {
"PtlAddData/ReqAddData": {
"type": "Interface",
"properties": [
{
"id": 0,
"name": "content",
"type": {
"type": "String"
}
}
]
},
"PtlAddData/ResAddData": {
"type": "Interface",
"properties": [
{
"id": 0,
"name": "time",
"type": {
"type": "Date"
}
}
]
},
"PtlGetData/ReqGetData": {
"type": "Interface"
},
"PtlGetData/ResGetData": {
"type": "Interface",
"properties": [
{
"id": 0,
"name": "data",
"type": {
"type": "Array",
"elementType": {
"type": "Interface",
"properties": [
{
"id": 0,
"name": "content",
"type": {
"type": "String"
}
},
{
"id": 1,
"name": "time",
"type": {
"type": "Date"
}
}
]
}
}
}
]
}
}
};

View File

@ -0,0 +1,18 @@
{
"compilerOptions": {
"lib": [
"es2018"
],
"module": "commonjs",
"target": "es2018",
"outDir": "dist",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"moduleResolution": "node"
},
"include": [
"src"
]
}

2
examples/layaair/frontend/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
.rpt2_cache
node_modules

View File

@ -0,0 +1,75 @@
// v1.2.7
//是否使用IDE自带的node环境和插件设置false后则使用自己环境(使用命令行方式执行)
const useIDENode = process.argv[0].indexOf("LayaAir") > -1 ? true : false;
const useCMDNode = process.argv[1].indexOf("layaair2-cmd") > -1 ? true : false;
function useOtherNode(){
return useIDENode||useCMDNode;
}
//获取Node插件和工作路径
let ideModuleDir = useOtherNode() ? process.argv[1].replace("gulp\\bin\\gulp.js", "").replace("gulp/bin/gulp.js", "") : "";
let workSpaceDir = useOtherNode() ? process.argv[2].replace("--gulpfile=", "").replace("\\.laya\\compile.js", "").replace("/.laya/compile.js", "") : "./../";
const gulp = require(ideModuleDir + "gulp");
const rollup = require(ideModuleDir + "rollup");
const typescript = require(ideModuleDir + 'rollup-plugin-typescript2');//typescript2 plugin
const glsl = require(ideModuleDir + 'rollup-plugin-glsl');
const path = require('path');
const fs = require('fs');
// 如果是发布时调用编译功能增加prevTasks
let prevTasks = "";
if (global.publish) {
prevTasks = ["loadConfig"];
}
gulp.task("compile", prevTasks, function () {
// 发布时调用编译功能,判断是否点击了编译选项
if (global.publish) {
workSpaceDir = global.workSpaceDir; // 发布时调用编译workSpaceDir使用publish.js里的变量
let forceCompile = !fs.existsSync(path.join(workSpaceDir, "bin", "js", "bundle.js")); // 发布时,并且没有编译过,则强制编译
if (!global.config.compile && !forceCompile) {
return;
}
}
return rollup.rollup({
input: workSpaceDir + '/src/Main.ts',
onwarn:(waring,warn)=>{
if(waring.code == "CIRCULAR_DEPENDENCY"){
console.log("warnning Circular dependency:");
console.log(waring);
}
},
treeshake: false, //建议忽略
plugins: [
typescript({
tsconfig:workSpaceDir + "/tsconfig.json",
check: true, //Set to false to avoid doing any diagnostic checks on the code
tsconfigOverride:{compilerOptions:{removeComments: true}},
include:/.*.ts/,
}),
glsl({
// By default, everything gets included
include: /.*(.glsl|.vs|.fs)$/,
sourceMap: false,
compress:false
}),
/*terser({
output: {
},
numWorkers:1,//Amount of workers to spawn. Defaults to the number of CPUs minus 1
sourcemap: false
})*/
]
}).then(bundle => {
return bundle.write({
file: workSpaceDir + '/bin/js/bundle.js',
format: 'iife',
name: 'laya',
sourcemap: false
});
}).catch(err=>{
console.log(err);
});
});

View File

@ -0,0 +1 @@
{"username":null,"gameId":null}

View File

@ -0,0 +1,92 @@
// v1.0.0
const ideModuleDir = global.ideModuleDir;
const workSpaceDir = global.workSpaceDir;
const fs = require("fs");
const path = require("path");
const crypto = require("crypto");
function getEngineVersion() {
let coreLibPath = path.join(workSpaceDir, "bin", "libs", "laya.core.js");
let isHasCoreLib = fs.existsSync(coreLibPath);
let isOldAsProj = fs.existsSync(`${workSpaceDir}/asconfig.json`) && !isHasCoreLib;
let isNewTsProj = fs.existsSync(`${workSpaceDir}/src/tsconfig.json`) && !isHasCoreLib;
let EngineVersion;
if (isHasCoreLib) {
let con = fs.readFileSync(coreLibPath, "utf8");
let matchList = con.match(/Laya\.version\s*=\s*['"]([0-9\.]+(beta)?.*)['"]/);
if (!Array.isArray(matchList)) {
return null;
}
EngineVersion = matchList[1];
} else { // newts项目和旧版本as项目
if (isOldAsProj) {
let coreLibFilePath = path.join(workSpaceDir, "libs", "laya", "src", "Laya.as");
if (!fs.existsSync(coreLibFilePath)) {
return null;
}
let con = fs.readFileSync(coreLibFilePath, "utf8");
let matchList = con.match(/version:String\s*=\s*['"]([0-9\.]+(beta)?.*)['"]/);
if (!Array.isArray(matchList)) {
return null;
}
EngineVersion = matchList[1];
} else if (isNewTsProj) {
let coreLibFilePath = path.join(workSpaceDir, "libs", "Laya.ts");
if (!fs.existsSync(coreLibFilePath)) {
return null;
}
let con = fs.readFileSync(coreLibFilePath, "utf8");
let matchList = con.match(/static\s*version:\s*string\s*=\s*['"]([0-9\.]+(beta)?.*)['"]/);
if (!Array.isArray(matchList)) {
return null;
}
EngineVersion = matchList[1];
}
}
// 特殊处理因为历史原因我们有一些4位的正式版本调整为3位
if (EngineVersion && /[\d\.]+/.test(EngineVersion) && EngineVersion.split(".").length > 3) {
let verList = EngineVersion.split(".");
verList.length = 3;
EngineVersion = verList.join(".");
}
return EngineVersion;
}
function getFileMd5(filePath) {
return new Promise(function(resolve, reject) {
let md5 = crypto.createHash('md5');
let stream = fs.createReadStream(filePath);
stream.on("data", function(data) {
md5.update(data);
});
stream.on("end", function() {
let md5Str = md5.digest('hex');
return resolve(md5Str);
});
});
}
function canUsePluginEngine(libsVersion, minVersionNum) {
let compileMacthList = minVersionNum.match(/^(\d+)\.(\d+)\.(\d+)/);
let matchList = libsVersion.match(/^(\d+)\.(\d+)\.(\d+)/);
let
s1n = Number(matchList[1]), // src first number
s2n = Number(matchList[2]),
s3n = Number(matchList[3]),
t1n = Number(compileMacthList[1]), // to first number
t2n = Number(compileMacthList[2]),
t3n = Number(compileMacthList[3]);
if (s1n > t1n) {
return true;
}
if (s1n === t1n && s2n > t2n) {
return true;
}
if (s1n === t1n && s2n === t2n && s3n >= t3n) {
return true;
}
return false;
}
module.exports = { getEngineVersion, getFileMd5, canUsePluginEngine }

View File

@ -0,0 +1,794 @@
// v1.8.18
//是否使用IDE自带的node环境和插件设置false后则使用自己环境(使用命令行方式执行)
const useIDENode = process.argv[0].indexOf("LayaAir") > -1 ? true : false;
const useCMDNode = process.argv[1].indexOf("layaair2-cmd") > -1 ? true : false;
const pubLayame = process.argv.length >= 4 && process.argv[3].startsWith("--config") && process.argv[3].endsWith("layame.json");
function useOtherNode(){
return useIDENode||useCMDNode ||pubLayame;
}
//获取Node插件和工作路径
const ideModuleDir = useOtherNode() ? process.argv[1].replace("gulp\\bin\\gulp.js", "").replace("gulp/bin/gulp.js", "") : "";
const workSpaceDir = useOtherNode() ? process.argv[2].replace("--gulpfile=", "").replace("\\.laya\\publish.js", "").replace("/.laya/publish.js", "") + "/" : "./../";
global.ideModuleDir = ideModuleDir;
global.workSpaceDir = workSpaceDir;
//引用插件模块
const gulp = require(ideModuleDir + "gulp");
const fs = require("fs");
const path = require("path");
const childProcess = require("child_process");
const uglify = require(ideModuleDir + 'gulp-uglify-es').default;
const jsonminify = require(ideModuleDir + "gulp-jsonminify");
const image = require(ideModuleDir + "gulp-image");
const rev = require(ideModuleDir + "gulp-rev");
const revdel = require(ideModuleDir + "gulp-rev-delete-original");
const revCollector = require(ideModuleDir + 'gulp-rev-collector');
const del = require(ideModuleDir + "del");
const requireDir = require(ideModuleDir + 'require-dir');
const babel = require(ideModuleDir + 'gulp-babel');
// 结合compile.js使用
global.publish = true;
const fileList = ["compile.js", "pub_utils.js", "publish_xmgame.js", "publish_oppogame.js", "publish_vivogame.js", "publish_biligame.js",
"publish_alipaygame.js", "publish_wxgame.js", "publish_bdgame.js", "publish_qqgame.js", "publish_bytedancegame.js", "publish_hwgame.js",
"publish_taobaominiapp.js", "publish_youkugame.js", "publish_taobaowidget.js", "publish_layame.js"];
requireDir('./', {
filter: function (fullPath) {
// 只用到了compile.js和publish.js
if (fileList.includes(path.basename(fullPath))) {
return true;
} else {
return false;
}
}
});
const QUICKGAMELIST = ["xmgame", "oppogame", "vivogame", "hwgame"];
// 清理临时文件夹,加载配置
let config,
releaseDir,
binPath,
platform = "web",
isOpendataProj = false,
platformCopyTask = [],// 平台脚本拷贝任务
platformTask = [], // 平台需要执行的任务
commandSuffix = ".cmd",
adbPath = "adb",
opensslPath = "openssl";
let execTask;
//任务对照列表
const copyTasks = {
"layame": "copy",
"taobaowidget": "preCreate_TBWidget",
"youkugame": "copyPlatformFile_youku",
"taobaominiapp": "preCreate_TBMini",
"hwgame": "copyPlatformFile_HW",
"bytedancegame": "copyPlatformFile_ByteDance",
"biligame": "copyPlatformFile_Bili",
"Alipaygame": "copyPlatformFile_Alipay",
"vivogame": "copyPlatformFile_VIVO",
"oppogame": "copyPlatformFile_OPPO",
"xmgame": "copyPlatformFile_XM",
"bdgame": "copyPlatformFile_BD",
"qqgame": "copyPlatformFile_QQ",
"wxgame": "fitwasm_WX",
"web": "copyPlatformLibsJsFile"
}
const tasks = {
"layame": "buildLayaMeProj",
"taobaowidget": "buildTBWidgetProj",
"youkugame": "buildYKProj",
"taobaominiapp": "buildTBMiniProj",
"hwgame": "buildHWProj",
"bytedancegame": "buildByteDanceProj",
"biligame": "buildBiliProj",
"Alipaygame": "buildAlipayProj",
"vivogame": "buildVivoProj",
"oppogame": "buildOPPOProj",
"xmgame": "buildXiaomiProj",
"bdgame": "buildBDProj",
"qqgame": "buildQQProj",
"wxgame": "buildWXProj",
"web": "version2"
}
// 是否build指定部分debug版本layame)
let buildOptions = null;
function toBuildPart(part) {
if (!buildOptions) {
return true;
}
if ('all' == part ) {
return buildOptions.type == 'all';
}
if (buildOptions.type == 'all') {
return true;
}
return (buildOptions.buildList.includes(part));
}
if (!useOtherNode() && process.argv.length > 5 && process.argv[4] == "--config") {
platform = process.argv[5].replace(".json", "");
}
if (useOtherNode() && process.argv.length >= 4 && process.argv[3].startsWith("--config") && process.argv[3].endsWith(".json")) {
platform = process.argv[3].match(/(\w+).json/)[1];
platformCopyTask.push(copyTasks[platform]);
platformTask.push(tasks[platform]);
execTask = process.argv[4];
}
let isDebugLayaMe = false;
gulp.task("loadConfig", function (cb) {
let _path;
if (!useOtherNode()) {
_path = platform + ".json";
releaseDir = "../release/" + platform;
binPath = "../bin/";
}
if (useOtherNode()) {
_path = path.join(workSpaceDir, ".laya", `${platform}.json`);
releaseDir = path.join(workSpaceDir, "release", platform).replace(/\\/g, "/");
binPath = path.join(workSpaceDir, "bin").replace(/\\/g, "/");
}
global.platform = platform;
let file = fs.readFileSync(_path, "utf-8");
if (file) {
if (platform == 'layame') {
let tmpconfig = JSON.parse(file);
if (tmpconfig.debugLayaMe) {
// 如本地调试版layame
releaseDir = path.join(workSpaceDir, 'layaMe').replace(/\\/g, "/");
isDebugLayaMe = true;
}
}
if ([...QUICKGAMELIST, "taobaominiapp", "taobaowidget"].includes(platform)) {
file = file.replace(/\$basePath/g, releaseDir + "/temprelease");
} else {
file = file.replace(/\$basePath/g, releaseDir);
}
config = JSON.parse(file);
global.config = config;
if (isDebugLayaMe) {
buildOptions = config.buildOptions;
}
// 我们遇到一个bug当使用min库同时开启es6toes5后es6toes5时会将min库部分变量忽略导致程序出错
// 我们原来的逻辑: 1) 将min库es6toes5 2) 将转换后的库重新压缩
// 所以当使用min库同时开启es6toes5时我们将: 1) 使用普通库 2) 开启js压缩
if (config.useMinJsLibs && config.es6toes5) {
config.useMinJsLibs = false;
config.compressJs = true;
}
}
// 是否是开放域项目
let projInfoPath = path.join(workSpaceDir, path.basename(workSpaceDir) + ".laya");
let isExist = fs.existsSync(projInfoPath);
if (isExist) {
try {
let projInfo = fs.readFileSync(projInfoPath, "utf8");
projInfo = projInfo && JSON.parse(projInfo);
isOpendataProj = projInfo.layaProType === 12;
} catch (e) {}
}
// 其他变量的初始化
let layarepublicPath = path.join(ideModuleDir, "../", "code", "layarepublic");
if (!fs.existsSync(layarepublicPath)) {
layarepublicPath = path.join(ideModuleDir, "../", "out", "layarepublic");
}
global.layarepublicPath = layarepublicPath;
if (process.platform === "darwin") {
commandSuffix = "";
}
global.commandSuffix = commandSuffix;
// 检查环境中是否存在adb和openssl
let otherLibsPath = path.join(layarepublicPath, "../", "vs", "layaEditor", "libs");
childProcess.exec("adb version", (error, stdout, stderr) => {
if (error) {
if (process.platform === "darwin") {
adbPath = path.join(otherLibsPath, "adb", "darwin", "adb");
} else {
adbPath = path.join(otherLibsPath, "adb", "win", "adb.exe");
}
adbPath = `"${adbPath}"`;
}
global.adbPath = adbPath;
if (global.opensslPath) {
cb();
}
});
childProcess.exec("openssl version", (error, stdout, stderr) => {
if (error) {
if (process.platform === "darwin") {
opensslPath = path.join(otherLibsPath, "openssl", "darwin", "bin", "openssl");
} else {
opensslPath = path.join(otherLibsPath, "openssl", "win", "bin", "openssl.exe");
let opensslCnfPath = path.join(otherLibsPath, "openssl", "win", "bin", "openssl.cfg");
// 特别的当windows没有openssl时需要额外的OPENSSL_CONF设置变量
// childProcess.execSync(`set OPENSSL_CONF=${opensslCnfPath}`);
process.env.OPENSSL_CONF = opensslCnfPath;
console.log("OPENSSL_CONF: " + childProcess.execSync("echo %OPENSSL_CONF%"));
}
opensslPath = `"${opensslPath}"`;
}
global.opensslPath = opensslPath;
if (global.adbPath) {
cb();
}
});
});
// 清理release文件夹
gulp.task("clearReleaseDir", ["compile"], function (cb) {
if (platform === "layame" && execTask !== "clearReleaseDir") { // 特殊的layame项目不执行清理命令
return cb();
}
if (config.clearReleaseDir) {
let delList = [`${releaseDir}/**`, releaseDir + "_pack"];
if (config.packfileTargetValue) {
delList.push(config.packfileTargetValue);
}
// 小米快游戏使用即存的项目删掉Laya工程文件保留小米环境项目文件
if (platform === "xmgame") {
let xmProj = path.join(releaseDir, config.xmInfo.projName);
// 这里不是node-glob语法详见: https://github.com/sindresorhus/del
delList = [`${xmProj}/**`, `!${xmProj}`, `!${xmProj}/node_modules/**`, `!${xmProj}/sign/**`, `!${xmProj}/{babel.config.js,main.js,manifest.json,package.json,package-lock.json}`];
} else if (platform === "oppogame") {
let oppoProjSrc = path.join(releaseDir, config.oppoInfo.projName);
delList = [`${oppoProjSrc}/**`, `!${oppoProjSrc}`, `!${oppoProjSrc}/{manifest.json,main.js}`];
} else if (platform === "vivogame") {
let vvProj = path.join(releaseDir, config.vivoInfo.projName);
let vvProjSrc = path.join(vvProj, "src");
// 这里不是node-glob语法详见: https://github.com/sindresorhus/del
delList = [`${vvProj}/engine/**`, `${vvProj}/laya-library/**`, `${vvProj}/config/**`,
`${vvProjSrc}/**`, `!${vvProjSrc}`, `!${vvProjSrc}/{game.js,manifest.json}`];
} else if (platform === "hwgame") {
let hwProjSrc = path.join(releaseDir, config.hwInfo.projName);
delList = [`${hwProjSrc}/**`, `!${hwProjSrc}`, `!${hwProjSrc}/{game.js,manifest.json}`];
}
// 保留平台配置文件
if (config.keepPlatformFile) {
if (["wxgame", "qqgame", "Alipaygame", "bytedancegame"].includes(platform)) {
delList = delList.concat(`!${releaseDir}`, `!${releaseDir}/{game.js,game.json,project.config.json}`);
} else if (platform === "bdgame") {
delList = delList.concat(`!${releaseDir}`, `!${releaseDir}/{game.js,game.json,project.swan.json}`);
} else if (platform === "biligame") {
delList = delList.concat(`!${releaseDir}`, `!${releaseDir}/{game.js,game.json}`);
} else if (platform === "taobaominiapp") { // 特殊的,淘宝平台,仅删除确定为我们的文件
// 删除 node_modules/layaengine/libs 下引擎文件,以及 node_modules/layaengine/laya.js 文件
// 删除 pages/index 下除 game.js,game.json,game.axml 外所有文件
// release/taobaominiapp/node_modules/layaengine/adapter.js 必更新
// 删除最外层除 .tea .mini-ide node_modules pages app.acss app.js app.json mini.project.json package.json
delList = [`${releaseDir}/node_modules/layaengine/libs`, `${releaseDir}/node_modules/layaengine/laya.js`,
`${releaseDir}/**`, `!${releaseDir}`, `!${releaseDir}/.tea/**`, `!${releaseDir}/.mini-ide/**·`,
`!${releaseDir}/node_modules/**`, `!${releaseDir}/pages/**`, `!${releaseDir}/{app.acss,app.js,app.json,mini.project.json,package.json}`,
// `${releaseDir}/node_modules/layaengine`, `!${releaseDir}/node_modules/layaengine`, `!${releaseDir}/node_modules/layaengine/{adapter.js,index.js/package.json}`,
`${releaseDir}/pages/index/**`, `!${releaseDir}/pages/index`, `!${releaseDir}/pages/index/{game.js,game.json,game.axml}`];
} else if (platform === "taobaowidget") {
delList = [`${releaseDir}/widget/component/**`, `!${releaseDir}/widget/component`, `!${releaseDir}/widget/component/{game.js,game.json,game.axml,game.acss,package.json}`];
}
}
del(delList, { force: true }).then(paths => {
cb();
}).catch((err) => {
throw err;
})
} else cb();
});
// copy bin文件到release文件夹
gulp.task("copyFile", ["clearReleaseDir"], function () {
let baseCopyFilter = [`${workSpaceDir}/bin/**/*.*`, `!${workSpaceDir}/bin/indexmodule.html`, `!${workSpaceDir}/bin/import/*.*`];
// 只拷贝index.js中引用的类库
if (config.onlyIndexJS) {
baseCopyFilter = baseCopyFilter.concat(`!${workSpaceDir}/bin/libs/**/*.*`);
}
if (platform === "wxgame" && isOpendataProj) { // 开放域项目微信发布,仅拷贝用到的文件
config.copyFilesFilter = [`${workSpaceDir}/bin/js/bundle.js`, `${workSpaceDir}/bin/index.js`, `${workSpaceDir}/bin/game.js`];
if (config.projectType !== "as") { // 开放域精简类库
config.copyFilesFilter.push(`${workSpaceDir}/bin/libs/laya.opendata.js`);
}
} else if (platform === "wxgame") { // 微信项目不拷贝index.html不拷贝百度bin目录中的文件
config.copyFilesFilter = baseCopyFilter.concat([`!${workSpaceDir}/bin/{project.swan.json,swan-game-adapter.js}`]);
} else if (platform === "bdgame") { // 百度项目不拷贝index.html不拷贝微信bin目录中的文件
config.copyFilesFilter = baseCopyFilter.concat([`!${workSpaceDir}/bin/{project.config.json,weapp-adapter.js}`]);
} else if (platform === "layame") { // layame项目不拷贝js/libs文件夹不拷贝index.js文件
config.copyFilesFilter = baseCopyFilter.concat([`!${workSpaceDir}/bin/{js/**/*.*,libs/**/*.*,index.js,version.json}`]);
} else { // 除微信、百度外不拷贝微信、百度在bin目录中的文件
config.copyFilesFilter = baseCopyFilter.concat([`!${workSpaceDir}/bin/{game.js,game.json,project.config.json,weapp-adapter.js,project.swan.json,swan-game-adapter.js}`]);
}
// bili/alipay/qq不拷贝index.html
if (platform !== "web") {
config.copyFilesFilter = config.copyFilesFilter.concat([`!${workSpaceDir}/bin/index.html`]);
}
// 快游戏,需要新建一个快游戏项目,拷贝的只是项目的一部分,将文件先拷贝到文件夹的临时目录中去
if ([...QUICKGAMELIST, "taobaominiapp", "taobaowidget"].includes(platform)) {
releaseDir = global.tempReleaseDir = path.join(releaseDir, "temprelease").replace(/\\/g, "/");
}
if (config.exclude) { // 排除文件
config.excludeFilter.forEach(function(item, index, list) {
releaseDir = releaseDir.replace(/\\/g, "/");
config.excludeFilter[index] = item.replace(releaseDir, binPath);
});
config.copyFilesFilter = config.copyFilesFilter.concat(config.excludeFilter);
}
global.releaseDir = releaseDir;
if (isDebugLayaMe) {
if (!toBuildPart('ui')) {
if(!fs.existsSync(releaseDir)) {
fs.mkdirSync(releaseDir);
}
return;
}
}
var stream = gulp.src(config.copyFilesFilter, { base: `${workSpaceDir}/bin` });
return stream.pipe(gulp.dest(releaseDir));
});
// 使用min版本引擎
gulp.task("useMinJsLibs", ["copyFile"], function () {
if (!config.useMinJsLibs) {
return;
}
if (platform === "wxgame" && isOpendataProj) { // 开放域项目微信发布,拷贝文件时已经拷贝类库文件了
return;
}
// 开放域项目as语言没有libs目录mac系统报错
let libs = path.join(workSpaceDir, "bin", "libs");
if (!fs.existsSync(libs)) {
return;
}
if (platform === "layame") {
return;
}
// 分析index.js
let indexJSPath = path.join(releaseDir, "index.js");
let indexJsContent = fs.readFileSync(indexJSPath, "utf8");
let libsList = indexJsContent.match(/loadLib\(['"]libs\/[\w-./]+\.(js|wasm)['"]\)/g);
if (!libsList) {
return;
}
let
item,
libsName = "",
minLibsName = "";
for (let i = 0, len = libsList.length; i < len; i++) {
item = libsList[i];
libsName = item.match(/loadLib\(['"]libs\/([\w-./]+\.(js|wasm))['"]\)/);
minLibsName = `min/${libsName[1].replace(".js", ".min.js")}`;
indexJsContent = indexJsContent.replace(libsName[1], minLibsName);
}
fs.writeFileSync(indexJSPath, indexJsContent);
});
// copy libs中的js文件到release文件夹
gulp.task("copyLibsJsFile", ["useMinJsLibs"], function () {
if (platform === "layame") {
return;
}
// 分析index.js
let indexJSPath = path.join(releaseDir, "index.js");
let indexJsContent = fs.readFileSync(indexJSPath, "utf8");
indexJsContent = indexJsContent.replace(/(loadLib\(['"]libs\/[\w-./]+\.wasm\.wasm['"]\))/g, "// $1");
fs.writeFileSync(indexJSPath, indexJsContent, "utf8");
if (!config.onlyIndexJS) {
return;
}
if (platform === "wxgame" && isOpendataProj) { // 开放域项目微信发布,拷贝文件时已经拷贝类库文件了
return;
}
// 开放域项目as语言没有libs目录mac系统报错
let libs = path.join(workSpaceDir, "bin", "libs");
if (!fs.existsSync(libs)) {
return;
}
let libsList = indexJsContent.match(/loadLib\(['"]libs\/[\w-./]+\.(js|wasm)['"]\)/g);
if (!libsList) {
libsList = [];
}
let
item,
libsName = "",
libsStr = "";
for (let i = 0, len = libsList.length; i < len; i++) {
item = libsList[i];
libsName = item.match(/loadLib\(['"]libs\/([\w-./]+\.(js|wasm))['"]\)/);
libsStr += libsStr ? `,${libsName[1]}` : libsName[1];
}
// 发布web项目如果使用了physics3D默认拷贝runtime
if (platform === "web" && libsStr.includes("laya.physics3D")) {
if (config.useMinJsLibs) {
libsStr += ',min/laya.physics3D.runtime.min.js';
} else {
libsStr += ',laya.physics3D.runtime.js';
}
}
let copyLibsList = [`${workSpaceDir}/bin/libs/{${libsStr}}`];
if (!libsStr.includes(",")) {
copyLibsList = [`${workSpaceDir}/bin/libs/${libsStr}`];
}
var stream = gulp.src(copyLibsList, { base: `${workSpaceDir}/bin` });
return stream.pipe(gulp.dest(releaseDir));
});
gulp.task("fitwasm", ["copyLibsJsFile"], function() {
let
phy3dWasmJs = path.join(releaseDir, "libs", "laya.physics3D.wasm.js"),
phy3dWasmMinJs = path.join(releaseDir, "libs", "min", "laya.physics3D.wasm.min.js");
let isPhy3dWasmJsExist = fs.existsSync(phy3dWasmJs);
let isPhy3dWasmMinJsExist = fs.existsSync(phy3dWasmMinJs);
if (!isPhy3dWasmJsExist && !isPhy3dWasmMinJsExist) {
return;
}
let phy3dWasmName = isPhy3dWasmJsExist ? phy3dWasmJs : phy3dWasmMinJs;
con = fs.readFileSync(phy3dWasmName, "utf8");
if (isPhy3dWasmJsExist) {
con = con.replace(/laya\.physics3D\.wasm\.wasm/mg, "libs/laya.physics3D.wasm.wasm");
}
if (isPhy3dWasmMinJsExist) {
con = con.replace(/laya\.physics3D\.wasm\.wasm/mg, "libs/min/laya.physics3D.wasm.wasm");
}
fs.writeFileSync(phy3dWasmName, con, "utf8");
})
gulp.task("copyPlatformLibsJsFile", ["fitwasm"], function () {
if (platform === "wxgame" && isOpendataProj) { // 开放域项目微信发布,拷贝文件时已经拷贝类库文件了
return;
}
// 开放域项目as语言没有libs目录mac系统报错
let libs = path.join(workSpaceDir, "bin", "libs");
if (!fs.existsSync(libs)) {
return;
}
if (platform === "web") {
return;
}
if (platform === "layame") {
return;
}
let platformLibName = "";
switch (platform) {
case "wxgame":
platformLibName = "laya.wxmini.js";
break;
case "qqgame":
platformLibName = "laya.qqmini.js";
break;
case "bdgame":
platformLibName = "laya.bdmini.js";
break;
case "Alipaygame":
platformLibName = "laya.Alipaymini.js";
break;
case "biligame":
platformLibName = "laya.bilimini.js";
break;
case "bytedancegame":
platformLibName = "laya.ttmini.js";
break;
case "oppogame":
platformLibName = "laya.quickgamemini.js";
break;
case "vivogame":
platformLibName = "laya.vvmini.js";
break;
case "xmgame":
platformLibName = "laya.xmmini.js";
break;
case "hwgame":
platformLibName = "laya.hwmini.js";
break;
case "taobaominiapp":
platformLibName = "laya.tbmini.js";
break;
case "taobaowidget":
platformLibName = "laya.tbpluginmini.js";
break;
}
let copyPath = `${workSpaceDir}/bin/libs`;
if (config.useMinJsLibs) {
platformLibName = platformLibName.replace(".js", ".min.js");
copyPath = path.join(copyPath, "min");
}
let copyLibPath = path.join(copyPath, platformLibName);
var stream = gulp.src(copyLibPath, { base: `${workSpaceDir}/bin` });
return stream.pipe(gulp.dest(releaseDir));
});
// es6toes5
gulp.task("es6toes5", platformCopyTask, function() {
if (config.es6toes5) {
process.env.BROWSERSLIST_IGNORE_OLD_DATA = true;
return gulp.src(`${releaseDir}/**/*.js`, { base: releaseDir })
.pipe(babel({
presets: ['@babel/env'],
compact: false // 1) 为规避500K限制不能为"auto" 2) 为便于调试并防止开发者误解已经经过压缩调整为false
}))
.on('error', function (err) {
console.warn(err.toString());
})
.pipe(gulp.dest(releaseDir));
}
})
// 压缩json
gulp.task("compressJson", ["es6toes5"], function () {
if (platform === "layame" && isDebugLayaMe) {
if (!toBuildPart('all')) {
return;
}
}
if (config.compressJson) {
return gulp.src(config.compressJsonFilter, { base: releaseDir })
.pipe(jsonminify())
.pipe(gulp.dest(releaseDir));
}
});
// 压缩js
gulp.task("compressJs", ["compressJson"], function () {
let compressJsFilter = null;
if (platform === "layame" && isDebugLayaMe) {
if (!toBuildPart('all')) {
return;
}
}
if (!config.compressJs) {
if (config.es6toes5 && config.useMinJsLibs) { // 如果开启了es6toes5并使用了压缩版类库
console.log("发布提示:\n 您当前开启了es6toes5并使用了压缩版类库为了保证符合预期脚本将对min文件夹下类库进行压缩");
compressJsFilter = [`${releaseDir}/libs/min/**/*.js`];
}
} else {
if (config.es6toes5 && config.useMinJsLibs) { // 如果开启了es6toes5并使用了压缩版类库
console.log("发布提示:\n 您当前开启了es6toes5并使用了压缩版类库为了保证符合预期脚本将对min文件夹下类库进行压缩");
compressJsFilter = config.compressJsFilter;
let index = compressJsFilter.indexOf(`!${releaseDir}/libs/min/**/*.js`)
if (index !== -1) {
compressJsFilter.splice(index, 1);
}
} else {
compressJsFilter = config.compressJsFilter;
}
}
if (!compressJsFilter) {
return;
}
let options = {
mangle: {
keep_fnames:true
}
}
if (["taobaominiapp", "taobaowidget"].includes(platform)) {
options = {
mangle: {
keep_fnames:true,
// sequences: false, // 不使用逗号
reserved: ["window"]
}
}
}
console.log("compressJsFilter: ", compressJsFilter);
return gulp.src(compressJsFilter, { base: releaseDir })
.pipe(uglify(options))
.on('error', function (err) {
console.warn(err.toString());
})
.pipe(gulp.dest(releaseDir));
});
// 压缩pngjpg
gulp.task("compressImage", ["compressJs"], function () {
// if (platform === "layame") {
// return;
// }
if (platform === "layame" && isDebugLayaMe) {
if (!toBuildPart('ui')) {
return;
}
}
if (config.compressImage) {
return gulp.src(config.compressImageFilter, { base: releaseDir })
.pipe(image({
pngquant: true, //PNG优化工具
optipng: false, //PNG优化工具
zopflipng: true, //PNG优化工具
jpegRecompress: false, //jpg优化工具
mozjpeg: true, //jpg优化工具
guetzli: false, //jpg优化工具
gifsicle: false, //gif优化工具
svgo: false, //SVG优化工具
concurrent: 10, //并发线程数
quiet: true //是否是静默方式
// optipng: ['-i 1', '-strip all', '-fix', '-o7', '-force'],
// pngquant: ['--speed=1', '--force', 256],
// zopflipng: ['-y', '--lossy_8bit', '--lossy_transparent'],
// jpegRecompress: ['--strip', '--quality', 'medium', '--min', 40, '--max', 80],
// mozjpeg: ['-optimize', '-progressive'],
// guetzli: ['--quality', 85]
}))
.pipe(gulp.dest(releaseDir));
}
});
// 生成版本管理信息
gulp.task("version1", ["compressImage"], function () {
if (platform === "layame") {
return;
}
if (config.version) {
return gulp.src(config.versionFilter, { base: releaseDir })
.pipe(rev())
.pipe(gulp.dest(releaseDir))
.pipe(revdel())
.pipe(rev.manifest("version.json"))
.pipe(gulp.dest(releaseDir));
}
});
// 更新index.js的hash值
gulp.task("renameIndexJs", ["version1"], function (cb) {
if (platform === "layame") {
return cb();
}
if (config.version) {
let versionPath = releaseDir + "/version.json";
let versionCon = fs.readFileSync(versionPath, "utf8");
versionCon = JSON.parse(versionCon);
let indexJSPath;
let indexJsStr = (versionCon && versionCon["index.js"]) ? versionCon["index.js"] : "index.js";
indexJSPath = releaseDir + "/" + indexJsStr;
return new Promise((resolve, reject) => {
let srcList = [versionPath, indexJSPath];
gulp.src(srcList)
.pipe(revCollector())
.pipe(gulp.dest(releaseDir));
setTimeout(resolve, 1500);
}).then(function() {
return new Promise(async function(resolve, reject) {
// index-xxx.js => index.js
let indexJsOrigin = path.join(releaseDir, "index.js")
fs.renameSync(indexJSPath, indexJsOrigin);
gulp.src(indexJsOrigin, { base: releaseDir })
.pipe(rev())
.pipe(gulp.dest(releaseDir))
.pipe(revdel())
.pipe(rev.manifest({
path: versionPath,
merge: true
}))
.pipe(gulp.dest("./")); // 注意这里不能是releaseDir (https://segmentfault.com/q/1010000002876613)
setTimeout(cb, 2000);
})
}).catch(function(e) {
throw e;
})
} else {
cb();
}
});
// 修改版本文件名
gulp.task("renameVersionJson", ["renameIndexJs"] , function () {
if (platform === "layame") {
return;
}
if (config.version) {
// 如果启用版本管理则修改version文件名
console.log('releaseDir', releaseDir);
let versionJsonJsOrigin = path.join(releaseDir, "version.json");
let versionPath = versionJsonJsOrigin;// releaseDir + "/version.json";
gulp.src(versionJsonJsOrigin, { base: releaseDir })
.pipe(rev())
.pipe(rev.manifest({
path: versionPath,
merge: true
}))
.pipe(gulp.dest("./"))
.on('end', function () {
let versionJsonJsOrigin = path.join(releaseDir, "version.json");
let versionConStr = fs.readFileSync(versionJsonJsOrigin, "utf8");
let versionCon = JSON.parse(versionConStr);
console.log('versionCon',versionCon );
let renameVersionJson = path.join(releaseDir, versionCon['version.json']);
// fs.renameSync(versionJsonJsOrigin, renameVersionJson);
// 最后再删除versionjson
fs.writeFileSync(renameVersionJson, versionConStr, 'utf8');
// 修改js/bundle.js里加载version.json路径
var bundleJSPath = path.join(releaseDir, versionCon['js/bundle.js']) ;
bundleJSStr = fs.readFileSync(bundleJSPath, "utf8");
bundleJSStr = bundleJSStr.replace('Laya.ResourceVersion.enable(\"version.json\"', `Laya.ResourceVersion.enable("${versionCon['version.json']}"`);
fs.writeFileSync(bundleJSPath, bundleJSStr, "utf8");
});
}
});
// 替换index.html/game.js/main.js以及index.js里面的变化的文件名
gulp.task("version2", ["renameVersionJson"], function () {
if (platform === "layame") {
return;
}
if (config.version) {
//替换index.html和index.js里面的文件名称
let htmlPath = releaseDir + "/index.html";
let versionPath = releaseDir + "/version.json";
let gameJSPath = releaseDir + "/game.js";
let mainJSPath = releaseDir + "/main.js";
let indexJSPath;
let versionCon = fs.readFileSync(versionPath, "utf8");
versionCon = JSON.parse(versionCon);
let indexJsStr = (versionCon && versionCon["index.js"]) ? versionCon["index.js"] : "index.js";
indexJSPath = releaseDir + "/" + indexJsStr;
// 替换config.packfileFullValue中的路径
let packfileStr = JSON.stringify(config.packfileFullValue).replace(/\\\\/g, "/");
let tempPackfile = `${workSpaceDir}/.laya/configTemp.json`;
fs.writeFileSync(tempPackfile, packfileStr, "utf8");
let srcList = [versionPath, indexJSPath, tempPackfile];
if (fs.existsSync(htmlPath)) {
srcList.push(htmlPath);
}
if (fs.existsSync(gameJSPath)) {
srcList.push(gameJSPath);
}
if (fs.existsSync(mainJSPath)) {
srcList.push(mainJSPath);
}
return gulp.src(srcList)
.pipe(revCollector())
.pipe(gulp.dest(releaseDir));
}
});
// 筛选4M包
gulp.task("packfile", platformTask, function() {
if (platform === "layame") {
return;
}
let taobaoFolders = "";
switch (platform) {
case "taobaominiapp":
taobaoFolders = "pages/index";
break;
case "taobaowidget":
taobaoFolders = "widget/component";
break;
default:
taobaoFolders = "quickgame";
}
if (config.version) {
releaseDir = releaseDir.replace("temprelease", taobaoFolders);
// 从release目录取得带有版本号的目录
let tempPackfile = `${workSpaceDir}/.laya/configTemp.json`;
let releasePackfile = `${releaseDir}/configTemp.json`;
let packfileStr = fs.readFileSync(releasePackfile, "utf8");
config.packfileFullValue = JSON.parse(packfileStr);
// 删掉临时目录
fs.unlinkSync(tempPackfile);
fs.unlinkSync(releasePackfile);
}
if (["taobaominiapp", "taobaowidget"].includes(platform)) {
releaseDir = releaseDir.replace("/temprelease", "").replace(`/${taobaoFolders}`, "");
for (let len = config.packfileFullValue.length, i = 0; i < len; i++) {
config.packfileFullValue[i] = config.packfileFullValue[i].replace("temprelease", "");
}
}
if (config.packfile) { // 提取本地包(文件列表形式)
return gulp.src(config.packfileFullValue, { base: releaseDir })
.pipe(gulp.dest(config.packfileTargetValue || releaseDir + "_pack"));
}
if (platform === "layame") {
return;
}
if (config.version) {
let versionJsonJsOrigin = path.join(releaseDir, "version.json");
fs.unlinkSync(versionJsonJsOrigin);
}
});
// 起始任务
gulp.task("publish", ["packfile"] , function () {
console.log("All tasks completed!");
});

View File

@ -0,0 +1,117 @@
// v1.8.0
const ideModuleDir = global.ideModuleDir;
const workSpaceDir = global.workSpaceDir;
//引用插件模块
const gulp = require(ideModuleDir + "gulp");
const fs = require("fs");
const path = require("path");
const revCollector = require(ideModuleDir + 'gulp-rev-collector');
let copyLibsTask = ["copyPlatformLibsJsFile"];
let versiontask = ["version2"];
let
config,
releaseDir;
let versionCon; // 版本管理version.json
let commandSuffix,
layarepublicPath;
gulp.task("preCreate_Alipay", copyLibsTask, function() {
releaseDir = global.releaseDir;
config = global.config;
commandSuffix = global.commandSuffix;
layarepublicPath = global.layarepublicPath;
});
gulp.task("copyPlatformFile_Alipay", ["preCreate_Alipay"], function() {
let adapterPath = path.join(layarepublicPath, "LayaAirProjectPack", "lib", "data", "Alipayfiles");
let hasPublishPlatform =
fs.existsSync(path.join(releaseDir, "game.js")) &&
fs.existsSync(path.join(releaseDir, "game.json")) &&
fs.existsSync(path.join(releaseDir, "project.config.json"));
let copyLibsList;
if (hasPublishPlatform) {
copyLibsList = [`${adapterPath}/my-adapter.js`];
} else {
copyLibsList = [`${adapterPath}/*.*`];
}
var stream = gulp.src(copyLibsList);
return stream.pipe(gulp.dest(releaseDir));
});
gulp.task("modifyFile_Alipay", versiontask, function() {
// 修改game.json文件
let gameJsonPath = path.join(releaseDir, "game.json");
let content = fs.readFileSync(gameJsonPath, "utf8");
let conJson = JSON.parse(content);
conJson.screenOrientation = config.AlipayInfo.orientation;
content = JSON.stringify(conJson, null, 4);
fs.writeFileSync(gameJsonPath, content, "utf8");
// 修改game.js
let filePath = path.join(releaseDir, "game.js");
let fileContent = fs.existsSync(filePath) && fs.readFileSync(filePath, "utf8");
let reWriteMainJs = !fs.existsSync(filePath) || !fileContent.includes("Alipaymini");
if (reWriteMainJs) {
fileContent = `require("./my-adapter.js");
require("./libs/laya.Alipaymini.js");\nrequire("./index.js");`;
fs.writeFileSync(filePath, fileContent, "utf8");
}
if (config.version || config.enableVersion) {
let versionPath = releaseDir + "/version.json";
versionCon = fs.readFileSync(versionPath, "utf8");
versionCon = JSON.parse(versionCon);
}
// 修改index.js
let indexJsStr = (versionCon && versionCon["index.js"]) ? versionCon["index.js"] : "index.js";
let indexFilePath = path.join(releaseDir, indexJsStr);
if (!fs.existsSync(indexFilePath)) {
return;
}
let indexFileContent = fs.readFileSync(indexFilePath, "utf8");
indexFileContent = indexFileContent.replace(/loadLib(\(['"])/gm, "require$1./");
fs.writeFileSync(indexFilePath, indexFileContent, "utf8");
})
gulp.task("modifyMinJs_Alipay", ["modifyFile_Alipay"], function() {
// 如果保留了平台文件如果同时取消使用min类库就会出现文件引用不正确的问题
if (config.keepPlatformFile) {
let fileJsPath = path.join(releaseDir, "game.js");
let content = fs.readFileSync(fileJsPath, "utf-8");
content = content.replace(/min\/laya(-[\w\d]+)?\.Alipaymini\.min\.js/gm, "laya.Alipaymini.js");
fs.writeFileSync(fileJsPath, content, 'utf-8');
}
if (!config.useMinJsLibs) {
return;
}
let fileJsPath = path.join(releaseDir, "game.js");
let content = fs.readFileSync(fileJsPath, "utf-8");
content = content.replace(/(min\/)?laya(-[\w\d]+)?\.Alipaymini(\.min)?\.js/gm, "min/laya.Alipaymini.min.js");
fs.writeFileSync(fileJsPath, content, 'utf-8');
});
gulp.task("version_Alipay", ["modifyMinJs_Alipay"], function () {
// 如果保留了平台文件,如果同时开启版本管理,就会出现文件引用不正确的问题
if (config.keepPlatformFile) {
let fileJsPath = path.join(releaseDir, "game.js");
let content = fs.readFileSync(fileJsPath, "utf-8");
content = content.replace(/laya(-[\w\d]+)?\.Alipaymini/gm, "laya.Alipaymini");
content = content.replace(/index(-[\w\d]+)?\.js/gm, "index.js");
fs.writeFileSync(fileJsPath, content, 'utf-8');
}
if (config.version) {
let versionPath = releaseDir + "/version.json";
let gameJSPath = releaseDir + "/game.js";
let srcList = [versionPath, gameJSPath];
return gulp.src(srcList)
.pipe(revCollector())
.pipe(gulp.dest(releaseDir));
}
});
gulp.task("buildAlipayProj", ["version_Alipay"], function() {
console.log("all tasks completed");
});

View File

@ -0,0 +1,163 @@
// v1.8.0
const ideModuleDir = global.ideModuleDir;
const workSpaceDir = global.workSpaceDir;
//引用插件模块
const gulp = require(ideModuleDir + "gulp");
const fs = require("fs");
const path = require("path");
const revCollector = require(ideModuleDir + 'gulp-rev-collector');
let copyLibsTask = ["copyPlatformLibsJsFile"];
let versiontask = ["version2"];
let
config,
releaseDir;
let versionCon; // 版本管理version.json
let commandSuffix,
layarepublicPath;
gulp.task("preCreate_BD", copyLibsTask, function() {
releaseDir = global.releaseDir;
config = global.config;
commandSuffix = global.commandSuffix;
layarepublicPath = global.layarepublicPath;
});
gulp.task("copyPlatformFile_BD", ["preCreate_BD"], function() {
let adapterPath = path.join(layarepublicPath, "LayaAirProjectPack", "lib", "data", "bdfiles");
// 如果新建项目时已经点击了"微信/百度小游戏bin目录快速调试",不再拷贝
let hasPlatform =
fs.existsSync(path.join(workSpaceDir, "bin", "game.js")) &&
fs.existsSync(path.join(workSpaceDir, "bin", "game.json")) &&
fs.existsSync(path.join(workSpaceDir, "bin", "project.swan.json"));
let hasPublishPlatform =
fs.existsSync(path.join(releaseDir, "game.js")) &&
fs.existsSync(path.join(releaseDir, "game.json")) &&
fs.existsSync(path.join(releaseDir, "project.swan.json"));
let copyLibsList;
if (hasPlatform || hasPublishPlatform) {
copyLibsList = [`${adapterPath}/swan-game-adapter.js`];
} else {
copyLibsList = [`${adapterPath}/*.*`];
}
var stream = gulp.src(copyLibsList);
return stream.pipe(gulp.dest(releaseDir));
});
gulp.task("modifyFile_BD", versiontask, function() {
// 修改game.json文件
let gameJsonPath = path.join(releaseDir, "game.json");
let content = fs.readFileSync(gameJsonPath, "utf8");
let conJson = JSON.parse(content);
conJson.deviceOrientation = config.bdInfo.orientation;
content = JSON.stringify(conJson, null, 4);
fs.writeFileSync(gameJsonPath, content, "utf8");
if (config.version) {
let versionPath = releaseDir + "/version.json";
versionCon = fs.readFileSync(versionPath, "utf8");
versionCon = JSON.parse(versionCon);
}
let indexJsStr = (versionCon && versionCon["index.js"]) ? versionCon["index.js"] : "index.js";
// 百度小游戏项目修改index.js
let filePath = path.join(releaseDir, indexJsStr);
if (!fs.existsSync(filePath)) {
return;
}
let fileContent = fs.readFileSync(filePath, "utf8");
fileContent = fileContent.replace(/loadLib(\(['"])/gm, "require$1./");
fs.writeFileSync(filePath, fileContent, "utf8");
});
// 开放域的情况下合并game.js和index.js并删除game.js
gulp.task("openData_BD", ["modifyFile_BD"], function (cb) {
if (config.openDataZone) {
let versionCon;
if (config.version) {
let versionPath = releaseDir + "/version.json";
versionCon = fs.readFileSync(versionPath, "utf8");
versionCon = JSON.parse(versionCon);
}
let indexJsStr = (versionCon && versionCon["index.js"]) ? versionCon["index.js"] : "index.js";
let indexPath = path.join(releaseDir, indexJsStr);
let indexjs = readFile(indexPath);
let gamejs = readFile(releaseDir + "/game.js");
if (gamejs && indexjs) {
gamejs = gamejs.replace(`require("index.js")`, indexjs);
fs.writeFileSync(indexPath, gamejs, 'utf-8');
}
return cb();
}
cb();
});
function readFile(path) {
if (fs.existsSync(path)) {
return fs.readFileSync(path, "utf-8");
}
return null;
}
gulp.task("modifyMinJs_BD", ["openData_BD"], function() {
// 如果保留了平台文件如果同时取消使用min类库就会出现文件引用不正确的问题
if (config.keepPlatformFile) {
let fileJsPath = path.join(releaseDir, "game.js");
let content = fs.readFileSync(fileJsPath, "utf-8");
content = content.replace(/min\/laya(-[\w\d]+)?\.bdmini\.min\.js/gm, "laya.bdmini.js");
fs.writeFileSync(fileJsPath, content, 'utf-8');
}
if (!config.useMinJsLibs) {
return;
}
let fileJsPath = path.join(releaseDir, "game.js");
let content = fs.readFileSync(fileJsPath, "utf-8");
content = content.replace(/(min\/)?laya(-[\w\d]+)?\.bdmini(\.min)?\.js/gm, "min/laya.bdmini.min.js");
fs.writeFileSync(fileJsPath, content, 'utf-8');
});
gulp.task("version_BD", ["modifyMinJs_BD"], function() {
// 如果保留了平台文件,如果同时开启版本管理,就会出现文件引用不正确的问题
if (config.keepPlatformFile) {
let fileJsPath = path.join(releaseDir, "game.js");
let content = fs.readFileSync(fileJsPath, "utf-8");
content = content.replace(/laya(-[\w\d]+)?\.bdmini/gm, "laya.bdmini");
content = content.replace(/index(-[\w\d]+)?\.js/gm, "index.js");
fs.writeFileSync(fileJsPath, content, 'utf-8');
}
if (config.version) {
let versionPath = releaseDir + "/version.json";
let gameJSPath = releaseDir + "/game.js";
let srcList = [versionPath, gameJSPath];
return gulp.src(srcList)
.pipe(revCollector())
.pipe(gulp.dest(releaseDir));
}
});
gulp.task("optimizeOpen_BD", ["version_BD"], function(cb) {
let bdOptimize = config.bdOptimize;
if (!bdOptimize || !bdOptimize.useOptimizeOpen) {
return cb();
}
// 首屏加载优化(秒开)修改game.json
let filePath = path.join(releaseDir, "game.json");
if (!fs.existsSync(filePath)) {
return cb();
}
let fileContent = fs.readFileSync(filePath, "utf8");
let fileConObj = JSON.parse(fileContent);
if (bdOptimize.preloadRes) {
fileConObj.preloadResources = bdOptimize.preloadResList;
} else {
delete fileConObj.preloadResources;
}
fs.writeFileSync(filePath, JSON.stringify(fileConObj, null, 4), "utf8");
return cb();
});
gulp.task("buildBDProj", ["optimizeOpen_BD"], function() {
console.log("all tasks completed");
});

View File

@ -0,0 +1,106 @@
// v1.8.0
const ideModuleDir = global.ideModuleDir;
const workSpaceDir = global.workSpaceDir;
//引用插件模块
const gulp = require(ideModuleDir + "gulp");
const fs = require("fs");
const path = require("path");
const revCollector = require(ideModuleDir + 'gulp-rev-collector');
let copyLibsTask = ["copyPlatformLibsJsFile"];
let versiontask = ["version2"];
let
config,
releaseDir;
let versionCon; // 版本管理version.json
let commandSuffix,
layarepublicPath;
gulp.task("preCreate_Bili", copyLibsTask, function() {
releaseDir = global.releaseDir;
config = global.config;
commandSuffix = global.commandSuffix;
layarepublicPath = global.layarepublicPath;
});
gulp.task("copyPlatformFile_Bili", ["preCreate_Bili"], function() {
let adapterPath = path.join(layarepublicPath, "LayaAirProjectPack", "lib", "data", "bilifiles");
let hasPublishPlatform =
fs.existsSync(path.join(releaseDir, "game.js")) &&
fs.existsSync(path.join(releaseDir, "game.json"));
let copyLibsList;
if (hasPublishPlatform) {
copyLibsList = [`${adapterPath}/weapp-adapter.js`];
} else {
copyLibsList = [`${adapterPath}/*.*`];
}
var stream = gulp.src(copyLibsList);
return stream.pipe(gulp.dest(releaseDir));
});
gulp.task("modifyFile_Bili", versiontask, function() {
// 修改game.json文件
let gameJsonPath = path.join(releaseDir, "game.json");
let content = fs.readFileSync(gameJsonPath, "utf8");
let conJson = JSON.parse(content);
conJson.deviceOrientation = config.biliInfo.orientation;
content = JSON.stringify(conJson, null, 4);
fs.writeFileSync(gameJsonPath, content, "utf8");
if (config.version) {
let versionPath = releaseDir + "/version.json";
versionCon = fs.readFileSync(versionPath, "utf8");
versionCon = JSON.parse(versionCon);
}
let indexJsStr = (versionCon && versionCon["index.js"]) ? versionCon["index.js"] : "index.js";
// bili小游戏项目修改index.js
let filePath = path.join(releaseDir, indexJsStr);
if (!fs.existsSync(filePath)) {
return;
}
let fileContent = fs.readFileSync(filePath, "utf8");
fileContent = fileContent.replace(/loadLib(\(['"])/gm, "require$1./");
fs.writeFileSync(filePath, fileContent, "utf8");
});
gulp.task("modifyMinJs_Bili", ["modifyFile_Bili"], function() {
// 如果保留了平台文件如果同时取消使用min类库就会出现文件引用不正确的问题
if (config.keepPlatformFile) {
let fileJsPath = path.join(releaseDir, "game.js");
let content = fs.readFileSync(fileJsPath, "utf-8");
content = content.replace(/min\/laya(-[\w\d]+)?\.bilimini\.min\.js/gm, "laya.bilimini.js");
fs.writeFileSync(fileJsPath, content, 'utf-8');
}
if (!config.useMinJsLibs) {
return;
}
let fileJsPath = path.join(releaseDir, "game.js");
let content = fs.readFileSync(fileJsPath, "utf-8");
content = content.replace(/(min\/)?laya(-[\w\d]+)?\.bilimini(\.min)?\.js/gm, "min/laya.bilimini.min.js");
fs.writeFileSync(fileJsPath, content, 'utf-8');
});
gulp.task("version_Bili", ["modifyMinJs_Bili"], function() {
// 如果保留了平台文件,如果同时开启版本管理,就会出现文件引用不正确的问题
if (config.keepPlatformFile) {
let fileJsPath = path.join(releaseDir, "game.js");
let content = fs.readFileSync(fileJsPath, "utf-8");
content = content.replace(/laya(-[\w\d]+)?\.bilimini/gm, "laya.bilimini");
content = content.replace(/index(-[\w\d]+)?\.js/gm, "index.js");
fs.writeFileSync(fileJsPath, content, 'utf-8');
}
if (config.version) {
let versionPath = releaseDir + "/version.json";
let gameJSPath = releaseDir + "/game.js";
let srcList = [versionPath, gameJSPath];
return gulp.src(srcList)
.pipe(revCollector())
.pipe(gulp.dest(releaseDir));
}
});
gulp.task("buildBiliProj", ["version_Bili"], function() {
console.log("all tasks completed");
});

View File

@ -0,0 +1,325 @@
// v1.1.3
const ideModuleDir = global.ideModuleDir;
const workSpaceDir = global.workSpaceDir;
//引用插件模块
const gulp = require(ideModuleDir + "gulp");
const fs = require("fs");
const path = require("path");
const del = require(ideModuleDir + "del");
const revCollector = require(ideModuleDir + 'gulp-rev-collector');
const { getEngineVersion, getFileMd5, canUsePluginEngine } = require("./pub_utils");
const provider = "tt13aa65178c90228a";
const minPluginVersion = "2.7.0";
let fullRemoteEngineList = ["laya.core.js", "laya.filter.js", "laya.ani.js", "laya.tiledmap.js", "laya.d3.js", "laya.html.js", "laya.particle.js", "laya.ui.js", "laya.webgl.js", "laya.filter.js", "laya.d3Plugin.js"];
let copyLibsTask = ["copyPlatformLibsJsFile"];
let versiontask = ["version2"];
let
config,
releaseDir;
let versionCon; // 版本管理version.json
let commandSuffix,
layarepublicPath;
gulp.task("preCreate_ByteDance", copyLibsTask, function() {
releaseDir = global.releaseDir;
config = global.config;
commandSuffix = global.commandSuffix;
layarepublicPath = global.layarepublicPath;
if (config.useMinJsLibs) {
fullRemoteEngineList = fullRemoteEngineList.map((item, index) => {
return item.replace(".js", ".min.js");
})
}
});
gulp.task("copyPlatformFile_ByteDance", ["preCreate_ByteDance"], function() {
let adapterPath = path.join(layarepublicPath, "LayaAirProjectPack", "lib", "data", "bytefiles");
let hasPublishPlatform =
fs.existsSync(path.join(releaseDir, "game.js")) &&
fs.existsSync(path.join(releaseDir, "game.json")) &&
fs.existsSync(path.join(releaseDir, "project.config.json"));
let copyLibsList;
if (hasPublishPlatform) {
copyLibsList = [`${adapterPath}/microgame-adapter.js`];
} else {
copyLibsList = [`${adapterPath}/*.*`];
}
var stream = gulp.src(copyLibsList);
return stream.pipe(gulp.dest(releaseDir));
});
gulp.task("modifyFile_ByteDance", versiontask, function() {
// 修改game.json文件
let gameJsonPath = path.join(releaseDir, "game.json");
let content = fs.readFileSync(gameJsonPath, "utf8");
let conJson = JSON.parse(content);
conJson.deviceOrientation = config.bytedanceInfo.orientation;
if (config.bytedanceInfo.subpack) { // 分包
conJson.subPackages = config.bytedanceSubpack;
// 检测分包目录是否有入口文件
console.log('检查分包文件...');
if (conJson.subPackages) {
for(let i = 0; i < conJson.subPackages.length; i ++) {
let conf = conJson.subPackages[i];
if (conf.root) {
let rootPath = path.join(releaseDir, conf.root);
if (!fs.existsSync(rootPath)) {
throw new Error(`分包文件/目录 ${rootPath} 不存在!`);
}
let jsIndex = rootPath.lastIndexOf('.js');
let jsPath = rootPath;
if (jsIndex < 0 || jsIndex != rootPath.length - 3) {
jsPath = path.join(rootPath, 'game.js');
}
if (!fs.existsSync(jsPath)) {
throw new Error(`分包文件/目录 ${jsPath} 不存在!`);
}
}
}
}
} else {
delete conJson.subPackages;
}
content = JSON.stringify(conJson, null, 4);
fs.writeFileSync(gameJsonPath, content, "utf8");
if (config.version || config.enableVersion) {
let versionPath = releaseDir + "/version.json";
versionCon = fs.readFileSync(versionPath, "utf8");
versionCon = JSON.parse(versionCon);
}
// 修改index.js
let indexJsStr = (versionCon && versionCon["index.js"]) ? versionCon["index.js"] : "index.js";
let indexFilePath = path.join(releaseDir, indexJsStr);
if (!fs.existsSync(indexFilePath)) {
return;
}
let indexFileContent = fs.readFileSync(indexFilePath, "utf8");
indexFileContent = indexFileContent.replace(/loadLib(\(['"])/gm, "require$1./");
fs.writeFileSync(indexFilePath, indexFileContent, "utf8");
})
gulp.task("modifyMinJs_ByteDance", ["modifyFile_ByteDance"], function() {
// 如果保留了平台文件如果同时取消使用min类库就会出现文件引用不正确的问题
if (config.keepPlatformFile) {
let fileJsPath = path.join(releaseDir, "game.js");
let content = fs.readFileSync(fileJsPath, "utf-8");
content = content.replace(/min\/laya(-[\w\d]+)?\.ttmini\.min\.js/gm, "laya.ttmini.js");
fs.writeFileSync(fileJsPath, content, 'utf-8');
}
if (!config.useMinJsLibs) {
return;
}
let fileJsPath = path.join(releaseDir, "game.js");
let content = fs.readFileSync(fileJsPath, "utf-8");
content = content.replace(/(min\/)?laya(-[\w\d]+)?\.ttmini(\.min)?\.js/gm, "min/laya.ttmini.min.js");
fs.writeFileSync(fileJsPath, content, 'utf-8');
});
gulp.task("version_ByteDance", ["modifyMinJs_ByteDance"], function() {
// 如果保留了平台文件,如果同时开启版本管理,就会出现文件引用不正确的问题
if (config.keepPlatformFile) {
let fileJsPath = path.join(releaseDir, "game.js");
let content = fs.readFileSync(fileJsPath, "utf-8");
content = content.replace(/laya(-[\w\d]+)?\.ttmini/gm, "laya.ttmini");
content = content.replace(/index(-[\w\d]+)?\.js/gm, "index.js");
fs.writeFileSync(fileJsPath, content, 'utf-8');
}
if (config.version) {
let versionPath = releaseDir + "/version.json";
let gameJSPath = releaseDir + "/game.js";
let srcList = [versionPath, gameJSPath];
return gulp.src(srcList)
.pipe(revCollector())
.pipe(gulp.dest(releaseDir));
}
});
gulp.task("pluginEngin_ByteDance", ["version_ByteDance"], function(cb) {
if (!config.uesEnginePlugin) { // 没有使用引擎插件,还是像以前一样发布
let gameJsonPath = path.join(releaseDir, "game.json");
let gameJsonContent = fs.readFileSync(gameJsonPath, "utf8");
let conJson = JSON.parse(gameJsonContent);
if (conJson.plugins) {
delete conJson.plugins;
gameJsonContent = JSON.stringify(conJson, null, 4);
fs.writeFileSync(gameJsonPath, gameJsonContent, "utf8");
let gameJsPath = path.join(releaseDir, "game.js");
let gameJscontent = fs.readFileSync(gameJsPath, "utf8");
gameJscontent = gameJscontent.replace(/requirePlugin\("[\w\/\.]+"\);?\n?/mg, "");
fs.writeFileSync(gameJsPath, gameJscontent, "utf8");
}
return cb();
}
if (config.version) {
let versionPath = releaseDir + "/version.json";
versionCon = fs.readFileSync(versionPath, "utf8");
versionCon = JSON.parse(versionCon);
}
let indexJsStr = (versionCon && versionCon["index.js"]) ? versionCon["index.js"] : "index.js";
// 获取version等信息
let coreLibPath = path.join(workSpaceDir, "bin", "libs", "laya.core.js");
let isHasCoreLib = fs.existsSync(coreLibPath);
let isOldAsProj = fs.existsSync(`${workSpaceDir}/asconfig.json`) && !isHasCoreLib;
let isNewTsProj = fs.existsSync(`${workSpaceDir}/src/tsconfig.json`) && !isHasCoreLib;
let EngineVersion = getEngineVersion();
if (!EngineVersion) {
throw new Error(`读取引擎版本号失败,请于服务提供商联系!`);
}
if (!EngineVersion || EngineVersion.includes("beta") || !canUsePluginEngine(EngineVersion, minPluginVersion)) {
throw new Error(`该版本引擎无法使用引擎插件功能(engineVersion: ${EngineVersion})`);
}
console.log(`通过版本号检查: ${EngineVersion}`);
// 使用引擎插件
let localUseEngineList = [];
let copyEnginePathList;
new Promise(function(resolve, reject) {
console.log(`修改game.js和game.json`);
// 1) 修改game.js和game.json
// 修改game.js
let gameJsPath = path.join(releaseDir, "game.js");
let platformJs = config.useMinJsLibs ? `require("./libs/min/laya.ttmini.min.js");` : `require("./libs/laya.ttmini.js");`;
let gameJscontent = `require("microgame-adapter.js");\n${platformJs}\nrequirePlugin('layaPlugin');\nwindow.loadLib = require;\nrequire("./${indexJsStr}");`;
fs.writeFileSync(gameJsPath, gameJscontent, "utf8");
// 修改game.json使其支持引擎插件
let gameJsonPath = path.join(releaseDir, "game.json");
let gameJsonContent = fs.readFileSync(gameJsonPath, "utf8");
let conJson = JSON.parse(gameJsonContent);
conJson.plugins = {
"layaPlugin": {
"version": EngineVersion,
"provider": provider,
"path": "laya-libs"
}
}
gameJsonContent = JSON.stringify(conJson, null, 4);
fs.writeFileSync(gameJsonPath, gameJsonContent, "utf8");
resolve();
}).then(function() {
return new Promise(function(resolve, reject) {
console.log(`确定用到的插件引擎`);
// 2) 确定用到了那些插件引擎并将插件引擎从index.js的引用中去掉
let indexJsPath = path.join(releaseDir, indexJsStr);
let indexJsCon = fs.readFileSync(indexJsPath, "utf8");
let item, fullRequireItem;
for (let i = 0, len = fullRemoteEngineList.length; i < len; i++) {
item = fullRemoteEngineList[i];
fullRequireItem = config.useMinJsLibs ? `require("./libs/min/${item}")` : `require("./libs/${item}")`;
if (indexJsCon.includes(fullRequireItem)) {
let _item = item.replace(".min.js", ".js"), _minItem = item;
localUseEngineList.push(_item);
indexJsCon = indexJsCon.replace(fullRequireItem + ";", "").replace(fullRequireItem + ",", "").replace(fullRequireItem, "");
// 如果引用了压缩的类库将其重命名为未压缩的类库并拷贝到libs中
if (config.useMinJsLibs) {
let oldMinlibPath = path.join(releaseDir, "libs", "min", _minItem);
let newMinlibPath = path.join(releaseDir, "libs", "min", _item);
let newlibPath = path.join(releaseDir, "libs", _item);
fs.renameSync(oldMinlibPath, newMinlibPath);
// fs.copyFileSync(newlibPath, newMinlibPath);
let con = fs.readFileSync(newMinlibPath, "utf8");
fs.writeFileSync(newlibPath, con, "utf8");
fs.unlinkSync(newMinlibPath);
}
}
}
if (isOldAsProj || isNewTsProj) { // 如果as||ts_new语言开发者将laya.js也写入index.js中了将其删掉
fullRequireItem = `require("./laya.js")`;
if (indexJsCon.includes(fullRequireItem)) {
indexJsCon = indexJsCon.replace(fullRequireItem + ";", "").replace(fullRequireItem + ",", "").replace(fullRequireItem, "");
}
}
fs.writeFileSync(indexJsPath, indexJsCon, "utf8");
// ts/js再次修改game.js仅引用使用到的类库
// as||ts_new因为本地只有laya.js无法仅引用使用到的类库
if (!isOldAsProj && !isNewTsProj) {
let pluginCon = "";
localUseEngineList.forEach(function(item) {
pluginCon += `requirePlugin("layaPlugin/${item}");\n`;
});
let gameJsPath = path.join(releaseDir, "game.js");
let gameJsCon = fs.readFileSync(gameJsPath, "utf8");
gameJsCon = gameJsCon.replace(`requirePlugin('layaPlugin');`, pluginCon);
fs.writeFileSync(gameJsPath, gameJsCon, "utf8");
}
resolve();
});
}).then(function() {
return new Promise(function(resolve, reject) {
console.log(`将本地的引擎插件移动到laya-libs中`);
// 3) 将本地的引擎插件移动到laya-libs中
let libsPath = /** config.useMinJsLibs ? `${releaseDir}/libs/min` : */`${releaseDir}/libs`;
copyEnginePathList = [`${libsPath}/{${localUseEngineList.join(",")}}`];
if (isOldAsProj || isNewTsProj) { // 单独拷贝laya.js
copyEnginePathList = [`${releaseDir}/laya.js`];
}
gulp.src(copyEnginePathList).pipe(gulp.dest(`${releaseDir}/laya-libs`));
setTimeout(resolve, 500);
});
}).then(function() {
return new Promise(function(resolve, reject) {
console.log(`将libs中的本地引擎插件删掉`);
// 4) 将libs中的本地引擎插件删掉
del(copyEnginePathList, { force: true }).then(resolve);
});
}).then(function() {
return new Promise(async function(resolve, reject) {
console.log(`完善引擎插件目录`);
// 5) 引擎插件目录laya-libs中还需要新建几个文件使该目录能够使用
if (isOldAsProj || isNewTsProj) { // 单独拷贝laya.js
localUseEngineList.push("laya.js");
}
let
layalibsPath = path.join(releaseDir, "laya-libs"),
engineIndex = path.join(layalibsPath, "index.js"),
engineplugin = path.join(layalibsPath, "plugin.json"),
enginesignature = path.join(layalibsPath, "signature.json");
// index.js
if (!fs.existsSync(layalibsPath)) {
throw new Error("引擎插件目录创建失败,请与服务提供商联系!");
}
let indexCon = "";
localUseEngineList.forEach(function(item) {
indexCon += `require("./${item}");\n`;
});
fs.writeFileSync(engineIndex, indexCon, "utf8");
// plugin.json
let pluginCon = {"main": "index.js"};
fs.writeFileSync(engineplugin, JSON.stringify(pluginCon, null, 4), "utf8");
// signature.json目前平台方将其作为保留用途不会做插件的md5校验IDE仍将生成md5
let signatureCon = {
"provider": provider,
"signature": []
};
localUseEngineList.unshift("index.js");
let fileName, md5Str;
for (let i = 0, len = localUseEngineList.length; i < len; i++) {
fileName = localUseEngineList[i];
let md5Str = await getFileMd5(path.join(releaseDir, "laya-libs", fileName));
signatureCon.signature.push({
"path": fileName,
"md5": md5Str
});
}
fs.writeFileSync(enginesignature, JSON.stringify(signatureCon, null, 4), "utf8");
resolve();
});
})
.then(function() {
cb();
}).catch(function(e) {
throw e;
})
});
gulp.task("buildByteDanceProj", ["pluginEngin_ByteDance"], function() {
console.log("all tasks completed");
});

View File

@ -0,0 +1,663 @@
// v1.0.7
const ideModuleDir = global.ideModuleDir;
const workSpaceDir = global.workSpaceDir;
//引用插件模块
const gulp = require(ideModuleDir + "gulp");
const fs = require("fs");
const path = require("path");
const https = require("https");
const childProcess = require("child_process");
const del = require(ideModuleDir + "del");
const revCollector = require(ideModuleDir + 'gulp-rev-collector');
const iconv = require(ideModuleDir + "iconv-lite");
const request = require(ideModuleDir + "request");
let copyLibsTask = ["copyPlatformLibsJsFile"];
let versiontask = ["version2"];
let
config,
releaseDir,
toolkitPath,
tempReleaseDir, // 华为临时拷贝目录
projDir; // 华为快游戏工程目录
let versionCon; // 版本管理version.json
let commandSuffix,
adbPath,
opensslPath,
layarepublicPath;
let isDevices = false;
// 创建华为项目前拷贝华为引擎库、修改index.js
gulp.task("preCreate_HW", copyLibsTask, function() {
releaseDir = global.releaseDir;
config = global.config;
commandSuffix = global.commandSuffix;
adbPath = global.adbPath;
opensslPath = global.opensslPath;
layarepublicPath = global.layarepublicPath;
tempReleaseDir = global.tempReleaseDir;
toolkitPath = path.join(layarepublicPath, "pub_huawei");
});
gulp.task("copyPlatformFile_HW", ["preCreate_HW"], function() {
let hwAdapterPath = path.join(layarepublicPath, "LayaAirProjectPack", "lib", "data", "hwfiles");
let copyLibsList = [`${hwAdapterPath}/**/*.*`];
var stream = gulp.src(copyLibsList);
return stream.pipe(gulp.dest(tempReleaseDir));
});
// 新建华为项目-华为项目与其他项目不同,需要安装华为 quickgame node_modules并打包成.rpk文件
gulp.task("installModules_HW", versiontask, function() {
releaseDir = path.dirname(releaseDir);
projDir = path.join(releaseDir, config.hwInfo.projName);
// 如果IDE里对应华为包已经install node_modules了忽略这一步
if (fs.existsSync(path.join(toolkitPath, "node_modules"))) {
return;
}
// 安装华为 quickgame node_modules
return new Promise((resolve, reject) => {
console.log("开始安装华为 toolkit node_modules请耐心等待...");
let cmd = `npm${commandSuffix}`;
let args = ["install"];
let opts = {
cwd: toolkitPath,
shell: true
};
let cp = childProcess.spawn(cmd, args, opts);
cp.stdout.on('data', (data) => {
console.log(`stdout: ${data}`);
});
cp.stderr.on('data', (data) => {
console.log(`stderr: ${data}`);
// reject();
});
cp.on('close', (code) => {
console.log(`子进程退出码:${code}`);
resolve();
});
});
});
// 拷贝文件到华为快游戏
gulp.task("copyFileToProj_HW", ["installModules_HW"], function() {
// 将临时文件夹中的文件,拷贝到项目中去
let originalDir = `${tempReleaseDir}/**/*.*`;
let stream = gulp.src(originalDir);
return stream.pipe(gulp.dest(path.join(projDir)));
});
// 拷贝icon到华为快游戏
gulp.task("copyIconToProj_HW", ["copyFileToProj_HW"], function() {
let originalDir = config.hwInfo.icon;
let stream = gulp.src(originalDir);
return stream.pipe(gulp.dest(path.join(projDir)));
});
// 清除华为快游戏临时目录
gulp.task("clearTempDir_HW", ["copyIconToProj_HW"], function() {
// 删掉临时目录
return del([tempReleaseDir], { force: true });
});
// 生成release签名(私钥文件 private.pem 和证书文件 certificate.pem )
gulp.task("generateSign_HW", ["clearTempDir_HW"], function() {
if (!config.hwSign.generateSign) {
return;
}
// https://doc.quickapp.cn/tools/compiling-tools.html
return new Promise((resolve, reject) => {
let cmd = `${opensslPath}`;
let args = ["req", "-newkey", "rsa:2048", "-nodes", "-keyout", "private.pem",
"-x509", "-days", "3650", "-out", "certificate.pem"];
let opts = {
cwd: projDir,
shell: true
};
let cp = childProcess.spawn(cmd, args, opts);
cp.stdout.on('data', (data) => {
console.log(`stdout: ${data}`);
});
cp.stderr.on('data', (data) => {
console.log(`stderr: ${data}`);
data += "";
if (data.includes("Country Name")) {
cp.stdin.write(`${config.hwSign.countryName}\n`);
console.log(`Country Name: ${config.hwSign.countryName}`);
} else if (data.includes("Province Name")) {
cp.stdin.write(`${config.hwSign.provinceName}\n`);
console.log(`Province Name: ${config.hwSign.provinceName}`);
} else if (data.includes("Locality Name")) {
cp.stdin.write(`${config.hwSign.localityName}\n`);
console.log(`Locality Name: ${config.hwSign.localityName}`);
} else if (data.includes("Organization Name")) {
cp.stdin.write(`${config.hwSign.orgName}\n`);
console.log(`Organization Name: ${config.hwSign.orgName}`);
} else if (data.includes("Organizational Unit Name")) {
cp.stdin.write(`${config.hwSign.orgUnitName}\n`);
console.log(`Organizational Unit Name: ${config.hwSign.orgUnitName}`);
} else if (data.includes("Common Name")) {
cp.stdin.write(`${config.hwSign.commonName}\n`);
console.log(`Common Name: ${config.hwSign.commonName}`);
} else if (data.includes("Email Address")) {
cp.stdin.write(`${config.hwSign.emailAddr}\n`);
console.log(`Email Address: ${config.hwSign.emailAddr}`);
// cp.stdin.end();
}
// reject();
});
cp.on('close', (code) => {
console.log(`子进程退出码:${code}`);
// 签名是否生成成功
let
privatePem = path.join(projDir, "private.pem"),
certificatePem = path.join(projDir, "certificate.pem");
let isSignExits = fs.existsSync(privatePem) && fs.existsSync(certificatePem);
if (!isSignExits) {
throw new Error("签名生成失败,请检查!");
}
resolve();
});
});
});
// 拷贝sign文件到指定位置
gulp.task("copySignFile_HW", ["generateSign_HW"], function() {
// debug签名拷贝默认拷贝
let
privatePem = path.join(toolkitPath, "sign", "debug", "private.pem"),
certificatePem = path.join(toolkitPath, "sign", "debug", "certificate.pem");
let isSignExits = fs.existsSync(privatePem) && fs.existsSync(certificatePem);
if (!isSignExits) {
return;
}
let
signDest = `${projDir}/sign/debug`;
let stream = gulp.src([privatePem, certificatePem]);
stream.pipe(gulp.dest(signDest));
if (config.hwSign.generateSign) { // 新生成的签名
// 移动签名文件到项目中Laya & 华为快游戏项目中)
let
privatePem = path.join(projDir, "private.pem"),
certificatePem = path.join(projDir, "certificate.pem");
let isSignExits = fs.existsSync(privatePem) && fs.existsSync(certificatePem);
if (!isSignExits) {
return;
}
let
xiaomiDest = `${projDir}/sign/release`,
layaDest = `${workSpaceDir}/sign/release`;
let stream = gulp.src([privatePem, certificatePem]);
return stream.pipe(gulp.dest(xiaomiDest))
.pipe(gulp.dest(layaDest));
} else if (config.hwInfo.useReleaseSign && !config.hwSign.generateSign) { // 使用release签名并且没有重新生成
// 从项目中将签名拷贝到华为快游戏项目中
let
privatePem = path.join(workSpaceDir, "sign", "release", "private.pem"),
certificatePem = path.join(workSpaceDir, "sign", "release", "certificate.pem");
let isSignExits = fs.existsSync(privatePem) && fs.existsSync(certificatePem);
if (!isSignExits) {
return;
}
let
xiaomiDest = `${projDir}/sign/release`;
let stream = gulp.src([privatePem, certificatePem]);
return stream.pipe(gulp.dest(xiaomiDest));
}
});
gulp.task("deleteSignFile_HW", ["copySignFile_HW"], function() {
if (config.hwSign.generateSign) { // 新生成的签名
let
privatePem = path.join(projDir, "private.pem"),
certificatePem = path.join(projDir, "certificate.pem");
return del([privatePem, certificatePem], { force: true });
}
});
gulp.task("modifyFile_HW", ["deleteSignFile_HW"], function() {
// 修改manifest.json文件
let manifestPath = path.join(projDir, "manifest.json");
let manifestJson;
if (fs.existsSync(manifestPath)) {
let manifestContent = fs.readFileSync(manifestPath, "utf8");
manifestJson = JSON.parse(manifestContent);
} else {
manifestJson = {
"package": "",
"name": "",
"appType": "fastgame",
"icon": "",
"versionName": "",
"versionCode": 0,
"minPlatformVersion": 1000,
"config": {
"logLevel": "off"
},
"display": {
"orientation": "portrait"
}
}
}
manifestJson.package = config.hwInfo.package;
manifestJson.name = config.hwInfo.name;
manifestJson.display.orientation = config.hwInfo.orientation;
manifestJson.config.logLevel = config.hwInfo.logLevel || "off";
manifestJson.versionName = config.hwInfo.versionName;
manifestJson.versionCode = config.hwInfo.versionCode;
manifestJson.minPlatformVersion = config.hwInfo.minPlatformVersion;
manifestJson.icon = `/${path.basename(config.hwInfo.icon)}`;
if (config.hwInfo.subpack) {
let hwSubpackList = [];
for (let i = 0, len = config.hwSubpack.length; i < len; i++) {
hwSubpackList.push({
name: config.hwSubpack[i].name,
resource: config.hwSubpack[i].root
})
}
manifestJson.subpackages = hwSubpackList;
// 检测分包目录是否有入口文件
console.log('检查分包文件...');
if (manifestJson.subpackages) {
for(let i = 0; i < manifestJson.subpackages.length; i ++) {
let conf = manifestJson.subpackages[i];
if (conf.name) {
let rootPath = path.join(projDir, conf.name);
if (!fs.existsSync(rootPath)) {
throw new Error(`分包文件/目录 ${rootPath} 不存在!`);
}
let jsPath = path.join(rootPath, 'game.js'); ;
if (!fs.existsSync(jsPath)) {
throw new Error(`分包文件/目录 ${jsPath} 不存在!`);
}
}
}
}
} else {
delete manifestJson.subpackages;
}
fs.writeFileSync(manifestPath, JSON.stringify(manifestJson, null, 4), "utf8");
if (config.version) {
let versionPath = projDir + "/version.json";
versionCon = fs.readFileSync(versionPath, "utf8");
versionCon = JSON.parse(versionCon);
}
let indexJsStr = (versionCon && versionCon["index.js"]) ? versionCon["index.js"] : "index.js";
// 华为项目修改game.js
let filePath = path.join(projDir, "game.js");
if (!fs.existsSync(filePath)) {
let fileContent = `require("./huawei-adapter.js");\nrequire("./libs/laya.hwmini.js");\nrequire("index.js");`;
fs.writeFileSync(filePath, fileContent, "utf8");
}
// 华为项目修改index.js
let indexFilePath = path.join(projDir, indexJsStr);
if (!fs.existsSync(indexFilePath)) {
return;
}
let indexFileContent = fs.readFileSync(indexFilePath, "utf8");
indexFileContent = indexFileContent.replace(/loadLib(\(['"])/gm, "require$1./");
fs.writeFileSync(indexFilePath, indexFileContent, "utf8");
});
gulp.task("modifyMinJs_HW", ["modifyFile_HW"], function() {
let fileJsPath = path.join(projDir, "game.js");
let content = fs.readFileSync(fileJsPath, "utf-8");
if (!config.useMinJsLibs) { // 默认保留了平台文件如果同时取消使用min类库就会出现文件引用不正确的问题
content = content.replace(/min\/laya(-[\w\d]+)?\.hwmini\.min\.js/gm, "laya.hwmini.js");
} else {
content = content.replace(/(min\/)?laya(-[\w\d]+)?\.hwmini(\.min)?\.js/gm, "min/laya.hwmini.min.js");
}
fs.writeFileSync(fileJsPath, content, 'utf-8');
});
gulp.task("version_HW", ["modifyMinJs_HW"], function () {
// main.js默认不覆盖如果同时开启版本管理就会出现文件引用不正确的问题
let fileJsPath = path.join(projDir, "game.js");
let content = fs.readFileSync(fileJsPath, "utf-8");
content = content.replace(/laya(-[\w\d]+)?\.hwmini/gm, "laya.hwmini");
content = content.replace(/index(-[\w\d]+)?\.js/gm, "index.js");
fs.writeFileSync(fileJsPath, content, 'utf-8');
if (config.version) {
let versionPath = projDir + "/version.json";
let mainJSPath = projDir + "/game.js";
let srcList = [versionPath, mainJSPath];
return gulp.src(srcList)
.pipe(revCollector())
.pipe(gulp.dest(projDir));
}
});
// 打包rpk
gulp.task("buildRPK_HW", ["version_HW"], function() {
// 在华为快游戏项目目录中执行:
// node .\signtool\package\index.js .\web .\dist com.demo .\release\private.pem .\release\certificate.pem
let
signtoolPath = path.join(toolkitPath, "index.js"),
releasePath = projDir,
distPath = path.join(projDir, "dist"),
name = config.hwInfo.package,
privatePem = path.join(projDir, "sign", "debug", "private.pem"),
certificatePemPath = path.join(projDir, "sign", "debug", "certificate.pem");
if (config.hwInfo.useReleaseSign) {
privatePem = path.join(projDir, "sign", "release", "private.pem"),
certificatePemPath = path.join(projDir, "sign", "release", "certificate.pem");
}
return new Promise((resolve, reject) => {
let cmd = `node`;
let args = [`"${signtoolPath}"`, `"${releasePath}"`, `"${distPath}"`, name, `"${privatePem}"`, `"${certificatePemPath}"`];
let opts = {
cwd: projDir,
shell: true
};
let cp = childProcess.spawn(cmd, args, opts);
// let cp = childProcess.spawn('npx.cmd', ['-v']);
cp.stdout.on('data', (data) => {
console.log(`stdout: ${data}`);
});
cp.stderr.on('data', (data) => {
console.log(`stderr: ${data}`);
console.log(`stderr(iconv): ${iconv.decode(data, 'gbk')}`);
// reject();
});
cp.on('close', (code) => {
console.log(`子进程退出码:${code}`);
// rpk是否生成成功
let distRpkPath = path.join(distPath, `${name}.rpk`);
if (!fs.existsSync(distRpkPath)) {
throw new Error("rpk生成失败请检查");
}
resolve();
});
});
});
gulp.task("getDevices_HW", ["buildRPK_HW"], function(cb) {
let cmd = `${adbPath} devices`;
childProcess.exec(cmd, (error, stdout, stderr) => {
if (error) {
console.error("获取设备失败...");
return cb();
}
if (stdout && stdout.match(/\bdevice\b/)) {
isDevices = true;
}
console.log(`检测到设备: ${isDevices}`);
return cb();
});
});
// 更新快应用加载器
gulp.task("updateAPK_HW", ["getDevices_HW"], function(cb) {
if (!config.hwInfo.apkUpdate || !isDevices) {
return cb();
}
let remoteInfo, remoteAPKVer, localAPKVer;
new Promise((resolve, reject) => {
https.get('https://deveco.huawei.com/FastIDE/update/api/update/engineVersion/', (res) => {
res.on('data', (data) => {
remoteInfo = JSON.parse(data);
remoteAPKVer = remoteInfo.version;
console.log("remote apk version: ", remoteAPKVer);
resolve();
});
}).on('error', (e) => {
reject(`获取远端快应用加载器失败: ${e}`);
});
}).then(() => {
return new Promise((resolve, reject) => {
// Unable为找不到快应用加载器
let cmd = `${adbPath} shell dumpsys package com.huawei.fastapp.dev | `;
if (process.platform === "darwin") {
cmd += `grep "versionName\\|Unable"`;
} else {
cmd += `findstr "versionName Unable"`
}
childProcess.exec(cmd, (error, stdout, stderr) => {
if (stdout && stdout.indexOf("Unable") >= 0) {
// 未安装
localAPKVer = '0.0.0.0_dev';
console.log("未安装快应用加载器");
return resolve();
}
if (error) {
console.log("获取快应用加载器本地版本号失败: ");
console.log(error);
console.log(stderr);
return resolve(error);
}
let matchList = stdout.match(/versionName=(.+)/);
if (!Array.isArray(matchList)) {
console.log("获取快应用加载器本地版本号失败: ");
return resolve();
}
localAPKVer = matchList[1];
console.log("local apk version: ", localAPKVer);
resolve();
});
});
}).then(() => {
return new Promise((resolve, reject) => {
if (remoteAPKVer === localAPKVer || donotUpdate(remoteAPKVer, localAPKVer)) {
console.log("您的快应用加载器是最新版本!");
return resolve();
}
let url = remoteInfo.url;
let apkName = path.basename(url);
let apkDownRoot = path.join(toolkitPath, "fastapp");
let apkDownPath = path.join(apkDownRoot, apkName);
// 1) 如果本地已经有最新版本的快应用加载器,则不再下载
if (fs.existsSync(apkDownPath)) {
console.log("您本地有最新版本的快应用加载器,将直接安装!");
return installAPK().then(() => {
return resolve();
}).catch((err) => {
return reject(err);
})
}
// 2) 下载并安装快应用加载器
console.log("正在下载快应用加载器,请稍等...");
!(fs.existsSync(apkDownRoot)) && fs.mkdirSync(apkDownRoot);
downFileToDir(url, apkDownPath).then(() => {
return installAPK();
}).then(() => {
return resolve();
}).catch((err) => {
return reject(err);
})
// 安装apk
function installAPK() {
return new Promise((resolve, reject) => {
console.log("正在安装快应用加载器,请稍等...");
let cmd = `${adbPath} install -r ${apkDownPath}`;
childProcess.exec(cmd, (error, stdout, stderr) => {
if (error) {
console.error("安装快应用加载器本地版本号失败: ");
console.error(error);
console.error(stderr);
return reject(error);
}
console.log("安装快应用加载器成功!");
resolve();
});
})
}
});
}).then(() => {
return cb();
}).catch((re) => {
console.error("更新快应用加载器失败: ", re);
return cb();
});
});
function downFileToDir(uri, dest){
return new Promise((resolve, reject) => {
if (!uri || !dest) {
reject(new Error(`downFileToDir 参数不全: ${uri}/${dest}`));
return;
}
let
totalLen = 9999,
progress = 0,
layaresponse;
var stream = fs.createWriteStream(dest);
request(uri).on('error', function(err) {
console.log("tool down err:" + err);
reject(err);
}).on("data", function(data) {
progress += data.length;
let downPercent = (progress / totalLen * 100).toFixed(3);
// console.log(`down: ${downPercent}%`);
}).on("response", function(response) {
layaresponse = response;
totalLen = response.caseless.dict['content-length'];
}).pipe(stream).on('close', function() {
if (layaresponse.statusCode == 200) {
console.log("下载成功!");
resolve();
} else {
reject(new Error("下载失败,连接关闭"));
}
});
});
}
gulp.task("pushRPK_HW", ["updateAPK_HW"], function() {
if (!config.hwInfo.adbDebug || !isDevices) {
return;
}
// 在华为快游戏项目目录中执行:
// adb shell am force-stop com.huawei.fastapp.dev
// adb push {rpk_file_path} /data/local/tmp/
// adb shell am start --es rpkpath /data/local/tmp/{rpk_file_name} --ei debugmode 1 --activity-clear-top com.huawei.fastapp.dev/com.huawei.fastapp.app.RpkRunnerActivity
return new Promise((resolve, reject) => {
// adb shell am force-stop com.huawei.fastapp.dev
console.log(`1) force-stop: `);
let cmd = `${adbPath}`;
let args = ["shell", "am", "force-stop", "com.huawei.fastapp.dev"];
let opts = {
cwd: projDir,
shell: true
};
let cp = childProcess.spawn(cmd, args, opts);
// let cp = childProcess.spawn('npx.cmd', ['-v']);
cp.stdout.on('data', (data) => {
console.log(`stdout: ${data}`);
});
cp.stderr.on('data', (data) => {
console.log(`stderr: ${data}`);
// reject();
});
cp.on('close', (code) => {
console.log(`force-stop 子进程退出码:${code}`);
resolve();
});
}).then(() => {
return new Promise((resolve, reject) => {
// adb push {rpk_file_path} /data/local/tmp/
console.log(`2) push_RPK: `);
let rpkFilePath = path.join(projDir, "dist", `${config.hwInfo.package}.rpk`);
let cmd = `${adbPath}`;
let args = ["push", `"${rpkFilePath}"`, "/data/local/tmp/"];
let opts = {
cwd: projDir,
shell: true
};
let cp = childProcess.spawn(cmd, args, opts);
// let cp = childProcess.spawn('npx.cmd', ['-v']);
cp.stdout.on('data', (data) => {
console.log(`stdout: ${data}`);
});
cp.stderr.on('data', (data) => {
console.log(`stderr: ${data}`);
// reject();
});
cp.on('close', (code) => {
console.log(`push_RPK 子进程退出码:${code}`);
resolve();
});
});
}).then(() => {
return new Promise((resolve, reject) => {
// adb shell am start --es rpkpath /data/local/tmp/{rpk_file_name} --ei debugmode 1 --activity-clear-top com.huawei.fastapp.dev/com.huawei.fastapp.app.RpkRunnerActivity
console.log(`3) 启动apk加载rpk: `);
let cmd = `${adbPath}`;
let args = ["shell", "am", "start", "--es", "rpkpath", `file://data/local/tmp/${config.hwInfo.package}.rpk`, "--ei", "debugmode", "1", "--activity-clear-top", "com.huawei.fastapp.dev/com.huawei.fastapp.app.RpkRunnerActivity"];
let opts = {
cwd: projDir,
shell: true
};
let cp = childProcess.spawn(cmd, args, opts);
// let cp = childProcess.spawn('npx.cmd', ['-v']);
cp.stdout.on('data', (data) => {
console.log(`stdout: ${data}`);
});
cp.stderr.on('data', (data) => {
console.log(`stderr: ${data}`);
// reject();
});
cp.on('close', (code) => {
console.log(`启动apk加载rpk: 子进程退出码:${code}`);
resolve();
});
});
});
});
function donotUpdate(remoteAPKVer, localAPKVer) {
let remoteAPKVerN = remoteAPKVer.match(/^(\d+)\.(\d+)\.(\d+)\.(\d+)/);
let localAPKVerN = localAPKVer.match(/^(\d+)\.(\d+)\.(\d+)\.(\d+)/);
let
l1n = Number(localAPKVerN[1]), // local first number
l2n = Number(localAPKVerN[2]),
l3n = Number(localAPKVerN[3]),
l4n = Number(localAPKVerN[4]),
r1n = Number(remoteAPKVerN[1]), // remote first number
r2n = Number(remoteAPKVerN[2]),
r3n = Number(remoteAPKVerN[3]);
r4n = Number(remoteAPKVerN[4]);
if (l1n > r1n) {
return true;
}
if (l1n === r1n && l2n > r2n) {
return true;
}
if (l1n === r1n && l2n === r2n && l3n > r3n) {
return true;
}
if (l1n === r1n && l2n === r2n && l3n === r3n && l4n >= r4n) {
return true;
}
return false;
}
gulp.task("buildHWProj", ["pushRPK_HW"], function() {
console.log("all tasks completed");
});

View File

@ -0,0 +1,453 @@
// v1.1.5
const ideModuleDir = global.ideModuleDir;
const workSpaceDir = global.workSpaceDir;
var Stream = require('stream');
//引用插件模块
const gulp = require(ideModuleDir + "gulp");
const fs = require("fs");
const path = require("path");
const del = require(ideModuleDir + "del");
let copyLibsTask = ["copyPlatformLibsJsFile"];
let versiontask = ["version2"];
let exec = require('child_process').exec;
let tsconfigPath = path.join(workSpaceDir, "tsconfig.json");
let isTS = fs.existsSync(tsconfigPath);
let buildOptions = null;
gulp.task("preCreate_LayaMe", copyLibsTask, function() {
releaseDir = global.releaseDir;
config = global.config;
buildOptions = config.buildOptions;
commandSuffix = global.commandSuffix;
});
// 是否build指定部分debug版本layame)
function toBuildPart(part) {
if (!buildOptions) {
return true;
}
if ('all' == part ) {
return buildOptions.type == 'all';
}
if (buildOptions.type == 'all') {
return true;
}
return (buildOptions.buildList.includes(part));
}
function toBuildTs() {
if (!buildOptions) {
return true;
}
return buildOptions.hasScript;
}
gulp.task("del", ["preCreate_LayaMe"], function(cb) {
let buildFolder = path.join(workSpaceDir, "build");
if (!isTS || !fs.existsSync(buildFolder)) {
return cb();
}
let delList = [`${buildFolder}/**`];
del(delList, { force: true }).then(paths => {
cb();
}).catch((err) => {
throw err;
})
});
gulp.task("tsc", ["del"], function(cb) {
if (!isTS) {
return cb();
}
if(!toBuildTs()) {
return cb();
}
console.log('tsconfigPath', tsconfigPath);
let tscPath = path.join(ideModuleDir, ".bin", `tsc${commandSuffix}`);
return exec(` "${tscPath}" -p "${tsconfigPath}"`, {
cwd: workSpaceDir,
shell: true
}, function(error, stdout, stderr) {
let errStr = stderr || '';
if (errStr.indexOf(": node: ") >= 0 || errStr.indexOf("'node'") >= 0) {
// 提示未安装node
console.log("err");
console.log("node not installed");
} else {
if (error) console.log("error", error);
if (stdout) console.log("stdout", stdout);
if (stderr) console.log("stderr", stderr);
cb();
}
});
});
function getFolderList(rootPath, fileList, fileType, deep= 0) {
if (!fs.existsSync(rootPath)) {
return fileList;
}
let dirList = fs.readdirSync(rootPath);
let fileName, fileFullPath;
for (let i = 0, len = dirList.length; i < len; i++) {
fileName = dirList[i];
fileFullPath = path.join(rootPath, fileName);
if (fs.statSync(fileFullPath).isDirectory()) {
getFolderList(fileFullPath, fileList, fileType, deep + 1);
} else {
if (!!fileType && !fileFullPath.endsWith(fileType)) {
continue;
}
fileList.push({path: fileFullPath,deep:deep});
}
}
}
// 把ui里type为view的runtime删除
gulp.task("deletRuntime", ["tsc"], function() {
// const pageUIFolder = path.join(releaseDir, "pageUI");
// let sceneList= [];
// getFolderList(pageUIFolder, sceneList, ".json");
// for (let i = 0, len = sceneList.length; i < len; i++) {
// let filePath = sceneList[i].path;
// let fileCon = fs.readFileSync(filePath, "utf8");
// let jsonData = JSON.parse(fileCon);
// if (jsonData.type == 'View') {
// if (jsonData.props && jsonData.props.runtime) {
// delete jsonData.props.runtime;
// fs.writeFileSync(filePath, JSON.stringify(jsonData), 'utf8');
// }
// }
// }
});
// 将引入的库的路径改为src根目录的LayaMeMain,并且将引入的该类合并到最终发布目录的根目录下的LayaMeMain.js里
function sortJS (a, b) {
return b.c - a.c;
}
function getFInfoByPath(path, list) {
for (let i = 0, len = list.length; i < len; i++) {
let info = list[i];
if (info.path === path) {
return info;
}
}
return null;
}
gulp.task("mergrToLayaMeMain", ["deletRuntime"], function() {
if (!toBuildPart('LayaMeMain')) {
return;
}
let source = "src";
if (isTS) {
source = "build";
}
let sourceFolder = path.join(workSpaceDir, source);
const scriptPath = path.join(sourceFolder, "script");
let jsList= [];
let scriptStrList = [];
let filePath, fileCon, deep;
// 遍历所有的script合并到LayaMeMain.js
jsList= [];
scriptStrList = [];
getFolderList(scriptPath, jsList, ".js");
// sort jsList
let needSort = false;
let sortList = [];
let otherList = [];
for (let i = 0, len = jsList.length; i < len; i++) {
let jsInfo = jsList[i];
filePath = jsInfo.path;
fileCon = fs.readFileSync(filePath, "utf8");
jsInfo.content = fileCon;
let extendsCls = fileCon.match((/\ s*extends \s*(.+?)\{/));
if (extendsCls) {
if (extendsCls[1]) {
extendsCls = extendsCls[1].trim();
if (extendsCls && !extendsCls.includes('.')) { // not include Laya.
let importCls = fileCon.match(`import\\s*[{| ]\\s*${extendsCls}\\s*[}| ]\\s*from (.+?)["']`) ;
// console.log( extendsCls, jsInfo.path, !!importCls );
if (importCls && importCls[1]) {
importCls = importCls[1].trim();
importCls = importCls.substr(1); console.log( importCls);
let deep = jsInfo.deep;
let currPath = null;
let _index = importCls.lastIndexOf('./');
let parenPath = '';
if (_index >= 0) {
let fPath = jsInfo.path;
let _index2 = fPath.indexOf('/') >= 0 ? fPath.lastIndexOf('/') : fPath.lastIndexOf('\\') ;
currPath = fPath.substring(0,_index2);
currPath = path.join(jsInfo.path,parenPath + '../', importCls) + '.js';
jsInfo.extendsCls = extendsCls;// currPath;
// console.log(jsInfo);
needSort = true;
if (!sortList.includes(jsInfo)) {
sortList.push(jsInfo);
}
let importJs = getFInfoByPath(currPath, jsList);
if (!importJs) {
throw new Error('not found', currPath);
}
if (!jsInfo.c) {
jsInfo.c = 0;
}
importJs.c = jsInfo.c + 1;
if (!sortList.includes(importJs)) {
sortList.push(importJs);
}
// console.log(currPath,_index,parenPath, jsInfo.path, importCls, extendsCls);
}
}
}
}
}
// .vs .fs 解析
let fileConTmp = fileCon + '';
let vsOrfsImport = fileConTmp.match(/import \s*(.+?) from \s*(.+?).[fv]s['"]/);
while (vsOrfsImport) {
let importVar = vsOrfsImport[1];
let filetype = vsOrfsImport[0];
let importFile = vsOrfsImport[2];
importFile = importFile.replace("'", '');
importFile = importFile.replace('"', '');
if (filetype.indexOf('.vs') >= 0) {
filetype = '.vs';
} else {
filetype = '.fs';
}
importFile = importFile + filetype;
let importFilePath = path.join(filePath,'../',importFile );
console.log('importFilePath', importFilePath);
fileConTmp = fileConTmp.replace(vsOrfsImport[0], '');
// console.log('fileConTmp', fileConTmp);
vsOrfsImport = fileConTmp.match(/import \s*(.+?) from \s*(.+?).[fv]s['"]/);
let srcPath = path.join(workSpaceDir, 'src');
importFilePath = importFilePath.replace(sourceFolder, srcPath);
let importFileStr = fs.readFileSync(importFilePath, 'utf8');
importFileStr = importFileStr.replace(/\r?\n/gm, '\\n');
importFileStr = importFileStr.replace(/"/gm,'\'');
importFileStr = importFileStr.replace(/\t/gm,'\\t');
importFileStr = importFileStr.replace(/\\n\s*/g,'\\n');
importFileStr = importFileStr.replace(/\\n\\n/g,'\\n');
// let lineList = importFileStr.split('\n');
// let rStr = '';
// for(let i = 0,len = lineList.length; i < len; i ++) {
// let lineStr = lineList[i];
// lineStr = lineStr.replace(/\r?\n/gm, '\\n');
// lineStr = lineStr.replace(/"/gm,'\\"');
// lineStr = lineStr.replace(/\t/gm,'\\t');
// lineStr = lineStr.trim();
// rStr = rStr + lineStr + '\\n';
// }
// // fs.writeFileSync(importFilePath + '2',rStr.replace(/\\n/gm,'\n'), 'utf8');
jsInfo.content = `var ${importVar} = "${importFileStr}";\n` + jsInfo.content;
}
}
// console.log('ssssssssss',sortList);
if (needSort) {
sortList.sort(sortJS);
for (let i = 0, len = sortList.length; i < len; i++) {
let jsInfo = sortList[i];
scriptStrList.push(jsInfo.content);
}
}
for (let i = 0, len = jsList.length; i < len; i++) {
let jsInfo = jsList[i];
if (!needSort || !sortList.includes(jsInfo)) {
scriptStrList.push(jsInfo.content);
}
}
let layaMeMainStr = '';
const layaMeMainPath = path.join(sourceFolder, "LayaMeMain.js");
if (fs.existsSync(layaMeMainPath)) {
layaMeMainStr = fs.readFileSync(layaMeMainPath, "utf8");
}
if (scriptStrList.length > 0) {
let scriptStrAll = scriptStrList.join('\n');
layaMeMainStr = scriptStrAll + layaMeMainStr;
}
if (layaMeMainStr) {
// console.log(jsList.length,'layaMeMainStr' , layaMeMainStr);
layaMeMainStr = layaMeMainStr.replace(/import/mg, "// import");
// 去掉class前面的字符
layaMeMainStr = layaMeMainStr.replace(/export\s+default\s+[class\.]+\s*/mg, "class ");
layaMeMainStr = layaMeMainStr.replace(/export\s+[class\.]+\s*/mg, "class ");
fs.writeFileSync(`${releaseDir}/LayaMeMain.js`, layaMeMainStr, "utf8");
}
});
// 修改extends Laya.Script3D 为 extends GameScript
// 修改 config.json把.ts替换为.js
function commentImport (str){
str = str.replace(/import/mg, "// import");
return str;
}
function changeComponentsFile() {
var stream = new Stream.Transform({ objectMode: true });
let source = "src";
if (isTS) {
source = "build";
}
let sourceFolder = path.join(workSpaceDir, source);
const scriptPath = path.join(sourceFolder, "script");
const componentsPath = path.join(sourceFolder, "components");
const actionScriptPath = path.join(sourceFolder, "actionScript", "actionFunc.js");
const uiScriptPath = path.join(sourceFolder, "uiScript");
let importPathList = [scriptPath, componentsPath, actionScriptPath, uiScriptPath];
stream._transform = function (originalFile, unused, callback) {
let fPath = originalFile.path;
// throw new Error();
let file = null;
const getFile = () => {
if (!file) {
file = originalFile.clone({ contents: false });
}
return file;
}
// console.log('fPth', fPath, componentsPath);
// 注释import
for(let k =0; k <importPathList.length; k ++) {
let _path = importPathList[k];
if (fPath.startsWith(_path)) {
file = getFile();
let stringData = String(file.contents);
stringData = commentImport(stringData);
let finalBinaryData = Buffer.from(stringData);
file.contents = finalBinaryData;
}
}
if (fPath.indexOf('components') >= 0) {
if ( fPath.endsWith('.js')) {
file = getFile();
let stringData = String(file.contents);
stringData = stringData.replace(/extends\s+[Laya.Script3D\.]+\s*{/mg, "extends GameScript {");
let finalBinaryData = Buffer.from(stringData);
file.contents = finalBinaryData;
} else if (fPath.endsWith('config.json')) {
file = getFile();
let stringData = String(file.contents);
stringData = stringData.replace(/.ts\"/mg, '.js"');
let finalBinaryData = Buffer.from(stringData);
file.contents = finalBinaryData;
}
}
// 去掉class前面的字符
if (fPath.endsWith('.js')) {
file = getFile();
let stringData = String(file.contents);
stringData = stringData.replace(/export\s+default\s+[class\.]+\s*/mg, "class ");
stringData = stringData.replace(/export\s+[class\.]+\s*/mg, "class ");
let finalBinaryData = Buffer.from(stringData);
file.contents = finalBinaryData;
}
if (file) {
callback(null, file);
} else {
callback(null, originalFile);
}
};
return stream;
}
gulp.task("genPreloadMap", ["mergrToLayaMeMain"], function() {
let atlasList = [];
getFolderList(releaseDir,atlasList, '.atlas');
let preloadJson = {
atlas: [],
atlasPng:[],
textures: []
};
let releaseDirTmp = releaseDir.replace(/\\/g, '/');
for(let i = 0,len = atlasList.length; i < len; i ++) {
let file = atlasList[i].path;
file = file.replace(/\\/g, '/');
file = file.replace(releaseDirTmp, '');
file = file.replace('/', '');
preloadJson.atlas.push(file);
preloadJson.atlasPng.push( file.replace('.atlas', '.png'));
}
let texturesList = [];
let texturesDir = path.join(releaseDir, 'textures');
getFolderList(texturesDir,texturesList, '.png');
getFolderList(texturesDir,texturesList, '.jpg');
getFolderList(texturesDir,texturesList, '.jpeg');
let texturesDirTmp = releaseDir.replace(/\\/g, '/');
for(let i = 0,len = texturesList.length; i < len; i ++) {
let file = texturesList[i].path;
file = file.replace(/\\/g, '/');
file = file.replace(texturesDirTmp, '');
file = file.replace('/', '');
preloadJson.textures.push(file);
}
fs.writeFileSync(path.join(releaseDir, 'preload.json'), JSON.stringify(preloadJson, null ,4), 'utf8');
// console.log('atlasList', preloadJson);
});
gulp.task("copy", ["genPreloadMap"], function() {
let source = "src";
if (isTS) {
source = "build";
}
let sourceFolder = path.join(workSpaceDir, source);
let layameInfo = config.layameInfo;
let filter1list = [];
if (toBuildPart('uiScript')) {
filter1list.push('uiScript/**/*.*');
}
if (toBuildPart('actionScript')) {
filter1list.push('actionScript/**/*.*');
}
if (toBuildPart('components')) {
filter1list.push('components/**/*.*');
}
let filter1 = ``;
if (filter1list.length > 1) {
filter1 = `${sourceFolder}/{`;
filter1 += filter1list.join(',');
filter1 += '}';
} else if (filter1list.length == 1) {
filter1 = `${sourceFolder}/{,`;
filter1 += filter1list[0];
filter1 += '}';
} else {
return;
}
let filters = [filter1];
// console.log('filter1', filter1);throw new Error();
if (isTS) {
let filter2 = `${workSpaceDir}/src/{,`;
let filter2list =[];
if (toBuildPart('uiScript')) {
filter2list.push('uiScript/**/!(*.ts)');
}
if (toBuildPart('actionScript')) {
filter2list.push('actionScript/**/!(*.ts)');
}
if (toBuildPart('components')) {
filter2list.push('components/**/!(*.ts)');
}
if (filter2list.length > 1) {
filter2 += filter2list.join(',');
} else if (filter2list.length == 1) {
filter2 += filter2list[0];
}
filter2 += '}';
filters.push(
filter2
);
}
return gulp.src(filters)
.pipe(changeComponentsFile())
.pipe(gulp.dest(releaseDir));
});
gulp.task("buildLayaMeProj", versiontask, function() {
console.log("all tasks completed");
});

View File

@ -0,0 +1,813 @@
// v1.9.3
const ideModuleDir = global.ideModuleDir;
const workSpaceDir = global.workSpaceDir;
//引用插件模块
const gulp = require(ideModuleDir + "gulp");
const fs = require("fs");
const path = require("path");
const childProcess = require("child_process");
const del = require(ideModuleDir + "del");
const revCollector = require(ideModuleDir + 'gulp-rev-collector');
const iconv = require(ideModuleDir + "iconv-lite");
const request = require(ideModuleDir + "request");
const { getEngineVersion, canUsePluginEngine } = require("./pub_utils");
let fullRemoteEngineList = ["laya.core.js", "laya.webgl.js", "laya.filter.js", "laya.ani.js", "laya.d3.js", "laya.html.js", "laya.particle.js", "laya.ui.js", "laya.d3Plugin.js", "bytebuffer.js", "laya.device.js", "laya.physics.js", "laya.physics3D.js", "laya.tiledmap.js", "worker.js", "workerloader.js"];
let copyLibsTask = ["copyPlatformLibsJsFile"];
let versiontask = ["version2"];
let
config,
releaseDir,
toolkitPath,
tempReleaseDir, // OPPO临时拷贝目录
projDir; // OPPO快游戏工程目录
let versionCon; // 版本管理version.json
let commandSuffix,
adbPath,
opensslPath,
layarepublicPath;
// 创建OPPO项目前拷贝OPPO引擎库、修改index.js
gulp.task("preCreate_OPPO", copyLibsTask, function() {
releaseDir = global.releaseDir;
config = global.config;
commandSuffix = global.commandSuffix;
adbPath = global.adbPath;
opensslPath = global.opensslPath;
layarepublicPath = global.layarepublicPath;
tempReleaseDir = global.tempReleaseDir;
toolkitPath = path.join(layarepublicPath, "oppo", "quickgame-toolkit");
if (config.useMinJsLibs) {
fullRemoteEngineList = fullRemoteEngineList.map((item, index) => {
return item.replace(".js", ".min.js");
})
}
});
gulp.task("copyPlatformFile_OPPO", ["preCreate_OPPO"], function() {
return;
});
// 新建OPPO项目-OPPO项目与其他项目不同需要安装OPPO quickgame node_modules并打包成.rpk文件
gulp.task("installModules_OPPO", versiontask, function() {
releaseDir = path.dirname(releaseDir);
projDir = path.join(releaseDir, config.oppoInfo.projName);
// 如果IDE里对应OPPO包已经install node_modules了忽略这一步
if (fs.existsSync(path.join(toolkitPath, "node_modules"))) {
return;
}
// 安装OPPO quickgame node_modules
return new Promise((resolve, reject) => {
console.log("开始安装OPPO quickgame node_modules请耐心等待...");
let cmd = `npm${commandSuffix}`;
let args = ["install"];
let opts = {
cwd: toolkitPath,
shell: true
};
let cp = childProcess.spawn(cmd, args, opts);
cp.stdout.on('data', (data) => {
console.log(`stdout: ${data}`);
});
cp.stderr.on('data', (data) => {
console.log(`stderr: ${data}`);
// reject();
});
cp.on('close', (code) => {
console.log(`子进程退出码:${code}`);
resolve();
});
});
});
// 拷贝文件到OPPO快游戏
gulp.task("copyFileToProj_OPPO", ["installModules_OPPO"], function() {
// 将临时文件夹中的文件,拷贝到项目中去
let originalDir = `${tempReleaseDir}/**/*.*`;
let stream = gulp.src(originalDir);
return stream.pipe(gulp.dest(path.join(projDir)));
});
// 拷贝icon到OPPO快游戏
gulp.task("copyIconToProj_OPPO", ["copyFileToProj_OPPO"], function() {
let originalDir = config.oppoInfo.icon;
let stream = gulp.src(originalDir);
return stream.pipe(gulp.dest(path.join(projDir)));
});
// 清除OPPO快游戏临时目录
gulp.task("clearTempDir_OPPO", ["copyIconToProj_OPPO"], function() {
// 删掉临时目录
return del([tempReleaseDir], { force: true });
});
// 生成release签名(私钥文件 private.pem 和证书文件 certificate.pem )
gulp.task("generateSign_OPPO", ["clearTempDir_OPPO"], function() {
if (!config.oppoSign.generateSign) {
return;
}
// https://doc.quickapp.cn/tools/compiling-tools.html
return new Promise((resolve, reject) => {
let cmd = `${opensslPath}`;
let args = ["req", "-newkey", "rsa:2048", "-nodes", "-keyout", "private.pem",
"-x509", "-days", "3650", "-out", "certificate.pem"];
let opts = {
cwd: projDir,
shell: true
};
let cp = childProcess.spawn(cmd, args, opts);
cp.stdout.on('data', (data) => {
console.log(`stdout: ${data}`);
});
cp.stderr.on('data', (data) => {
console.log(`stderr: ${data}`);
data += "";
if (data.includes("Country Name")) {
cp.stdin.write(`${config.oppoSign.countryName}\n`);
console.log(`Country Name: ${config.oppoSign.countryName}`);
} else if (data.includes("Province Name")) {
cp.stdin.write(`${config.oppoSign.provinceName}\n`);
console.log(`Province Name: ${config.oppoSign.provinceName}`);
} else if (data.includes("Locality Name")) {
cp.stdin.write(`${config.oppoSign.localityName}\n`);
console.log(`Locality Name: ${config.oppoSign.localityName}`);
} else if (data.includes("Organization Name")) {
cp.stdin.write(`${config.oppoSign.orgName}\n`);
console.log(`Organization Name: ${config.oppoSign.orgName}`);
} else if (data.includes("Organizational Unit Name")) {
cp.stdin.write(`${config.oppoSign.orgUnitName}\n`);
console.log(`Organizational Unit Name: ${config.oppoSign.orgUnitName}`);
} else if (data.includes("Common Name")) {
cp.stdin.write(`${config.oppoSign.commonName}\n`);
console.log(`Common Name: ${config.oppoSign.commonName}`);
} else if (data.includes("Email Address")) {
cp.stdin.write(`${config.oppoSign.emailAddr}\n`);
console.log(`Email Address: ${config.oppoSign.emailAddr}`);
// cp.stdin.end();
}
// reject();
});
cp.on('close', (code) => {
console.log(`子进程退出码:${code}`);
// 签名是否生成成功
let
privatePem = path.join(projDir, "private.pem"),
certificatePem = path.join(projDir, "certificate.pem");
let isSignExits = fs.existsSync(privatePem) && fs.existsSync(certificatePem);
if (!isSignExits) {
throw new Error("签名生成失败,请检查!");
}
resolve();
});
});
});
// 拷贝sign文件到指定位置
gulp.task("copySignFile_OPPO", ["generateSign_OPPO"], function() {
if (config.oppoSign.generateSign) { // 新生成的签名
// 移动签名文件到项目中Laya & OPPO快游戏项目中
let
privatePem = path.join(projDir, "private.pem"),
certificatePem = path.join(projDir, "certificate.pem");
let isSignExits = fs.existsSync(privatePem) && fs.existsSync(certificatePem);
if (!isSignExits) {
return;
}
let
xiaomiDest = `${projDir}/sign/release`,
layaDest = `${workSpaceDir}/sign/release`;
let stream = gulp.src([privatePem, certificatePem]);
return stream.pipe(gulp.dest(xiaomiDest))
.pipe(gulp.dest(layaDest));
} else if (config.oppoInfo.useReleaseSign && !config.oppoSign.generateSign) { // 使用release签名并且没有重新生成
// 从项目中将签名拷贝到OPPO快游戏项目中
let
privatePem = path.join(workSpaceDir, "sign", "release", "private.pem"),
certificatePem = path.join(workSpaceDir, "sign", "release", "certificate.pem");
let isSignExits = fs.existsSync(privatePem) && fs.existsSync(certificatePem);
if (!isSignExits) {
return;
}
let
xiaomiDest = `${projDir}/sign/release`;
let stream = gulp.src([privatePem, certificatePem]);
return stream.pipe(gulp.dest(xiaomiDest));
}
});
gulp.task("deleteSignFile_OPPO", ["copySignFile_OPPO"], function() {
if (config.oppoSign.generateSign) { // 新生成的签名
let
privatePem = path.join(projDir, "private.pem"),
certificatePem = path.join(projDir, "certificate.pem");
return del([privatePem, certificatePem], { force: true });
}
});
gulp.task("modifyFile_OPPO", ["deleteSignFile_OPPO"], function() {
// 修改manifest.json文件
let manifestPath = path.join(projDir, "manifest.json");
let IDEManifestPath = path.join(toolkitPath, "tpl", "manifest.json");
if (!fs.existsSync(IDEManifestPath) && !fs.existsSync(manifestPath)) {
return;
}
let manifestContent;
if (fs.existsSync(manifestPath)) {
manifestContent = fs.readFileSync(manifestPath, "utf8");
} else {
manifestContent = fs.readFileSync(IDEManifestPath, "utf8");
}
let manifestJson = JSON.parse(manifestContent);
manifestJson.package = config.oppoInfo.package;
manifestJson.name = config.oppoInfo.name;
manifestJson.orientation = config.oppoInfo.orientation;
manifestJson.config.logLevel = config.oppoInfo.logLevel || "off";
manifestJson.versionName = config.oppoInfo.versionName;
manifestJson.versionCode = config.oppoInfo.versionCode;
manifestJson.minPlatformVersion = config.oppoInfo.minPlatformVersion;
manifestJson.icon = `./${path.basename(config.oppoInfo.icon)}`;
if (config.oppoInfo.subpack) {
manifestJson.subpackages = config.oppoSubpack;
// 检测分包目录是否有入口文件
console.log('检查分包文件...');
if (manifestJson.subpackages) {
for(let i = 0; i < manifestJson.subpackages.length; i ++) {
let conf = manifestJson.subpackages[i];
if (conf.root) {
let rootPath = path.join(projDir, conf.root);
if (!fs.existsSync(rootPath)) {
throw new Error(`分包文件/目录 ${rootPath} 不存在!`);
}
let jsIndex = rootPath.lastIndexOf('.js');
let jsPath = rootPath;
if (jsIndex < 0 || jsIndex != rootPath.length - 3) {
jsPath = path.join(rootPath, 'main.js');
}
if (!fs.existsSync(jsPath)) {
throw new Error(`分包文件/目录 ${jsPath} 不存在!`);
}
}
}
}
} else {
delete manifestJson.subpackages;
}
fs.writeFileSync(manifestPath, JSON.stringify(manifestJson, null, 4), "utf8");
if (config.version) {
let versionPath = projDir + "/version.json";
versionCon = fs.readFileSync(versionPath, "utf8");
versionCon = JSON.parse(versionCon);
}
let indexJsStr = (versionCon && versionCon["index.js"]) ? versionCon["index.js"] : "index.js";
// OPPO项目修改main.js
let filePath = path.join(projDir, "main.js");
let fileContent;
if (!fs.existsSync(filePath)) {
fileContent = `window.navigator.userAgent = 'Mozilla/5.0 (Linux; Android 5.1.1; Nexus 6 Build/LYZ28E) AppleWebKit/603.1.30 (KHTML, like Gecko) Mobile/14E8301 OPPO MiniGame NetType/WIFI Language/zh_CN';
require("./libs/laya.quickgamemini.js");\nrequire("index.js");`;
} else {
// 额外的,如果有引擎插件相关代码,需要删掉
fileContent = fs.readFileSync(filePath, "utf8");
fileContent = fileContent.replace(/if\s\(window\.requirePlugin\)\s{\n[\w\"\.\-\/\(\);\s\n]*\n}\selse\s{\n[\w\"\.\-\/\(\);\s\n]*\n}\n/gm, "");
}
fs.writeFileSync(filePath, fileContent, "utf8");
// OPPO项目修改index.js
let indexFilePath = path.join(projDir, indexJsStr);
if (!fs.existsSync(indexFilePath)) {
return;
}
let indexFileContent = fs.readFileSync(indexFilePath, "utf8");
indexFileContent = indexFileContent.replace(/loadLib(\(['"])/gm, "require$1./");
fs.writeFileSync(indexFilePath, indexFileContent, "utf8");
});
gulp.task("modifyMinJs_OPPO", ["modifyFile_OPPO"], function() {
let fileJsPath = path.join(projDir, "main.js");
let content = fs.readFileSync(fileJsPath, "utf-8");
if (!config.useMinJsLibs) { // 默认保留了平台文件如果同时取消使用min类库就会出现文件引用不正确的问题
content = content.replace(/min\/laya(-[\w\d]+)?\.quickgamemini\.min\.js/gm, "laya.quickgamemini.js");
} else {
content = content.replace(/(min\/)?laya(-[\w\d]+)?\.quickgamemini(\.min)?\.js/gm, "min/laya.quickgamemini.min.js");
}
fs.writeFileSync(fileJsPath, content, 'utf-8');
});
gulp.task("version_OPPO", ["modifyMinJs_OPPO"], function () {
// main.js默认不覆盖如果同时开启版本管理就会出现文件引用不正确的问题
let fileJsPath = path.join(projDir, "main.js");
let content = fs.readFileSync(fileJsPath, "utf-8");
content = content.replace(/laya(-[\w\d]+)?\.quickgamemini/gm, "laya.quickgamemini");
content = content.replace(/index(-[\w\d]+)?\.js/gm, "index.js");
fs.writeFileSync(fileJsPath, content, 'utf-8');
if (config.version) {
let versionPath = projDir + "/version.json";
let mainJSPath = projDir + "/main.js";
let srcList = [versionPath, mainJSPath];
return gulp.src(srcList)
.pipe(revCollector())
.pipe(gulp.dest(projDir));
}
});
// 处理引擎插件
// 我们会将所有的libs下的文件放到engine里但不能认定libs下全是我们的引擎所以还是要加判断
gulp.task("pluginEngin_OPPO", ["version_OPPO"], function(cb) {
let manifestJsonPath = path.join(projDir, "manifest.json");
let manifestJsonContent = fs.readFileSync(manifestJsonPath, "utf8");
let conJson = JSON.parse(manifestJsonContent);
let copyBinPath;
if (!config.uesEnginePlugin) { // 没有使用引擎插件,还是像以前一样发布
delete conJson.plugins;
manifestJsonContent = JSON.stringify(conJson, null, 4);
fs.writeFileSync(manifestJsonPath, manifestJsonContent, "utf8");
return cb();
}
// 引擎源码项目
// 将所有的min拷贝进来
if (config.useMinJsLibs) {
copyBinPath = path.join(workSpaceDir, "bin", "libs", "min");
} else { // 如果不是min
copyBinPath = path.join(workSpaceDir, "bin", "libs");
}
// 针对min引擎文件很多配置文件也需要该同时改
if (config.version) {
let versionPath = projDir + "/version.json";
versionCon = fs.readFileSync(versionPath, "utf8");
versionCon = JSON.parse(versionCon);
}
let indexJsStr = (versionCon && versionCon["index.js"]) ? versionCon["index.js"] : "index.js";
// 获取version等信息
let coreLibPath = path.join(workSpaceDir, "bin", "libs", "laya.core.js");
let isHasCoreLib = fs.existsSync(coreLibPath);
let isOldAsProj = fs.existsSync(`${workSpaceDir}/asconfig.json`) && !isHasCoreLib;
let isNewTsProj = fs.existsSync(`${workSpaceDir}/src/tsconfig.json`) && !isHasCoreLib;
let EngineVersion = getEngineVersion();
if (isOldAsProj || isNewTsProj) {
// 下载对应版本js引擎按照普通项目走
console.log(`ts源码项目(${isNewTsProj})或as源码项目(${isOldAsProj}),开始处理引擎`);
let engineNum = EngineVersion.split("beta")[0];
let suffix = EngineVersion.includes("beta") ? `_beta${EngineVersion.split("beta")[1]}` : "";
let engineURL;
if (canUsePluginEngine(EngineVersion, "2.7.2")) { // 2.7.2 开始,下载地址更新为 cos 服务器
engineURL = `https://ldc-1251285021.cos.ap-shanghai.myqcloud.com/download/Libs/LayaAirJS_${engineNum}${suffix}.zip`;
} else {
engineURL = `http://ldc.layabox.com/download/LayaAirJS_${engineNum}${suffix}.zip`;
}
let engineDownPath = path.join(releaseDir, `LayaAirJS_${engineNum}${suffix}.zip`);
let engineExtractPath = path.join(releaseDir, `LayaAirJS_${engineNum}${suffix}`);
if (config.useMinJsLibs) {
copyBinPath = path.join(engineExtractPath, "js", "libs", "min");
} else { // 如果不是min
copyBinPath = path.join(engineExtractPath, "js", "libs");
}
// 情况1) 如果已经下载过引擎了,直接开始处理引擎插件
if (fs.existsSync(copyBinPath)) {
console.log("情况1) 如果已经下载过引擎了,直接开始处理引擎插件");
return dealPluginEngine().then(() => {
// return cb();
}).catch((err) => {
console.error("ts源码项目及as源码项目下载或处理oppo引擎插件项目失败(code 1)!");
throw err;
});
}
// 情况2) 下载并解压引擎,然后开始处理引擎插件
console.log("情况2) 下载并解压引擎,然后开始处理引擎插件");
return downFileToDir(engineURL, engineDownPath).then(() => {
console.log("下载引擎库成功,开始解压");
return extractZipFile(engineDownPath, engineExtractPath);
}).then(() => {
console.log("解压成功,开始处理引擎插件");
return dealPluginEngine();
}).then(() => {
// return cb();
}).catch((err) => {
console.error("ts源码项目及as源码项目下载或处理oppo引擎插件项目失败(code 2)!");
throw err;
})
}
// 情况3) 非源码项目,开始处理引擎插件
console.log("情况3) 非源码项目,开始处理引擎插件");
return dealPluginEngine().then(() => {
// return cb();
}).catch((err) => {
throw err;
});
function dealPluginEngine() {
// 使用引擎插件
let localUseEngineList = [];
let copyEnginePathList;
return new Promise(function(resolve, reject) {
console.log(`修改main.js和manifest.json`);
// 1) 修改main.js和manifest.json
// 修改main.js
let gameJsPath = path.join(projDir, "main.js");
let gameJscontent = fs.readFileSync(gameJsPath, "utf8");
gameJscontent = gameJscontent.replace(`require("${indexJsStr}");`, `requirePlugin('layaPlugin');\nrequire("${indexJsStr}");`);
fs.writeFileSync(gameJsPath, gameJscontent, "utf8");
// 修改manifest.json使其支持引擎插件
conJson.plugins = {
"laya-library": {
"version": EngineVersion,
"provider": "",
"path": "laya-library"
}
}
manifestJsonContent = JSON.stringify(conJson, null, 4);
fs.writeFileSync(manifestJsonPath, manifestJsonContent, "utf8");
resolve();
}).then(function() {
return new Promise(function(resolve, reject) {
console.log(`确定用到的插件引擎`);
// 2) 确定用到了那些插件引擎并将插件引擎从index.js的引用中去掉
let indexJsPath = path.join(projDir, indexJsStr);
let indexJsCon = fs.readFileSync(indexJsPath, "utf8");
let item, fullRequireItem;
for (let i = 0, len = fullRemoteEngineList.length; i < len; i++) {
item = fullRemoteEngineList[i];
fullRequireItem = config.useMinJsLibs ? `require("./libs/min/${item}")` : `require("./libs/${item}")`;
if (indexJsCon.includes(fullRequireItem)) {
localUseEngineList.push(item);
indexJsCon = indexJsCon.replace(fullRequireItem + ";", "").replace(fullRequireItem + ",", "").replace(fullRequireItem, "");
}
}
// 源码项目需要特殊处理
if (isNewTsProj || isOldAsProj) {
indexJsCon = indexJsCon.replace(`require("./laya.js");`, "").replace(`require("./laya.js"),`, "").replace(`require("./laya.js")`, "");
let item, libPath/*, oppoConfigList = []*/;
for (let i = 0, len = fullRemoteEngineList.length; i < len; i++) {
item = fullRemoteEngineList[i];
libPath = path.join(copyBinPath, item);
if (fs.existsSync(libPath) && !["bytebuffer", "laya.physics3D", "worker", "workerloader"].includes(item.replace(".min.js", "").replace(".js", ""))) {
localUseEngineList.push(item);
// config.useMinJsLibs ? oppoConfigList.push(`libs/min/${item}`) : oppoConfigList.push(`libs/${item}`);
}
}
// let bundleJsStr = (versionCon && versionCon["js/bundle.js"]) ? versionCon["js/bundle.js"] : "js/bundle.js";
// oppoConfigList.push(bundleJsStr);
// configoppoConfigFile(oppoConfigList, true);
}
fs.writeFileSync(indexJsPath, indexJsCon, "utf8");
// 再次修改game.js仅引用使用到的类库
let pluginCon = "", normalCon = "";
localUseEngineList.forEach(function(item) {
pluginCon += `\trequirePlugin("laya-library/${item}");\n`;
normalCon += `\trequire("laya-library/${item}");\n`;
});
let finalyPluginCon = `if (window.requirePlugin) {\n${pluginCon}\n} else {\n${normalCon}\n}`;
let gameJsPath = path.join(projDir, "main.js");
let gameJsCon = fs.readFileSync(gameJsPath, "utf8");
gameJsCon = gameJsCon.replace(`requirePlugin('layaPlugin');`, finalyPluginCon);
fs.writeFileSync(gameJsPath, gameJsCon, "utf8");
resolve();
});
}).then(function() {
return new Promise(function(resolve, reject) {
console.log(`将本地的引擎插件移动到laya-libs中`);
// 3) 将本地的引擎插件移动到laya-libs中
copyEnginePathList = [`${copyBinPath}/{${fullRemoteEngineList.join(",")}}`];
gulp.src(copyEnginePathList).pipe(gulp.dest(`${projDir}/laya-library`));
setTimeout(resolve, 500);
});
}).then(function() {
return new Promise(function(resolve, reject) {
console.log(`将libs中的本地引擎插件删掉`);
// 4) 将libs中的本地引擎插件删掉
let deleteList = [`${projDir}/libs/{${localUseEngineList.join(",")}}`, `${projDir}/libs/min/{${localUseEngineList.join(",")}}`];
del(deleteList, { force: true }).then(resolve);
});
}).then(function() {
return new Promise(async function(resolve, reject) {
console.log(`完善引擎插件目录`);
// 5) 引擎插件目录laya-libs中还需要新建几个文件使该目录能够使用
let
layalibsPath = path.join(projDir, "laya-library"),
engineIndex = path.join(layalibsPath, "index.js"),
engineplugin = path.join(layalibsPath, "plugin.json");
// enginesignature = path.join(layalibsPath, "signature.json");
// index.js
if (!fs.existsSync(layalibsPath)) {
throw new Error("引擎插件目录创建失败,请与服务提供商联系!");
}
let layaLibraryList = fs.readdirSync(layalibsPath);
let indexCon = "";
layaLibraryList.forEach(function(item) {
indexCon += `require("./${item}");\n`;
});
fs.writeFileSync(engineIndex, indexCon, "utf8");
// plugin.json
let pluginCon = {"main": "index.js"};
fs.writeFileSync(engineplugin, JSON.stringify(pluginCon, null, 4), "utf8");
// signature.json
// let signatureCon = {
// "provider": provider,
// "signature": []
// };
// localUseEngineList.unshift("index.js");
// let fileName, md5Str;
// for (let i = 0, len = localUseEngineList.length; i < len; i++) {
// fileName = localUseEngineList[i];
// let md5Str = await getFileMd5(path.join(projDir, "laya-library", fileName));
// signatureCon.signature.push({
// "path": fileName,
// "md5": md5Str
// });
// }
// fs.writeFileSync(enginesignature, JSON.stringify(signatureCon, null, 4), "utf8");
resolve();
});
}).catch(function(e) {
throw e;
})
}
});
function downFileToDir(uri, dest){
return new Promise((resolve, reject) => {
if (!uri || !dest) {
reject(new Error(`downFileToDir 参数不全: ${uri}/${dest}`));
return;
}
let
totalLen = 9999,
progress = 0,
layaresponse;
var stream = fs.createWriteStream(dest);
request(uri).on('error', function(err) {
console.log("tool down err:" + err);
reject(err);
}).on("data", function(data) {
progress += data.length;
let downPercent = (progress / totalLen * 100).toFixed(3);
// console.log(`down: ${downPercent}%`);
}).on("response", function(response) {
layaresponse = response;
totalLen = response.caseless.dict['content-length'];
}).pipe(stream).on('close', function() {
if (layaresponse.statusCode == 200) {
console.log("下载成功!");
resolve();
} else {
reject(new Error(`下载失败,连接关闭 -> ${uri}`));
}
});
});
}
function extractZipFile(zipPath, extractDir) {
return new Promise((resolve, reject) => {
if (!zipPath || !extractDir) {
reject(new Error(`extractZipFile 参数不全: ${zipPath}/${extractDir}`));
return false;
}
zipPath = `"${zipPath}"`;
let unzipexepath = path.join(ideModuleDir, "../", "out", "codeextension", "updateversion", "tools", "unzip.exe");
unzipexepath = `"${unzipexepath}"`;
let cmd;
if (process.platform === 'darwin') {
cmd = "unzip -o " + zipPath + " -d " + "\"" + extractDir + "\"";
} else {
cmd = unzipexepath + " -o " + zipPath + " -d " + "\"" + extractDir + "\"";
}
childProcess.exec(cmd, (error, stdout, stderr) => {
if (error || stderr) {
reject(error || stderr);
return;
}
resolve();
});
});
}
// 打包rpk
gulp.task("buildRPK_OPPO", ["pluginEngin_OPPO"], function() {
// 在OPPO轻游戏项目目录中执行:
// quickgame pack || quickgame pack release
// quickgame subpack --no-build-js || quickgame subpack release --no-build-js
let cmdStr = "";
let packStr = "pack";
let nobuildjs = "";
if (config.oppoInfo.subpack) {
packStr = "subpack";
nobuildjs = "--no-build-js";
}
if (config.oppoInfo.useReleaseSign) {
cmdStr = "release";
}
return new Promise((resolve, reject) => {
let cmd = path.join(toolkitPath, "lib", "bin", `quickgame${commandSuffix}`);
let args = [packStr, cmdStr, nobuildjs];
let opts = {
cwd: projDir,
shell: true
};
let cp = childProcess.spawn(`"${cmd}"`, args, opts);
// let cp = childProcess.spawn('npx.cmd', ['-v']);
cp.stdout.on('data', (data) => {
console.log(`stdout: ${data}`);
});
cp.stderr.on('data', (data) => {
console.log(`stderr: ${data}`);
console.log(`stderr(iconv): ${iconv.decode(data, 'gbk')}`);
// reject();
});
cp.on('close', (code) => {
console.log(`子进程退出码:${code}`);
// rpk是否生成成功
let distRpkPath = path.join(projDir, "dist", `${config.oppoInfo.package}${config.oppoInfo.useReleaseSign ? ".signed" : ""}.rpk`);
if (!fs.existsSync(distRpkPath)) {
throw new Error("rpk生成失败请检查");
}
resolve();
});
});
});
gulp.task("pushRPK_OPPO", ["buildRPK_OPPO"], function() {
if (!config.oppoInfo.adbDebug) {
return;
}
// 在OPPO轻游戏项目目录中执行:
// adb push dist/game.rpk sdcard/games
// adb push layarepublicPath/oppo/instant_app_settings.properties
// adb shell am force-stop com.nearme.instant.platform
// adb shell am start -n com.nearme.instant.platform/com.oppo.autotest.main.InstantAppActivity
return new Promise((resolve, reject) => {
if (!config.oppoInfo.subpack) {
return resolve();
}
let cmd = `${adbPath}`;
let args = ["shell", "mkdir", `sdcard/subPkg`];
let opts = {
cwd: projDir,
shell: true
};
let cp = childProcess.spawn(cmd, args, opts);
// let cp = childProcess.spawn('npx.cmd', ['-v']);
cp.stdout.on('data', (data) => {
console.log(`stdout: ${data}`);
});
cp.stderr.on('data', (data) => {
console.log(`stderr: ${data}`);
// reject();
});
cp.on('close', (code) => {
console.log(`pre) push_RPK 子进程退出码:${code}`);
resolve();
});
}).then(() => {
return new Promise((resolve, reject) => {
if (!config.uesEnginePlugin) {
resolve();
return;
}else {
// 如果使用引擎插件,解压完整包
let distRpkPath = path.join(projDir, "dist", `${config.oppoInfo.package}${config.oppoInfo.useReleaseSign ? ".signed" : ""}.rpk`);
console.log("解压完整包",distRpkPath);
let tmpDir = path.join(projDir, "dist", `tmp`);
if (!fs.existsSync(tmpDir)) {
fs.mkdirSync(tmpDir);
}
extractZipFile(distRpkPath, tmpDir).then(() => {
console.log('解压完整包完成');
resolve();
});
}
})
}).then(() => {
return new Promise((resolve, reject) => {
let cmd = `${adbPath}`;
let sdGamesPath = config.oppoInfo.subpack ? "sdcard/subPkg" : "sdcard/games";
let args = ["push", `dist${config.uesEnginePlugin ?"/tmp" : "" }/${config.oppoInfo.package}${config.oppoInfo.useReleaseSign ? ".signed" : ""}.rpk`, sdGamesPath];
let opts = {
cwd: projDir,
shell: true
};
let cp = childProcess.spawn(cmd, args, opts);
// let cp = childProcess.spawn('npx.cmd', ['-v']);
cp.stdout.on('data', (data) => {
console.log(`stdout: ${data}`);
});
cp.stderr.on('data', (data) => {
console.log(`stderr: ${data}`);
// reject();
});
cp.on('close', (code) => {
console.log(`1) push_RPK 子进程退出码:${code}`);
resolve();
});
})
}).then(() => {
return new Promise((resolve, reject) => {
// 如果是分包,需要修改里面的内容
let oppoPropPath = path.join(layarepublicPath, "oppo", "instant_app_settings.properties");
if (config.oppoInfo.subpack) {
fs.writeFileSync(oppoPropPath, "default_tab=game_split", "utf8");
} else {
fs.writeFileSync(oppoPropPath, "default_tab=game", "utf8");
}
let cmd = `${adbPath}`;
let args = ["push", oppoPropPath, "sdcard/"];
let opts = {
cwd: projDir,
shell: true
};
let cp = childProcess.spawn(cmd, args, opts);
// let cp = childProcess.spawn('npx.cmd', ['-v']);
cp.stdout.on('data', (data) => {
console.log(`stdout: ${data}`);
});
cp.stderr.on('data', (data) => {
console.log(`stderr: ${data}`);
// reject();
});
cp.on('close', (code) => {
console.log(`2) push_RPK 子进程退出码:${code}`);
resolve();
});
});
}).then(() => {
return new Promise((resolve, reject) => {
let cmd = `${adbPath}`;
let args = ["shell", "am", "force-stop", "com.nearme.instant.platform"];
let opts = {
cwd: projDir,
shell: true
};
let cp = childProcess.spawn(cmd, args, opts);
// let cp = childProcess.spawn('npx.cmd', ['-v']);
cp.stdout.on('data', (data) => {
console.log(`stdout: ${data}`);
});
cp.stderr.on('data', (data) => {
console.log(`stderr: ${data}`);
// reject();
});
cp.on('close', (code) => {
console.log(`3) push_RPK 子进程退出码:${code}`);
resolve();
});
});
}).then(() => {
return new Promise((resolve, reject) => {
let cmd = `${adbPath}`;
let args = ["shell", "am", "start", "-n", "com.nearme.instant.platform/com.oppo.autotest.main.InstantAppActivity"];
let opts = {
cwd: projDir,
shell: true
};
let cp = childProcess.spawn(cmd, args, opts);
// let cp = childProcess.spawn('npx.cmd', ['-v']);
cp.stdout.on('data', (data) => {
console.log(`stdout: ${data}`);
});
cp.stderr.on('data', (data) => {
console.log(`stderr: ${data}`);
// reject();
});
cp.on('close', (code) => {
console.log(`4) push_RPK 子进程退出码:${code}`);
resolve();
});
});
});
});
gulp.task("buildOPPOProj", ["pushRPK_OPPO"], function() {
console.log("all tasks completed");
});

View File

@ -0,0 +1,296 @@
// v1.8.7
const ideModuleDir = global.ideModuleDir;
const workSpaceDir = global.workSpaceDir;
//引用插件模块
const gulp = require(ideModuleDir + "gulp");
const fs = require("fs");
const path = require("path");
const del = require(ideModuleDir + "del");
const revCollector = require(ideModuleDir + 'gulp-rev-collector');
const { getEngineVersion, getFileMd5, canUsePluginEngine } = require("./pub_utils");
const provider = "1109625052";
const minPluginVersion = "2.1.1";
let fullRemoteEngineList = ["laya.core.js", "laya.filter.js", "laya.ani.js", "laya.tiledmap.js", "laya.d3.js", "laya.html.js", "laya.particle.js", "laya.ui.js", "laya.webgl.js", "laya.filter.js", "laya.d3Plugin.js"];
let copyLibsTask = ["copyPlatformLibsJsFile"];
let versiontask = ["version2"];
let
config,
releaseDir;
let versionCon; // 版本管理version.json
let commandSuffix,
layarepublicPath;
gulp.task("preCreate_QQ", copyLibsTask, function() {
releaseDir = global.releaseDir;
config = global.config;
commandSuffix = global.commandSuffix;
layarepublicPath = global.layarepublicPath;
if (config.useMinJsLibs) {
fullRemoteEngineList = fullRemoteEngineList.map((item, index) => {
return item.replace(".js", ".min.js");
})
}
});
gulp.task("copyPlatformFile_QQ", ["preCreate_QQ"], function() {
let adapterPath = path.join(layarepublicPath, "LayaAirProjectPack", "lib", "data", "qqfiles");
let hasPublishPlatform =
fs.existsSync(path.join(releaseDir, "game.js")) &&
fs.existsSync(path.join(releaseDir, "game.json")) &&
fs.existsSync(path.join(releaseDir, "project.config.json"));
let copyLibsList;
if (hasPublishPlatform) {
copyLibsList = [`${adapterPath}/weapp-adapter.js`];
} else {
copyLibsList = [`${adapterPath}/*.*`];
}
var stream = gulp.src(copyLibsList);
return stream.pipe(gulp.dest(releaseDir));
});
gulp.task("modifyFile_QQ", versiontask, function() {
// 修改game.json文件
let gameJsonPath = path.join(releaseDir, "game.json");
let content = fs.readFileSync(gameJsonPath, "utf8");
let conJson = JSON.parse(content);
conJson.deviceOrientation = config.qqInfo.orientation;
content = JSON.stringify(conJson, null, 4);
fs.writeFileSync(gameJsonPath, content, "utf8");
if (config.version) {
let versionPath = releaseDir + "/version.json";
versionCon = fs.readFileSync(versionPath, "utf8");
versionCon = JSON.parse(versionCon);
}
let indexJsStr = (versionCon && versionCon["index.js"]) ? versionCon["index.js"] : "index.js";
// QQ小游戏项目修改index.js
let filePath = path.join(releaseDir, indexJsStr);
if (!fs.existsSync(filePath)) {
return;
}
let fileContent = fs.readFileSync(filePath, "utf8");
fileContent = fileContent.replace(/loadLib(\(['"])/gm, "require$1./");
fs.writeFileSync(filePath, fileContent, "utf8");
});
gulp.task("modifyMinJs_QQ", ["modifyFile_QQ"], function() {
// 如果保留了平台文件如果同时取消使用min类库就会出现文件引用不正确的问题
if (config.keepPlatformFile) {
let fileJsPath = path.join(releaseDir, "game.js");
let content = fs.readFileSync(fileJsPath, "utf-8");
content = content.replace(/min\/laya(-[\w\d]+)?\.qqmini\.min\.js/gm, "laya.qqmini.js");
fs.writeFileSync(fileJsPath, content, 'utf-8');
}
if (!config.useMinJsLibs) {
return;
}
let fileJsPath = path.join(releaseDir, "game.js");
let content = fs.readFileSync(fileJsPath, "utf-8");
content = content.replace(/(min\/)?laya(-[\w\d]+)?\.qqmini(\.min)?\.js/gm, "min/laya.qqmini.min.js");
fs.writeFileSync(fileJsPath, content, 'utf-8');
});
gulp.task("version_QQ", ["modifyMinJs_QQ"], function() {
// 如果保留了平台文件,如果同时开启版本管理,就会出现文件引用不正确的问题
if (config.keepPlatformFile) {
let fileJsPath = path.join(releaseDir, "game.js");
let content = fs.readFileSync(fileJsPath, "utf-8");
content = content.replace(/laya(-[\w\d]+)?\.qqmini/gm, "laya.qqmini");
content = content.replace(/index(-[\w\d]+)?\.js/gm, "index.js");
fs.writeFileSync(fileJsPath, content, 'utf-8');
}
if (config.version) {
let versionPath = releaseDir + "/version.json";
let gameJSPath = releaseDir + "/game.js";
let srcList = [versionPath, gameJSPath];
return gulp.src(srcList)
.pipe(revCollector())
.pipe(gulp.dest(releaseDir));
}
});
gulp.task("pluginEngin_QQ", ["version_QQ"], function(cb) {
if (!config.uesEnginePlugin) { // 没有使用引擎插件,还是像以前一样发布
let gameJsonPath = path.join(releaseDir, "game.json");
let gameJsonContent = fs.readFileSync(gameJsonPath, "utf8");
let conJson = JSON.parse(gameJsonContent);
if (conJson.plugins) {
delete conJson.plugins;
gameJsonContent = JSON.stringify(conJson, null, 4);
fs.writeFileSync(gameJsonPath, gameJsonContent, "utf8");
let gameJsPath = path.join(releaseDir, "game.js");
let gameJscontent = fs.readFileSync(gameJsPath, "utf8");
gameJscontent = gameJscontent.replace(/requirePlugin\("[\w\/\.]+"\);?\n?/mg, "");
fs.writeFileSync(gameJsPath, gameJscontent, "utf8");
}
return cb();
}
if (config.version) {
let versionPath = releaseDir + "/version.json";
versionCon = fs.readFileSync(versionPath, "utf8");
versionCon = JSON.parse(versionCon);
}
let indexJsStr = (versionCon && versionCon["index.js"]) ? versionCon["index.js"] : "index.js";
// 获取version等信息
let coreLibPath = path.join(workSpaceDir, "bin", "libs", "laya.core.js");
let isHasCoreLib = fs.existsSync(coreLibPath);
let isOldAsProj = fs.existsSync(`${workSpaceDir}/asconfig.json`) && !isHasCoreLib;
let isNewTsProj = fs.existsSync(`${workSpaceDir}/src/tsconfig.json`) && !isHasCoreLib;
let EngineVersion = getEngineVersion();
if (!EngineVersion) {
throw new Error(`读取引擎版本号失败,请于服务提供商联系!`);
}
if (!EngineVersion || EngineVersion.includes("beta") || !canUsePluginEngine(EngineVersion, minPluginVersion)) {
throw new Error(`该版本引擎无法使用引擎插件功能(engineVersion: ${EngineVersion})`);
}
console.log(`通过版本号检查: ${EngineVersion}`);
// 使用引擎插件
let localUseEngineList = [];
let copyEnginePathList;
new Promise(function(resolve, reject) {
console.log(`修改game.js和game.json`);
// 1) 修改game.js和game.json
// 修改game.js
let gameJsPath = path.join(releaseDir, "game.js");
let platformJs = config.useMinJsLibs ? `require("./libs/min/laya.qqmini.min.js");` : `require("./libs/laya.qqmini.js");`;
let gameJscontent = `require("weapp-adapter.js");\n${platformJs}\nrequirePlugin('layaPlugin');\nwindow.loadLib = require;\nrequire("./${indexJsStr}");`;
fs.writeFileSync(gameJsPath, gameJscontent, "utf8");
// 修改game.json使其支持引擎插件
let gameJsonPath = path.join(releaseDir, "game.json");
let gameJsonContent = fs.readFileSync(gameJsonPath, "utf8");
let conJson = JSON.parse(gameJsonContent);
conJson.plugins = {
"layaPlugin": {
"version": EngineVersion,
"provider": provider,
"path": "laya-libs"
}
}
gameJsonContent = JSON.stringify(conJson, null, 4);
fs.writeFileSync(gameJsonPath, gameJsonContent, "utf8");
resolve();
}).then(function() {
return new Promise(function(resolve, reject) {
console.log(`确定用到的插件引擎`);
// 2) 确定用到了那些插件引擎并将插件引擎从index.js的引用中去掉
let indexJsPath = path.join(releaseDir, indexJsStr);
let indexJsCon = fs.readFileSync(indexJsPath, "utf8");
let item, fullRequireItem;
for (let i = 0, len = fullRemoteEngineList.length; i < len; i++) {
item = fullRemoteEngineList[i];
fullRequireItem = config.useMinJsLibs ? `require("./libs/min/${item}")` : `require("./libs/${item}")`;
if (indexJsCon.includes(fullRequireItem)) {
let _item = item.replace(".min.js", ".js"), _minItem = item;
localUseEngineList.push(_item);
indexJsCon = indexJsCon.replace(fullRequireItem + ";", "").replace(fullRequireItem + ",", "").replace(fullRequireItem, "");
// 如果引用了压缩的类库将其重命名为未压缩的类库并拷贝到libs中
if (config.useMinJsLibs) {
let oldMinlibPath = path.join(releaseDir, "libs", "min", _minItem);
let newMinlibPath = path.join(releaseDir, "libs", "min", _item);
let newlibPath = path.join(releaseDir, "libs", _item);
fs.renameSync(oldMinlibPath, newMinlibPath);
// fs.copyFileSync(newlibPath, newMinlibPath);
let con = fs.readFileSync(newMinlibPath, "utf8");
fs.writeFileSync(newlibPath, con, "utf8");
fs.unlinkSync(newMinlibPath);
}
}
}
if (isOldAsProj || isNewTsProj) { // 如果as||ts_new语言开发者将laya.js也写入index.js中了将其删掉
fullRequireItem = `require("./laya.js")`;
if (indexJsCon.includes(fullRequireItem)) {
indexJsCon = indexJsCon.replace(fullRequireItem + ";", "").replace(fullRequireItem + ",", "").replace(fullRequireItem, "");
}
}
fs.writeFileSync(indexJsPath, indexJsCon, "utf8");
// ts/js再次修改game.js仅引用使用到的类库
// as||ts_new因为本地只有laya.js无法仅引用使用到的类库
if (!isOldAsProj && !isNewTsProj) {
let pluginCon = "";
localUseEngineList.forEach(function(item) {
pluginCon += `requirePlugin("layaPlugin/${item}");\n`;
});
let gameJsPath = path.join(releaseDir, "game.js");
let gameJsCon = fs.readFileSync(gameJsPath, "utf8");
gameJsCon = gameJsCon.replace(`requirePlugin('layaPlugin');`, pluginCon);
fs.writeFileSync(gameJsPath, gameJsCon, "utf8");
}
resolve();
});
}).then(function() {
return new Promise(function(resolve, reject) {
console.log(`将本地的引擎插件移动到laya-libs中`);
// 3) 将本地的引擎插件移动到laya-libs中
let libsPath = /** config.useMinJsLibs ? `${releaseDir}/libs/min` : */`${releaseDir}/libs`;
copyEnginePathList = [`${libsPath}/{${localUseEngineList.join(",")}}`];
if (isOldAsProj || isNewTsProj) { // 单独拷贝laya.js
copyEnginePathList = [`${releaseDir}/laya.js`];
}
gulp.src(copyEnginePathList).pipe(gulp.dest(`${releaseDir}/laya-libs`));
setTimeout(resolve, 500);
});
}).then(function() {
return new Promise(function(resolve, reject) {
console.log(`将libs中的本地引擎插件删掉`);
// 4) 将libs中的本地引擎插件删掉
del(copyEnginePathList, { force: true }).then(resolve);
});
}).then(function() {
return new Promise(async function(resolve, reject) {
console.log(`完善引擎插件目录`);
// 5) 引擎插件目录laya-libs中还需要新建几个文件使该目录能够使用
if (isOldAsProj || isNewTsProj) { // 单独拷贝laya.js
localUseEngineList.push("laya.js");
}
let
layalibsPath = path.join(releaseDir, "laya-libs"),
engineIndex = path.join(layalibsPath, "index.js"),
engineplugin = path.join(layalibsPath, "plugin.json"),
enginesignature = path.join(layalibsPath, "signature.json");
// index.js
if (!fs.existsSync(layalibsPath)) {
throw new Error("引擎插件目录创建失败,请与服务提供商联系!");
}
let indexCon = "";
localUseEngineList.forEach(function(item) {
indexCon += `require("./${item}");\n`;
});
fs.writeFileSync(engineIndex, indexCon, "utf8");
// plugin.json
let pluginCon = {"main": "index.js"};
fs.writeFileSync(engineplugin, JSON.stringify(pluginCon, null, 4), "utf8");
// signature.json目前平台方将其作为保留用途不会做插件的md5校验IDE仍将生成md5
let signatureCon = {
"provider": provider,
"signature": []
};
localUseEngineList.unshift("index.js");
let fileName, md5Str;
for (let i = 0, len = localUseEngineList.length; i < len; i++) {
fileName = localUseEngineList[i];
let md5Str = await getFileMd5(path.join(releaseDir, "laya-libs", fileName));
signatureCon.signature.push({
"path": fileName,
"md5": md5Str
});
}
fs.writeFileSync(enginesignature, JSON.stringify(signatureCon, null, 4), "utf8");
resolve();
});
})
.then(function() {
cb();
}).catch(function(e) {
throw e;
})
});
gulp.task("buildQQProj", ["pluginEngin_QQ"], function() {
console.log("all tasks completed");
});

View File

@ -0,0 +1,265 @@
// v1.1.5
const ideModuleDir = global.ideModuleDir;
const workSpaceDir = global.workSpaceDir;
//引用插件模块
const gulp = require(ideModuleDir + "gulp");
const fs = require("fs");
const path = require("path");
const del = require(ideModuleDir + "del");
const revCollector = require(ideModuleDir + 'gulp-rev-collector');
let copyLibsTask = ["copyPlatformLibsJsFile"];
let versiontask = ["version2"];
let
config,
releaseDir,
tempReleaseDir;
let versionCon; // 版本管理version.json
let commandSuffix,
layarepublicPath;
let subList = [];
gulp.task("preCreate_TBMini", copyLibsTask, function() {
releaseDir = global.releaseDir;
tempReleaseDir = global.tempReleaseDir;
config = global.config;
commandSuffix = global.commandSuffix;
layarepublicPath = global.layarepublicPath;
});
gulp.task("copyPlatformFile_TBMini", versiontask, function() {
releaseDir = path.dirname(releaseDir);
let adapterPath = path.join(layarepublicPath, "LayaAirProjectPack", "lib", "data", "taobaofiles");
let hasPublishPlatform =
fs.existsSync(path.join(releaseDir, "app.js")) &&
fs.existsSync(path.join(releaseDir, "app.json")) &&
fs.existsSync(path.join(releaseDir, "package.json"));
let copyLibsList;
if (hasPublishPlatform) {
copyLibsList = [`${adapterPath}/node_modules/layaengine/adapter.js`];
} else {
copyLibsList = [`${adapterPath}/**/*.*`];
}
var stream = gulp.src(copyLibsList, {base: adapterPath});
return stream.pipe(gulp.dest(releaseDir));
});
gulp.task("copyFiles2Pages_TBMini", ["copyPlatformFile_TBMini"], function() {
return gulp.src([`${tempReleaseDir}/**/*.*`, `!${tempReleaseDir}/libs/**/*.*`]).pipe(gulp.dest(`${releaseDir}/pages/index`));
});
gulp.task("moveToLibs_TBMini", ["copyFiles2Pages_TBMini"], function() {
let libsPath = path.join(tempReleaseDir, "libs");
let layaenginePath = path.join(releaseDir, "node_modules", "layaengine", "libs");
return gulp.src(`${libsPath}/**/*.*`)
.pipe(gulp.dest(layaenginePath));
});
gulp.task("delFiles_TBMini", ["moveToLibs_TBMini"], function(cb) {
let delList = [`${tempReleaseDir}/**`];
del(delList, { force: true }).then(paths => {
cb();
}).catch((err) => {
throw err;
})
});
gulp.task("modifyFile_TBMini", ["delFiles_TBMini"], function() {
if (config.version || config.enableVersion) {
let versionPath = path.join(releaseDir, "pages", "index", "version.json");
versionCon = fs.readFileSync(versionPath, "utf-8");
versionCon = JSON.parse(versionCon);
}
// 修改 app.json mini.project.json 文件
let miniProJJsonPath = path.join(releaseDir, "mini.project.json");
let minicontent = fs.readFileSync(miniProJJsonPath, "utf8");
let miniConJson = JSON.parse(minicontent);
let appJsonPath = path.join(releaseDir, "app.json");
let content = fs.readFileSync(appJsonPath, "utf8");
let conJson = JSON.parse(content);
// 先删掉之前的记录
delete conJson.subPackages;
delete conJson.subPackageBuildType;
delete miniConJson.enableEnhancedBuild;
let index = 0, value;
while(miniConJson.include.length > index) {
value = miniConJson.include[index];
if (value.match(/[\w]+\/\*\*/mg)) {
miniConJson.include.splice(index, 1);
continue;
}
index++;
}
if (config.taobaoInfo.subpack) { // 分包
let subpack = config.taobaoSubpack;
let subitem, obj;
conJson.subPackages = [];
for (let i = 0, len = subpack.length; i < len; i++) {
subitem = subpack[i];
obj = {
"root": subitem.name
};
if (config.taobaoInfo.ispagesub) { // 页面分包
if (!subitem.root) continue;
obj.pages = subitem.root.split(",")
} else { // 资源分包
conJson.subPackageBuildType = "shared";
miniConJson.enableEnhancedBuild = true;
if (!miniConJson.include) miniConJson.include = [];
miniConJson.include.push(`${subitem.name}/**`);
}
conJson.subPackages.push(obj);
}
}
content = JSON.stringify(conJson, null, 4);
fs.writeFileSync(appJsonPath, content, "utf8");
minicontent = JSON.stringify(miniConJson, null, 4);
fs.writeFileSync(miniProJJsonPath, minicontent, "utf8");
// 修改index.js
let indexJsStr = (versionCon && versionCon["index.js"]) ? versionCon["index.js"] : "index.js";
let indexFilePath = path.join(releaseDir, "pages", "index", indexJsStr);
if (!fs.existsSync(indexFilePath)) {
return;
}
let indexFileContent = fs.readFileSync(indexFilePath, "utf-8");
indexFileContent = indexFileContent.replace(/(window.screenOrientation\s*=\s*"\w+"[,;]?)/gm, "/**$1*/");
indexFileContent = indexFileContent.replace(/loadLib(\(['"]libs\/)/gm, `require("layaengine/libs/`);
indexFileContent = indexFileContent.replace(/loadLib(\(['"])/gm, "require$1./");
indexFileContent = indexFileContent.replace(/require\(\"\.\/laya([-\w]*)\.js\"\)/gm, `require("layaengine/laya$1.js")`);
// 特殊的,增加清除缓存
indexFileContent = indexFileContent.replace(/(require(\(['"][\w\/\.]+['"]\));?)/gm, "delete require.cache[require.resolve$2];\n$1");
fs.writeFileSync(indexFilePath, indexFileContent, "utf-8");
})
gulp.task("movesubpack_TBMini", ["modifyFile_TBMini"], function() {
if (!config.taobaoInfo.subpack) { // 分包
return;
}
let subpack = config.taobaoSubpack;
let subitem, obj;
// conJson.subPackages = [];
for (let i = 0, len = subpack.length; i < len; i++) {
subitem = subpack[i];
subList.push(`${subitem.name}/**`);
}
let source = `${path.join(releaseDir, "pages", "index")}/${subList.length > 1 ? `{${subList.join(",")}}` : `${subList[0]}`}`;
return gulp.src(source, { base: path.join(releaseDir, "pages", "index") }).pipe(gulp.dest(releaseDir));
})
gulp.task("rmsubpack_TBMini", ["movesubpack_TBMini"], function(cb) {
if (!config.taobaoInfo.subpack || subList.length == 0) { // 分包
return cb();
}
let delList = [];
for (let i = 0, len = subList.length; i < len; i++) {
delList.push(`${releaseDir}/pages/index/${subList[i]}`);
}
console.log(delList);
del(delList, { force: true }).then(paths => {
cb();
}).catch((err) => {
throw err;
})
});
gulp.task("modifyMinJs_TBMini", ["rmsubpack_TBMini"], function() {
// 如果保留了平台文件如果同时取消使用min类库就会出现文件引用不正确的问题
if (config.keepPlatformFile) {
let fileJsPath = path.join(releaseDir, "pages", "index", "game.js");
let content = fs.readFileSync(fileJsPath, "utf-8");
content = content.replace(/min\/laya(-[\w\d]+)?\.tbmini\.min\.js/gm, "laya.tbmini.js");
fs.writeFileSync(fileJsPath, content, 'utf-8');
}
if (!config.useMinJsLibs) {
return;
}
let fileJsPath = path.join(releaseDir, "pages", "index", "game.js");
let content = fs.readFileSync(fileJsPath, "utf-8");
content = content.replace(/(min\/)?laya(-[\w\d]+)?\.tbmini(\.min)?\.js/gm, "min/laya.tbmini.min.js");
fs.writeFileSync(fileJsPath, content, 'utf-8');
});
gulp.task("modifyLibsJs_TBMini", ["modifyMinJs_TBMini"], function() {
const NONCORESTR = "var window = $global.window;\nvar document = window.document;\nvar XMLHttpRequest = window.XMLHttpRequest;\nvar Laya = window.Laya;\nvar Config = window.Config;\nvar Config3D = window.Config3D;\nvar Laya3D = window.Laya3D;\nvar performance = window.performance;\nvar CANNON = window.CANNON;\nvar spine = window.spin;\n";
const CORESTR = "var window = $global.window;\nvar document = window.document;\nvar XMLHttpRequest = window.XMLHttpRequest;\n";
// libs
let libsPath = path.join(releaseDir, "node_modules", "layaengine", "libs", config.useMinJsLibs ? "min" : "");
let libsList = fs.readdirSync(libsPath);
for (let libName, fullPath, con, len = libsList.length, i = 0; i < len; i++) {
libName = libsList[i];
fullPath = path.join(libsPath, libName);
con = fs.readFileSync(fullPath, "utf8");
if (/laya(-[\w\d]+)?\.core/gm.test(libName)) {
con = CORESTR + con;
} else {
con = NONCORESTR + con;
}
fs.writeFileSync(fullPath, con, "utf8");
}
// bundle.js
let bundleJsStr = (versionCon && versionCon["js/bundle.js"]) ? versionCon["js/bundle.js"] : "js/bundle.js";
let bundlePath = path.join(releaseDir, "pages", "index", bundleJsStr);
let con = fs.readFileSync(bundlePath, "utf8");
// as 侵入式的修改bundle.js
if (fs.existsSync(path.join(workSpaceDir, "asconfig.json"))) {
let fileList = fs.readdirSync(path.join(workSpaceDir, "src"));
for (let i = 0, len = fileList.length, fileItem, filePath, isDir; i < len; i++) {
fileItem = fileList[i];
filePath = path.join(workSpaceDir, "src", fileItem);
isDir = fs.statSync(filePath).isDirectory();
if (isDir && (con.includes(`window.${fileItem} = {};`) || con.includes(`window.${fileItem}={}`))) {
// 因为压缩时不能禁用逗号,只能穷尽所有可能
con = con.replace(`window.${fileItem} = {};`, `var ${fileItem} = window.${fileItem} = {};`)
.replace(`;window.${fileItem}={};`, `;var ${fileItem}=window.${fileItem}={};`)
.replace(`,window.${fileItem}={};`, `;var ${fileItem}=window.${fileItem}={};`)
.replace(`,window.${fileItem}={},`, `;var ${fileItem}=window.${fileItem}={};`)
.replace(`;window.${fileItem}={},`, `;var ${fileItem}=window.${fileItem}={};`)
if (!con.includes(`;var ${fileItem}=window.${fileItem}={};`)) {
con = con.replace(`window.${fileItem}={}`, `;var ${fileItem}=window.${fileItem}={};`)
}
}
}
}
con = NONCORESTR + con;
fs.writeFileSync(bundlePath, con, "utf8");
// laya.js
let layaJsStr = (versionCon && versionCon["laya.js"]) ? versionCon["laya.js"] : "laya.js";
let layaPath = path.join(releaseDir, "pages", "index", layaJsStr);
if (fs.existsSync(layaPath)) {
let con = fs.readFileSync(layaPath, "utf8");
con = CORESTR + con;
// 移动到 layaengine 下
let newLayaPath = path.join(releaseDir, "node_modules", "layaengine", layaJsStr);
fs.writeFileSync(newLayaPath, con, "utf8");
fs.unlinkSync(layaPath);
}
});
gulp.task("version_TBMini", ["modifyLibsJs_TBMini"], function() {
// 如果保留了平台文件,如果同时开启版本管理,就会出现文件引用不正确的问题
if (config.keepPlatformFile) {
let fileJsPath = path.join(releaseDir, "pages", "index", "game.js");
let content = fs.readFileSync(fileJsPath, "utf-8");
content = content.replace(/laya(-[\w\d]+)?\.tbmini/gm, "laya.tbmini");
content = content.replace(/index(-[\w\d]+)?\.js/gm, "index.js");
fs.writeFileSync(fileJsPath, content, 'utf-8');
}
if (config.version) {
let versionPath = path.join(releaseDir, "pages", "index", "version.json");
let gameJSPath = path.join(releaseDir, "pages", "index", "game.js");
let srcList = [versionPath, gameJSPath];
return gulp.src(srcList)
.pipe(revCollector())
.pipe(gulp.dest(`${releaseDir}/pages/index`));
}
});
gulp.task("buildTBMiniProj", ["version_TBMini"], function() {
console.log("all tasks completed");
});

View File

@ -0,0 +1,177 @@
// v1.0.2
const ideModuleDir = global.ideModuleDir;
const workSpaceDir = global.workSpaceDir;
//引用插件模块
const gulp = require(ideModuleDir + "gulp");
const fs = require("fs");
const path = require("path");
const del = require(ideModuleDir + "del");
const revCollector = require(ideModuleDir + 'gulp-rev-collector');
let copyLibsTask = ["copyPlatformLibsJsFile"];
let versiontask = ["version2"];
let
config,
releaseDir,
tempReleaseDir;
let versionCon; // 版本管理version.json
let commandSuffix,
layarepublicPath;
gulp.task("preCreate_TBWidget", copyLibsTask, function() {
releaseDir = global.releaseDir;
tempReleaseDir = global.tempReleaseDir;
config = global.config;
commandSuffix = global.commandSuffix;
layarepublicPath = global.layarepublicPath;
});
gulp.task("copyPlatformFile_TBWidget", versiontask, function() {
releaseDir = path.dirname(releaseDir);
let adapterPath = path.join(layarepublicPath, "LayaAirProjectPack", "lib", "data", "taobaowidgetfiles");
let hasPublishPlatform =
fs.existsSync(path.join(releaseDir, "client")) &&
fs.existsSync(path.join(releaseDir, "widget")) &&
fs.existsSync(path.join(releaseDir, "mini.project.json"));
let copyLibsList;
if (hasPublishPlatform) {
copyLibsList = [`${adapterPath}/widget/component/adapter.js`];
} else {
copyLibsList = [`${adapterPath}/**/*.*`];
}
var stream = gulp.src(copyLibsList, {base: adapterPath});
return stream.pipe(gulp.dest(releaseDir));
});
gulp.task("copyFiles2Pages_TBWidget", ["copyPlatformFile_TBWidget"], function() {
return gulp.src(`${tempReleaseDir}/**/*.*`).pipe(gulp.dest(`${releaseDir}/widget/component`));
});
gulp.task("delFiles_TBWidget", ["copyFiles2Pages_TBWidget"], function(cb) {
let delList = [`${tempReleaseDir}/**`];
del(delList, { force: true }).then(paths => {
cb();
}).catch((err) => {
throw err;
})
});
gulp.task("modifyFile_TBWidget", ["delFiles_TBWidget"], function() {
if (config.version || config.enableVersion) {
let versionPath = path.join(releaseDir, "widget", "component", "version.json");
versionCon = fs.readFileSync(versionPath, "utf-8");
versionCon = JSON.parse(versionCon);
}
// 修改index.js
let indexJsStr = (versionCon && versionCon["index.js"]) ? versionCon["index.js"] : "index.js";
let indexFilePath = path.join(releaseDir, "widget", "component", indexJsStr);
if (!fs.existsSync(indexFilePath)) {
return;
}
let indexFileContent = fs.readFileSync(indexFilePath, "utf-8");
indexFileContent = indexFileContent.replace(/(window.screenOrientation\s*=\s*"\w+"[,;]?)/gm, "/**$1*/");
indexFileContent = indexFileContent.replace(/loadLib(\(['"]libs\/)/gm, `require("./libs/`);
indexFileContent = indexFileContent.replace(/loadLib(\(['"])/gm, "require$1./");
indexFileContent = indexFileContent.replace(/require\(\"\.\/laya([-\w]*)\.js\"\)/gm, `require("./laya$1.js")`);
// 特殊的,增加清除缓存
indexFileContent = indexFileContent.replace(/(require(\(['"][\w\/\.]+['"]\));?)/gm, "delete require.cache[require.resolve$2];\n$1");
fs.writeFileSync(indexFilePath, indexFileContent, "utf-8");
})
gulp.task("modifyMinJs_TBWidget", ["modifyFile_TBWidget"], function() {
// 如果保留了平台文件如果同时取消使用min类库就会出现文件引用不正确的问题
if (config.keepPlatformFile) {
let fileJsPath = path.join(releaseDir, "widget", "component", "game.js");
let content = fs.readFileSync(fileJsPath, "utf-8");
content = content.replace(/min\/laya(-[\w\d]+)?\.tbpluginmini\.min\.js/gm, "laya.tbpluginmini.js");
fs.writeFileSync(fileJsPath, content, 'utf-8');
}
if (!config.useMinJsLibs) {
return;
}
let fileJsPath = path.join(releaseDir, "widget", "component", "game.js");
let content = fs.readFileSync(fileJsPath, "utf-8");
content = content.replace(/(min\/)?laya(-[\w\d]+)?\.tbpluginmini(\.min)?\.js/gm, "min/laya.tbpluginmini.min.js");
fs.writeFileSync(fileJsPath, content, 'utf-8');
});
gulp.task("modifyLibsJs_TBWidget", ["modifyMinJs_TBWidget"], function() {
const NONCORESTR = "var window = $global.window;\nvar document = window.document;\nvar XMLHttpRequest = window.XMLHttpRequest;\nvar Laya = window.Laya;\nvar Config = window.Config;\nvar Config3D = window.Config3D;\nvar Laya3D = window.Laya3D;\nvar performance = window.performance;\nvar CANNON = window.CANNON;\nvar spine = window.spin;\n";
const CORESTR = "var window = $global.window;\nvar document = window.document;\nvar XMLHttpRequest = window.XMLHttpRequest;\n";
// libs
let libsPath = path.join(releaseDir, "widget", "component", "libs", config.useMinJsLibs ? "min" : "");
let libsList = fs.readdirSync(libsPath);
for (let libName, fullPath, con, len = libsList.length, i = 0; i < len; i++) {
libName = libsList[i];
fullPath = path.join(libsPath, libName);
if (path.extname(fullPath) !== ".js") {
continue;
}
con = fs.readFileSync(fullPath, "utf8");
if (/laya(-[\w\d]+)?\.core/gm.test(libName)) {
con = CORESTR + con;
} else {
con = NONCORESTR + con;
}
fs.writeFileSync(fullPath, con, "utf8");
}
// bundle.js
let bundleJsStr = (versionCon && versionCon["js/bundle.js"]) ? versionCon["js/bundle.js"] : "js/bundle.js";
let bundlePath = path.join(releaseDir, "widget", "component", bundleJsStr);
let con = fs.readFileSync(bundlePath, "utf8");
// as 侵入式的修改bundle.js
if (fs.existsSync(path.join(workSpaceDir, "asconfig.json"))) {
let fileList = fs.readdirSync(path.join(workSpaceDir, "src"));
for (let i = 0, len = fileList.length, fileItem, filePath, isDir; i < len; i++) {
fileItem = fileList[i];
filePath = path.join(workSpaceDir, "src", fileItem);
isDir = fs.statSync(filePath).isDirectory();
if (isDir && (con.includes(`window.${fileItem} = {};`) || con.includes(`window.${fileItem}={}`))) {
// 因为压缩时不能禁用逗号,只能穷尽所有可能
con = con.replace(`window.${fileItem} = {};`, `var ${fileItem} = window.${fileItem} = {};`)
.replace(`;window.${fileItem}={};`, `;var ${fileItem}=window.${fileItem}={};`)
.replace(`,window.${fileItem}={};`, `;var ${fileItem}=window.${fileItem}={};`)
.replace(`,window.${fileItem}={},`, `;var ${fileItem}=window.${fileItem}={};`)
.replace(`;window.${fileItem}={},`, `;var ${fileItem}=window.${fileItem}={};`)
if (!con.includes(`;var ${fileItem}=window.${fileItem}={};`)) {
con = con.replace(`window.${fileItem}={}`, `;var ${fileItem}=window.${fileItem}={};`)
}
}
}
}
con = NONCORESTR + con;
fs.writeFileSync(bundlePath, con, "utf8");
// laya.js
let layaJsStr = (versionCon && versionCon["laya.js"]) ? versionCon["laya.js"] : "laya.js";
let layaPath = path.join(releaseDir, "widget", "component", layaJsStr);
if (fs.existsSync(layaPath)) {
let con = fs.readFileSync(layaPath, "utf8");
con = CORESTR + con;
fs.writeFileSync(layaPath, con, "utf8");
}
});
gulp.task("version_TBWidget", ["modifyLibsJs_TBWidget"], function() {
// 如果保留了平台文件,如果同时开启版本管理,就会出现文件引用不正确的问题
if (config.keepPlatformFile) {
let fileJsPath = path.join(releaseDir, "widget", "component", "game.js");
let content = fs.readFileSync(fileJsPath, "utf-8");
content = content.replace(/laya(-[\w\d]+)?\.tbpluginmini/gm, "laya.tbpluginmini");
content = content.replace(/index(-[\w\d]+)?\.js/gm, "index.js");
fs.writeFileSync(fileJsPath, content, 'utf-8');
}
if (config.version) {
let versionPath = path.join(releaseDir, "widget", "component", "version.json");
let gameJSPath = path.join(releaseDir, "widget", "component", "game.js");
let srcList = [versionPath, gameJSPath];
return gulp.src(srcList)
.pipe(revCollector())
.pipe(gulp.dest(`${releaseDir}/widget/component`));
}
});
gulp.task("buildTBWidgetProj", ["version_TBWidget"], function() {
console.log("all tasks completed");
});

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,384 @@
// v1.8.9
const ideModuleDir = global.ideModuleDir;
const workSpaceDir = global.workSpaceDir;
//引用插件模块
const gulp = require(ideModuleDir + "gulp");
const fs = require("fs");
const path = require("path");
const del = require(ideModuleDir + "del");
const revCollector = require(ideModuleDir + 'gulp-rev-collector');
const { getEngineVersion, getFileMd5, canUsePluginEngine } = require("./pub_utils");
const provider = "wx70d8aa25ec591f7a";
const minPluginVersion = "2.0.1";
let fullRemoteEngineList = ["laya.core.js", "laya.filter.js", "laya.ani.js", "laya.tiledmap.js", "laya.d3.js", "laya.html.js", "laya.particle.js", "laya.ui.js", "laya.webgl.js", "laya.filter.js", "laya.d3Plugin.js"];
let copyLibsTask = ["copyPlatformLibsJsFile"];
let versiontask = ["version2"];
let
config,
releaseDir;
let isOpendataProj;
let versionCon; // 版本管理version.json
let commandSuffix,
layarepublicPath;
gulp.task("preCreate_WX", copyLibsTask, function() {
releaseDir = global.releaseDir;
config = global.config;
commandSuffix = global.commandSuffix;
layarepublicPath = global.layarepublicPath;
if (config.useMinJsLibs) {
fullRemoteEngineList = fullRemoteEngineList.map((item, index) => {
return item.replace(".js", ".min.js");
})
}
// 是否是开放域项目
let projInfoPath = path.join(workSpaceDir, path.basename(workSpaceDir) + ".laya");
let isExist = fs.existsSync(projInfoPath);
if (isExist) {
try {
let projInfo = fs.readFileSync(projInfoPath, "utf8");
projInfo = projInfo && JSON.parse(projInfo);
isOpendataProj = projInfo.layaProType === 12;
} catch (e) {}
}
});
gulp.task("copyPlatformFile_WX", ["preCreate_WX"], function() {
let adapterPath = path.join(layarepublicPath, "LayaAirProjectPack", "lib", "data", "wxfiles");
// 开放域项目
if (isOpendataProj) {
let platformDir = path.join(adapterPath, "weapp-adapter.js");
let stream = gulp.src(platformDir);
return stream.pipe(gulp.dest(releaseDir));
}
// 如果新建项目时已经点击了"微信/百度小游戏bin目录快速调试",不再拷贝
let hasPlatform =
fs.existsSync(path.join(workSpaceDir, "bin", "game.js")) &&
fs.existsSync(path.join(workSpaceDir, "bin", "game.json")) &&
fs.existsSync(path.join(workSpaceDir, "bin", "project.config.json"));
let hasPublishPlatform =
fs.existsSync(path.join(releaseDir, "game.js")) &&
fs.existsSync(path.join(releaseDir, "game.json")) &&
fs.existsSync(path.join(releaseDir, "project.config.json"));
let copyLibsList;
if (hasPlatform || hasPublishPlatform) {
copyLibsList = [`${adapterPath}/weapp-adapter.js`];
} else {
copyLibsList = [`${adapterPath}/*.*`];
}
var stream = gulp.src(copyLibsList);
return stream.pipe(gulp.dest(releaseDir));
});
// 适配微信wasm
gulp.task("fitwasm_WX", ["copyPlatformFile_WX"], function() {
let
phy3dWasmJs = path.join(releaseDir, "libs", "laya.physics3D.wasm.js"),
phy3dWasmMinJs = path.join(releaseDir, "libs", "min", "laya.physics3D.wasm.min.js");
let isPhy3dWasmJsExist = fs.existsSync(phy3dWasmJs);
let isPhy3dWasmMinJsExist = fs.existsSync(phy3dWasmMinJs);
if (!isPhy3dWasmJsExist && !isPhy3dWasmMinJsExist) {
return;
}
let phy3dWasmName = isPhy3dWasmJsExist ? phy3dWasmJs : phy3dWasmMinJs;
con = fs.readFileSync(phy3dWasmName, "utf8");
con = con.replace(/WebAssembly/mg, "WXWebAssembly");
con = con.replace(/(fetch\(("[\w./]+")\)\.then[(\w)\s=>]+\{\n?\s*[(\.\w)\s=>]+\{)(\n?\s*WXWebAssembly\.instantiate\()(\w+,)/mg, "/** $1 */$3/** $4 */$2,");
con = con.replace(/(\}\);?\n?\s*\}\);?\n?)(\s*\}\);?\n?\s*\};)/mg, "/** $1 */$2");
fs.writeFileSync(phy3dWasmName, con, "utf8");
})
// 开放域的情况下合并game.js和index.js并删除game.js
gulp.task("openData_WX", versiontask, function (cb) {
if (config.openDataZone) {
let versionCon;
if (config.version) {
let versionPath = releaseDir + "/version.json";
versionCon = fs.readFileSync(versionPath, "utf8");
versionCon = JSON.parse(versionCon);
}
let indexJsStr = (versionCon && versionCon["index.js"]) ? versionCon["index.js"] : "index.js";
let indexPath = path.join(releaseDir, indexJsStr);
let indexjs = readFile(indexPath);
let gamejs = readFile(releaseDir + "/game.js");
if (gamejs && indexjs) {
gamejs = gamejs.replace(`require("index.js")`, indexjs);
fs.writeFileSync(indexPath, gamejs, 'utf-8');
}
if (isOpendataProj) {
// 开放域项目将game.js删掉发布最小包
del(`${releaseDir}/game.js`, { force: true }).then(paths => {
cb();
});
} else {
cb();
}
} else {
cb();
}
});
function readFile(path) {
if (fs.existsSync(path)) {
return fs.readFileSync(path, "utf-8");
}
return null;
}
gulp.task("modifyMinJs_WX", ["openData_WX"], function() {
if (config.openDataZone) {
return;
}
// 如果保留了平台文件如果同时取消使用min类库就会出现文件引用不正确的问题
if (config.keepPlatformFile) {
let fileJsPath = path.join(releaseDir, "game.js");
let content = fs.readFileSync(fileJsPath, "utf-8");
content = content.replace(/min\/laya(-[\w\d]+)?\.wxmini\.min\.js/gm, "laya.wxmini.js");
fs.writeFileSync(fileJsPath, content, 'utf-8');
}
if (!config.useMinJsLibs) {
return;
}
let fileJsPath = path.join(releaseDir, "game.js");
let content = fs.readFileSync(fileJsPath, "utf-8");
content = content.replace(/(min\/)?laya(-[\w\d]+)?\.wxmini(\.min)?\.js/gm, "min/laya.wxmini.min.js");
fs.writeFileSync(fileJsPath, content, 'utf-8');
});
gulp.task("version_WX", ["modifyMinJs_WX"], function() {
if (config.openDataZone) {
return;
}
// 如果保留了平台文件,如果同时开启版本管理,就会出现文件引用不正确的问题
if (config.keepPlatformFile) {
let fileJsPath = path.join(releaseDir, "game.js");
let content = fs.readFileSync(fileJsPath, "utf-8");
content = content.replace(/laya(-[\w\d]+)?\.wxmini/gm, "laya.wxmini");
content = content.replace(/index(-[\w\d]+)?\.js/gm, "index.js");
fs.writeFileSync(fileJsPath, content, 'utf-8');
}
if (config.version) {
let versionPath = releaseDir + "/version.json";
let gameJSPath = releaseDir + "/game.js";
let srcList = [versionPath, gameJSPath];
return gulp.src(srcList)
.pipe(revCollector())
.pipe(gulp.dest(releaseDir));
}
});
gulp.task("optimizeOpen_WX", ["version_WX"], function(cb) {
let wxOptimize = config.wxOptimize;
if (!wxOptimize || !wxOptimize.useOptimizeOpen) { // 没有使用微信引擎插件,还是像以前一样发布
return cb();
}
// 首屏加载优化(秒开)修改game.json
let filePath = path.join(releaseDir, "game.json");
if (!fs.existsSync(filePath)) {
return cb();
}
let fileContent = fs.readFileSync(filePath, "utf8");
let fileConObj = JSON.parse(fileContent);
if (wxOptimize.preloadRes) {
fileConObj.preloadResources = wxOptimize.preloadResList;
} else {
delete fileConObj.preloadResources;
}
if (wxOptimize.preloadSubpack) {
fileConObj.preloadSubpackages = wxOptimize.preloadSubpackList;
} else {
delete fileConObj.preloadSubpackages;
}
fs.writeFileSync(filePath, JSON.stringify(fileConObj, null, 4), "utf8");
return cb();
});
gulp.task("pluginEngin_WX", ["optimizeOpen_WX"], function(cb) {
if (!config.uesEnginePlugin) { // 没有使用引擎插件,还是像以前一样发布
let gameJsonPath = path.join(releaseDir, "game.json");
if (!fs.existsSync(gameJsonPath)) {
return cb();
}
let gameJsonContent = fs.readFileSync(gameJsonPath, "utf8");
let conJson = JSON.parse(gameJsonContent);
if (conJson.plugins) {
delete conJson.plugins;
gameJsonContent = JSON.stringify(conJson, null, 4);
fs.writeFileSync(gameJsonPath, gameJsonContent, "utf8");
let gameJsPath = path.join(releaseDir, "game.js");
let gameJscontent = fs.readFileSync(gameJsPath, "utf8");
gameJscontent = gameJscontent.replace(/requirePlugin\("[\w\/\.]+"\);?\n?/mg, "");
fs.writeFileSync(gameJsPath, gameJscontent, "utf8");
}
return cb();
}
if (config.version) {
let versionPath = releaseDir + "/version.json";
versionCon = fs.readFileSync(versionPath, "utf8");
versionCon = JSON.parse(versionCon);
}
let indexJsStr = (versionCon && versionCon["index.js"]) ? versionCon["index.js"] : "index.js";
// 获取version等信息
let coreLibPath = path.join(workSpaceDir, "bin", "libs", "laya.core.js");
let isHasCoreLib = fs.existsSync(coreLibPath);
let isOldAsProj = fs.existsSync(`${workSpaceDir}/asconfig.json`) && !isHasCoreLib;
let isNewTsProj = fs.existsSync(`${workSpaceDir}/src/tsconfig.json`) && !isHasCoreLib;
let EngineVersion = getEngineVersion();
if (!EngineVersion) {
throw new Error(`读取引擎版本号失败,请于服务提供商联系!`);
}
if (!EngineVersion || EngineVersion.includes("beta") || !canUsePluginEngine(EngineVersion, minPluginVersion)) {
throw new Error(`该版本引擎无法使用引擎插件功能(engineVersion: ${EngineVersion})`);
}
console.log(`通过版本号检查: ${EngineVersion}`);
// 使用引擎插件
let localUseEngineList = [];
let copyEnginePathList;
new Promise(function(resolve, reject) {
console.log(`修改game.js和game.json`);
// 1) 修改game.js和game.json
// 修改game.js
let gameJsPath = path.join(releaseDir, "game.js");
let platformJs = config.useMinJsLibs ? `require("./libs/min/laya.wxmini.min.js");` : `require("./libs/laya.wxmini.js");`;
let gameJscontent = `require("weapp-adapter.js");\n${platformJs}\nrequirePlugin('layaPlugin');\nwindow.loadLib = require;\nrequire("./${indexJsStr}");`;
fs.writeFileSync(gameJsPath, gameJscontent, "utf8");
// 修改game.json使其支持引擎插件
let gameJsonPath = path.join(releaseDir, "game.json");
let gameJsonContent = fs.readFileSync(gameJsonPath, "utf8");
let conJson = JSON.parse(gameJsonContent);
conJson.plugins = {
"layaPlugin": {
"version": EngineVersion,
"provider": provider,
"path": "laya-libs"
}
}
gameJsonContent = JSON.stringify(conJson, null, 4);
fs.writeFileSync(gameJsonPath, gameJsonContent, "utf8");
resolve();
}).then(function() {
return new Promise(function(resolve, reject) {
console.log(`确定用到的插件引擎`);
// 2) 确定用到了那些插件引擎并将插件引擎从index.js的引用中去掉
let indexJsPath = path.join(releaseDir, indexJsStr);
let indexJsCon = fs.readFileSync(indexJsPath, "utf8");
let item, fullRequireItem;
for (let i = 0, len = fullRemoteEngineList.length; i < len; i++) {
item = fullRemoteEngineList[i];
fullRequireItem = config.useMinJsLibs ? `loadLib("libs/min/${item}")` : `loadLib("libs/${item}")`;
if (indexJsCon.includes(fullRequireItem)) {
let _item = item.replace(".min.js", ".js"), _minItem = item;
localUseEngineList.push(_item);
indexJsCon = indexJsCon.replace(fullRequireItem + ";", "").replace(fullRequireItem + ",", "").replace(fullRequireItem, "");
// 如果引用了压缩的类库将其重命名为未压缩的类库并拷贝到libs中
if (config.useMinJsLibs) {
let oldMinlibPath = path.join(releaseDir, "libs", "min", _minItem);
let newMinlibPath = path.join(releaseDir, "libs", "min", _item);
let newlibPath = path.join(releaseDir, "libs", _item);
fs.renameSync(oldMinlibPath, newMinlibPath);
// fs.copyFileSync(newlibPath, newMinlibPath);
let con = fs.readFileSync(newMinlibPath, "utf8");
fs.writeFileSync(newlibPath, con, "utf8");
fs.unlinkSync(newMinlibPath);
}
}
}
if (isOldAsProj || isNewTsProj) { // 如果as||ts_new语言开发者将laya.js也写入index.js中了将其删掉
fullRequireItem = `loadLib("laya.js")`;
if (indexJsCon.includes(fullRequireItem)) {
indexJsCon = indexJsCon.replace(fullRequireItem + ";", "").replace(fullRequireItem + ",", "").replace(fullRequireItem, "");
}
}
fs.writeFileSync(indexJsPath, indexJsCon, "utf8");
// ts/js再次修改game.js仅引用使用到的类库
// as||ts_new因为本地只有laya.js无法仅引用使用到的类库
if (!isOldAsProj && !isNewTsProj) {
let pluginCon = "";
localUseEngineList.forEach(function(item) {
pluginCon += `requirePlugin("layaPlugin/${item}");\n`;
});
let gameJsPath = path.join(releaseDir, "game.js");
let gameJsCon = fs.readFileSync(gameJsPath, "utf8");
gameJsCon = gameJsCon.replace(`requirePlugin('layaPlugin');`, pluginCon);
fs.writeFileSync(gameJsPath, gameJsCon, "utf8");
}
resolve();
});
}).then(function() {
return new Promise(function(resolve, reject) {
console.log(`将本地的引擎插件移动到laya-libs中`);
// 3) 将本地的引擎插件移动到laya-libs中
let libsPath = /** config.useMinJsLibs ? `${releaseDir}/libs/min` : */`${releaseDir}/libs`;
copyEnginePathList = [`${libsPath}/{${localUseEngineList.join(",")}}`];
if (isOldAsProj || isNewTsProj) { // 单独拷贝laya.js
copyEnginePathList = [`${releaseDir}/laya.js`];
}
gulp.src(copyEnginePathList).pipe(gulp.dest(`${releaseDir}/laya-libs`));
setTimeout(resolve, 500);
});
}).then(function() {
return new Promise(function(resolve, reject) {
console.log(`将libs中的本地引擎插件删掉`);
// 4) 将libs中的本地引擎插件删掉
del(copyEnginePathList, { force: true }).then(resolve);
});
}).then(function() {
return new Promise(async function(resolve, reject) {
console.log(`完善引擎插件目录`);
// 5) 引擎插件目录laya-libs中还需要新建几个文件使该目录能够使用
if (isOldAsProj || isNewTsProj) { // 单独拷贝laya.js
localUseEngineList.push("laya.js");
}
let
layalibsPath = path.join(releaseDir, "laya-libs"),
engineIndex = path.join(layalibsPath, "index.js"),
engineplugin = path.join(layalibsPath, "plugin.json"),
enginesignature = path.join(layalibsPath, "signature.json");
// index.js
if (!fs.existsSync(layalibsPath)) {
throw new Error("引擎插件目录创建失败,请与服务提供商联系!");
}
let indexCon = "";
localUseEngineList.forEach(function(item) {
indexCon += `require("./${item}");\n`;
});
fs.writeFileSync(engineIndex, indexCon, "utf8");
// plugin.json
let pluginCon = {"main": "index.js"};
fs.writeFileSync(engineplugin, JSON.stringify(pluginCon, null, 4), "utf8");
// signature.json目前平台方将其作为保留用途不会做插件的md5校验IDE仍将生成md5
let signatureCon = {
"provider": provider,
"signature": []
};
localUseEngineList.unshift("index.js");
let fileName, md5Str;
for (let i = 0, len = localUseEngineList.length; i < len; i++) {
fileName = localUseEngineList[i];
let md5Str = await getFileMd5(path.join(releaseDir, "laya-libs", fileName));
signatureCon.signature.push({
"path": fileName,
"md5": md5Str
});
}
fs.writeFileSync(enginesignature, JSON.stringify(signatureCon, null, 4), "utf8");
resolve();
});
})
.then(function() {
cb();
}).catch(function(e) {
throw e;
})
});
gulp.task("buildWXProj", ["pluginEngin_WX"], function() {
console.log("all tasks completed");
});

View File

@ -0,0 +1,379 @@
// v1.8.2
const ideModuleDir = global.ideModuleDir;
const workSpaceDir = global.workSpaceDir;
//引用插件模块
const gulp = require(ideModuleDir + "gulp");
const fs = require("fs");
const path = require("path");
const childProcess = require("child_process");
const del = require(ideModuleDir + "del");
const revCollector = require(ideModuleDir + 'gulp-rev-collector');
let copyLibsTask = ["copyPlatformLibsJsFile"];
let versiontask = ["version2"];
let
config,
releaseDir,
tempReleaseDir, // 小米临时拷贝目录
projDir; // 小米快游戏工程目录
let versionCon; // 版本管理version.json
let commandSuffix,
opensslPath,
layarepublicPath;
// 创建小米项目前拷贝小米引擎库、修改index.js
gulp.task("preCreate_XM", copyLibsTask, function() {
releaseDir = global.releaseDir;
config = global.config;
commandSuffix = global.commandSuffix;
opensslPath = global.opensslPath;
layarepublicPath = global.layarepublicPath;
tempReleaseDir = global.tempReleaseDir;
});
gulp.task("copyPlatformFile_XM", ["preCreate_XM"], function() {
let xmAdapterPath = path.join(layarepublicPath, "LayaAirProjectPack", "lib", "data", "xmfiles");
let copyLibsList = [`${xmAdapterPath}/**/*.*`];
var stream = gulp.src(copyLibsList);
return stream.pipe(gulp.dest(tempReleaseDir));
});
gulp.task("createProj_XM", versiontask, function() {
releaseDir = path.dirname(releaseDir);
projDir = path.join(releaseDir, config.xmInfo.projName);
// 如果有即存项目,不再新建
let isProjExist = fs.existsSync(projDir + "/node_modules") &&
fs.existsSync(projDir + "/sign");
if (isProjExist) {
return;
}
// 在项目中创建小米项目
return new Promise((resolve, reject) => {
console.log("(proj)开始创建小米快游戏项目,请耐心等待(预计需要10分钟)...");
let cmd = `npx${commandSuffix}`;
let args = ["create-quickgame", config.xmInfo.projName, `path=${releaseDir}`,
`package=${config.xmInfo.package}`, `versionName=${config.xmInfo.versionName}`,
`versionCode=${config.xmInfo.versionCode}`, `minPlatformVersion=${config.xmInfo.minPlatformVersion}`,
`icon=/layaicon/${path.basename(config.xmInfo.icon)}`, `name=${config.xmInfo.name}`, `rebuild=true`];
let opts = {
shell: true
};
let cp = childProcess.spawn(cmd, args, opts);
cp.stdout.on('data', (data) => {
console.log(`stdout: ${data}`);
});
cp.stderr.on('data', (data) => {
console.log(`stderr: ${data}`);
// reject();
});
cp.on('close', (code) => {
console.log(`子进程退出码:${code}`);
resolve();
});
});
});
// 拷贝文件到小米快游戏
gulp.task("copyFileToProj_XM", ["createProj_XM"], function() {
// 将临时文件夹中的文件,拷贝到项目中去
let originalDir = `${tempReleaseDir}/**/*.*`;
let stream = gulp.src(originalDir);
return stream.pipe(gulp.dest(path.join(projDir)));
});
// 拷贝icon到小米快游戏
gulp.task("copyIconToProj_XM", ["copyFileToProj_XM"], function() {
let originalDir = config.xmInfo.icon;
let stream = gulp.src(originalDir);
return stream.pipe(gulp.dest(path.join(projDir, "layaicon")));
});
// 清除小米快游戏临时目录
gulp.task("clearTempDir_XM", ["copyIconToProj_XM"], function() {
// 删掉临时目录
return del([tempReleaseDir], { force: true });
});
// 生成release签名(私钥文件 private.pem 和证书文件 certificate.pem )
gulp.task("generateSign_XM", ["clearTempDir_XM"], function() {
if (!config.xmSign.generateSign) {
return;
}
// https://doc.quickapp.cn/tools/compiling-tools.html
return new Promise((resolve, reject) => {
let cmd = `${opensslPath}`;
let args = ["req", "-newkey", "rsa:2048", "-nodes", "-keyout", "private.pem",
"-x509", "-days", "3650", "-out", "certificate.pem"];
let opts = {
cwd: projDir,
shell: true
};
let cp = childProcess.spawn(cmd, args, opts);
cp.stdout.on('data', (data) => {
console.log(`stdout: ${data}`);
});
cp.stderr.on('data', (data) => {
console.log(`stderr: ${data}`);
data += "";
if (data.includes("Country Name")) {
cp.stdin.write(`${config.xmSign.countryName}\n`);
console.log(`Country Name: ${config.xmSign.countryName}`);
} else if (data.includes("Province Name")) {
cp.stdin.write(`${config.xmSign.provinceName}\n`);
console.log(`Province Name: ${config.xmSign.provinceName}`);
} else if (data.includes("Locality Name")) {
cp.stdin.write(`${config.xmSign.localityName}\n`);
console.log(`Locality Name: ${config.xmSign.localityName}`);
} else if (data.includes("Organization Name")) {
cp.stdin.write(`${config.xmSign.orgName}\n`);
console.log(`Organization Name: ${config.xmSign.orgName}`);
} else if (data.includes("Organizational Unit Name")) {
cp.stdin.write(`${config.xmSign.orgUnitName}\n`);
console.log(`Organizational Unit Name: ${config.xmSign.orgUnitName}`);
} else if (data.includes("Common Name")) {
cp.stdin.write(`${config.xmSign.commonName}\n`);
console.log(`Common Name: ${config.xmSign.commonName}`);
} else if (data.includes("Email Address")) {
cp.stdin.write(`${config.xmSign.emailAddr}\n`);
console.log(`Email Address: ${config.xmSign.emailAddr}`);
// cp.stdin.end();
}
// reject();
});
cp.on('close', (code) => {
console.log(`子进程退出码:${code}`);
// 签名是否生成成功
let
privatePem = path.join(projDir, "private.pem"),
certificatePem = path.join(projDir, "certificate.pem");
let isSignExits = fs.existsSync(privatePem) && fs.existsSync(certificatePem);
if (!isSignExits) {
throw new Error("签名生成失败,请检查!");
}
resolve();
});
});
});
// 拷贝sign文件到指定位置
gulp.task("copySignFile_XM", ["generateSign_XM"], function() {
if (config.xmSign.generateSign) { // 新生成的签名
// 移动签名文件到项目中Laya & 小米快游戏项目中)
let
privatePem = path.join(projDir, "private.pem"),
certificatePem = path.join(projDir, "certificate.pem");
let isSignExits = fs.existsSync(privatePem) && fs.existsSync(certificatePem);
if (!isSignExits) {
return;
}
let
xiaomiDest = `${projDir}/sign/release`,
layaDest = `${workSpaceDir}/sign/release`;
let stream = gulp.src([privatePem, certificatePem]);
return stream.pipe(gulp.dest(xiaomiDest))
.pipe(gulp.dest(layaDest));
} else if (config.xmInfo.useReleaseSign && !config.xmSign.generateSign) { // 使用release签名并且没有重新生成
// 从项目中将签名拷贝到小米快游戏项目中
let
privatePem = path.join(workSpaceDir, "sign", "release", "private.pem"),
certificatePem = path.join(workSpaceDir, "sign", "release", "certificate.pem");
let isSignExits = fs.existsSync(privatePem) && fs.existsSync(certificatePem);
if (!isSignExits) {
return;
}
let
xiaomiDest = `${projDir}/sign/release`;
let stream = gulp.src([privatePem, certificatePem]);
return stream.pipe(gulp.dest(xiaomiDest));
}
});
gulp.task("deleteSignFile_XM", ["copySignFile_XM"], function() {
if (config.xmSign.generateSign) { // 新生成的签名
let
privatePem = path.join(projDir, "private.pem"),
certificatePem = path.join(projDir, "certificate.pem");
return del([privatePem, certificatePem], { force: true });
}
});
gulp.task("modifyFile_XM", ["deleteSignFile_XM"], function() {
// 修改manifest.json文件
let manifestPath = path.join(projDir, "manifest.json");
if (!fs.existsSync(manifestPath)) {
return;
}
let manifestContent = fs.readFileSync(manifestPath, "utf8");
let manifestJson = JSON.parse(manifestContent);
manifestJson.package = config.xmInfo.package;
manifestJson.name = config.xmInfo.name;
manifestJson.orientation = config.xmInfo.orientation;
manifestJson.config.logLevel = config.xmInfo.logLevel || "off";
manifestJson.versionName = config.xmInfo.versionName;
manifestJson.versionCode = config.xmInfo.versionCode;
manifestJson.minPlatformVersion = config.xmInfo.minPlatformVersion;
manifestJson.icon = `/layaicon/${path.basename(config.xmInfo.icon)}`;
if (config.xmInfo.subpack) { // 分包
manifestJson.subpackages = config.xmSubpack;
// 检测分包目录是否有入口文件
console.log('检查分包文件...');
if (manifestJson.subpackages) {
for(let i = 0; i < manifestJson.subpackages.length; i ++) {
let conf = manifestJson.subpackages[i];
if (conf.root) {
let rootPath = path.join(projDir, conf.root);
if (!fs.existsSync(rootPath)) {
throw new Error(`分包文件/目录 ${rootPath} 不存在!`);
}
let jsIndex = rootPath.lastIndexOf('.js');
let jsPath = rootPath;
if (jsIndex < 0 || jsIndex != rootPath.length - 3) {
jsPath = path.join(rootPath, 'main.js');
}
if (!fs.existsSync(jsPath)) {
throw new Error(`分包文件/目录 ${jsPath} 不存在!`);
}
}
}
}
} else {
delete manifestJson.subpackages;
}
fs.writeFileSync(manifestPath, JSON.stringify(manifestJson, null, 4), "utf8");
if (config.version) {
let versionPath = projDir + "/version.json";
versionCon = fs.readFileSync(versionPath, "utf8");
versionCon = JSON.parse(versionCon);
}
let indexJsStr = (versionCon && versionCon["index.js"]) ? versionCon["index.js"] : "index.js";
// 修改main.js文件
let mainJsPath = path.join(projDir, "main.js");
let mainJsCon = fs.existsSync(mainJsPath) && fs.readFileSync(mainJsPath, "utf8");
let reWriteMainJs = !fs.existsSync(mainJsPath) || !mainJsCon.includes("xmmini");
if (reWriteMainJs) {
mainJsCon = 'require("./qg-adapter.js");\nrequire("./libs/laya.xmmini.js");\nrequire("./index.js");';
fs.writeFileSync(mainJsPath, mainJsCon, "utf8");
}
// 小米项目修改index.js
let filePath = path.join(projDir, indexJsStr);
if (!fs.existsSync(filePath)) {
return;
}
let fileContent = fs.readFileSync(filePath, "utf8");
fileContent = fileContent.replace(/loadLib(\(['"])/gm, "require$1./");
fs.writeFileSync(filePath, fileContent, "utf8");
})
gulp.task("modifyMinJs_XM", ["modifyFile_XM"], function() {
let fileJsPath = path.join(projDir, "main.js");
let content = fs.readFileSync(fileJsPath, "utf-8");
if (!config.useMinJsLibs) { // 默认保留了平台文件如果同时取消使用min类库就会出现文件引用不正确的问题
content = content.replace(/min\/laya(-[\w\d]+)?\.xmmini\.min\.js/gm, "laya.xmmini.js");
} else {
content = content.replace(/(min\/)?laya(-[\w\d]+)?\.xmmini(\.min)?\.js/gm, "min/laya.xmmini.min.js");
}
fs.writeFileSync(fileJsPath, content, 'utf-8');
});
gulp.task("version_XM", ["modifyMinJs_XM"], function () {
// main.js默认不覆盖如果同时开启版本管理就会出现文件引用不正确的问题
let fileJsPath = path.join(projDir, "main.js");
let content = fs.readFileSync(fileJsPath, "utf-8");
content = content.replace(/laya(-[\w\d]+)?\.xmmini/gm, "laya.xmmini");
content = content.replace(/index(-[\w\d]+)?\.js/gm, "index.js");
fs.writeFileSync(fileJsPath, content, 'utf-8');
if (config.version) {
let versionPath = projDir + "/version.json";
let mainJSPath = projDir + "/main.js";
let srcList = [versionPath, mainJSPath];
return gulp.src(srcList)
.pipe(revCollector())
.pipe(gulp.dest(projDir));
}
});
// 打包rpk
gulp.task("buildRPK_XM", ["version_XM"], function() {
// 在小米轻游戏项目目录中执行:
// npm run build || npm run release
let cmdStr = "build";
if (config.xmInfo.useReleaseSign) {
cmdStr = "release";
}
return new Promise((resolve, reject) => {
let cmd = `npm${commandSuffix}`;
let args = ["run", cmdStr];
let opts = {
cwd: projDir,
shell: true
};
let cp = childProcess.spawn(cmd, args, opts);
// let cp = childProcess.spawn(`npx${commandSuffix}`, ['-v']);
cp.stdout.on('data', (data) => {
console.log(`stdout: ${data}`);
});
cp.stderr.on('data', (data) => {
console.log(`stderr: ${data}`);
// reject();
});
cp.on('close', (code) => {
console.log(`子进程退出码:${code}`);
// rpk是否生成成功
let distRpkPath = path.join(projDir, "dist", `${config.xmInfo.package}${config.xmInfo.useReleaseSign ? ".release" : ".debug"}.rpk`);
if (!fs.existsSync(distRpkPath)) {
throw new Error("rpk生成失败请检查");
}
resolve();
});
});
});
gulp.task("showQRCode_XM", ["buildRPK_XM"], function() {
// 在小米轻游戏项目目录中执行:
// npm run server
return new Promise((resolve, reject) => {
let cmd = `npm${commandSuffix}`;
let args = ["run", "server"];
let opts = {
cwd: projDir,
shell: true
};
let cp = childProcess.spawn(cmd, args, opts);
// let cp = childProcess.spawn(`npx${commandSuffix}`, ['-v']);
cp.stdout.on('data', (data) => {
console.log(`${data}`);
// 输出pidmacos要用: macos无法kill进程树也无法执行命令获取3000端口pid(没有查询权限)导致无法kill这个进程
console.log('xm_qrcode_pid:' + cp.pid);
});
cp.stderr.on('data', (data) => {
console.log(`stderr: ${data}`);
// reject();
});
cp.on('close', (code) => {
console.log(`子进程退出码:${code}`);
resolve();
});
});
});
gulp.task("buildXiaomiProj", ["showQRCode_XM"], function() {
console.log("all tasks completed");
});

View File

@ -0,0 +1,118 @@
// v1.0.0
const ideModuleDir = global.ideModuleDir;
const workSpaceDir = global.workSpaceDir;
//引用插件模块
const gulp = require(ideModuleDir + "gulp");
const fs = require("fs");
const path = require("path");
const revCollector = require(ideModuleDir + 'gulp-rev-collector');
let copyLibsTask = ["copyPlatformLibsJsFile"];
let versiontask = ["version2"];
let
config,
releaseDir;
let versionCon; // 版本管理version.json
let commandSuffix,
layarepublicPath;
gulp.task("preCreate_youku", copyLibsTask, function() {
releaseDir = global.releaseDir;
config = global.config;
commandSuffix = global.commandSuffix;
layarepublicPath = global.layarepublicPath;
});
gulp.task("copyPlatformFile_youku", ["preCreate_youku"], function() {
let adapterPath = path.join(layarepublicPath, "LayaAirProjectPack", "lib", "data", "youkufiles");
let hasPublishPlatform =
fs.existsSync(path.join(releaseDir, "game.js")) &&
fs.existsSync(path.join(releaseDir, "game.json")) &&
fs.existsSync(path.join(releaseDir, "project.config.json"));
let copyLibsList;
if (hasPublishPlatform) {
copyLibsList = [`${adapterPath}/my-adapter.js`];
} else {
copyLibsList = [`${adapterPath}/*.*`];
}
var stream = gulp.src(copyLibsList);
return stream.pipe(gulp.dest(releaseDir));
});
gulp.task("modifyFile_youku", versiontask, function() {
// 修改game.json文件
let gameJsonPath = path.join(releaseDir, "game.json");
let content = fs.readFileSync(gameJsonPath, "utf8");
let conJson = JSON.parse(content);
conJson.screenOrientation = config.youkuInfo.orientation;
content = JSON.stringify(conJson, null, 4);
fs.writeFileSync(gameJsonPath, content, "utf8");
// 修改game.js
let filePath = path.join(releaseDir, "game.js");
let fileContent = fs.existsSync(filePath) && fs.readFileSync(filePath, "utf8");
let reWriteMainJs = !fs.existsSync(filePath) || !fileContent.includes("ykmini");
if (reWriteMainJs) {
fileContent = `window.navigator.userAgent += " youku";
require("./my-adapter.js");
require("./libs/laya.ykmini.js");\nrequire("./index.js");`;
fs.writeFileSync(filePath, fileContent, "utf8");
}
if (config.version || config.enableVersion) {
let versionPath = releaseDir + "/version.json";
versionCon = fs.readFileSync(versionPath, "utf8");
versionCon = JSON.parse(versionCon);
}
// 修改index.js
let indexJsStr = (versionCon && versionCon["index.js"]) ? versionCon["index.js"] : "index.js";
let indexFilePath = path.join(releaseDir, indexJsStr);
if (!fs.existsSync(indexFilePath)) {
return;
}
let indexFileContent = fs.readFileSync(indexFilePath, "utf8");
indexFileContent = indexFileContent.replace(/loadLib(\(['"])/gm, "require$1./");
fs.writeFileSync(indexFilePath, indexFileContent, "utf8");
})
gulp.task("modifyMinJs_youku", ["modifyFile_youku"], function() {
// 如果保留了平台文件如果同时取消使用min类库就会出现文件引用不正确的问题
if (config.keepPlatformFile) {
let fileJsPath = path.join(releaseDir, "game.js");
let content = fs.readFileSync(fileJsPath, "utf-8");
content = content.replace(/min\/laya(-[\w\d]+)?\.ykmini\.min\.js/gm, "laya.ykmini.js");
fs.writeFileSync(fileJsPath, content, 'utf-8');
}
if (!config.useMinJsLibs) {
return;
}
let fileJsPath = path.join(releaseDir, "game.js");
let content = fs.readFileSync(fileJsPath, "utf-8");
content = content.replace(/(min\/)?laya(-[\w\d]+)?\.ykmini(\.min)?\.js/gm, "min/laya.ykmini.min.js");
fs.writeFileSync(fileJsPath, content, 'utf-8');
});
gulp.task("version_youku", ["modifyMinJs_youku"], function () {
// 如果保留了平台文件,如果同时开启版本管理,就会出现文件引用不正确的问题
if (config.keepPlatformFile) {
let fileJsPath = path.join(releaseDir, "game.js");
let content = fs.readFileSync(fileJsPath, "utf-8");
content = content.replace(/laya(-[\w\d]+)?\.ykmini/gm, "laya.ykmini");
content = content.replace(/index(-[\w\d]+)?\.js/gm, "index.js");
fs.writeFileSync(fileJsPath, content, 'utf-8');
}
if (config.version) {
let versionPath = releaseDir + "/version.json";
let gameJSPath = releaseDir + "/game.js";
let srcList = [versionPath, gameJSPath];
return gulp.src(srcList)
.pipe(revCollector())
.pipe(gulp.dest(releaseDir));
}
});
gulp.task("buildYKProj", ["version_youku"], function() {
console.log("all tasks completed");
});

View File

@ -0,0 +1,26 @@
{
"version": "0.2.0",
"configurations": [
{
"name": "chrome调试",
"type": "chrome",
"request": "launch",
"file": "${workspaceRoot}/bin/index.html",
// "换成自己的谷歌安装路径,":
//window : "C:/Program Files (x86)/Google/Chrome/Application/chrome.exe"
//mac "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome";
// "runtimeExecutable": "C:/Program Files (x86)/Google/Chrome/Application/chrome.exe",
"runtimeArgs": [
"--allow-file-access-from-files",
"--disable-web-security"
],
"sourceMaps": true,
"webRoot": "${workspaceRoot}",
//userDataDir,${tmpdir}
"userDataDir": "${workspaceRoot}/.laya/chrome",
"sourceMapPathOverrides": {
"src/*": "${workspaceRoot}/src/*"
}
}
]
}

View File

@ -0,0 +1,9 @@
# Laya Air
测试于 LayaAir 2.12.0
1. 使用请前先 `npm install`
2. 由于 Laya 本身不支持 NPM所以 `npm install` 的作用仅仅是获取代码提示(类型定义)。
3. `tsrpc-browser` 打包为单个文件 `src/tsrpc_browser/index.js`,请从该文件中引用 `HttpClient`、`WsClient` 等。
示例,见 `Main.ts` 头部。

View File

@ -0,0 +1 @@
{"res/atlas/comp.atlas":["comp/",["btn_close.png","button.png","check_circle.png","checkbox.png","clip_num.png","clip_tree_arrow.png","clip_tree_folder.png","colorPicker.png","combobox.png","fontClip.png","fontClip_num.png","hscroll$bar.png","hscroll$down.png","hscroll$up.png","hscroll.png","hslider$bar.png","hslider.png","html.png","image.png","img_bg.png","img_bg2.png","img_bg3.png","img_bg4.png","img_bg5.png","img_blank.png","label.png","progress$bar.png","progress.png","radio.png","radiogroup.png","tab.png","textarea.png","textinput.png","vscroll$bar.png","vscroll$down.png","vscroll$up.png","vscroll.png","vslider$bar.png","vslider.png"]],"res/atlas/test.atlas":["test/",["b1.png","b2.png","block.png","c1.png","c2.png","p1.png","t1.png","tra.png"]]}

View File

@ -0,0 +1,32 @@
<html>
<head>
<title>www.layabox.com</title>
<meta charset='utf-8' />
<meta name='renderer' content='webkit' />
<meta name='viewport' content='width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no'
/>
<meta name='apple-mobile-web-app-capable' content='yes' />
<meta name='full-screen' content='true' />
<meta name='x5-fullscreen' content='true' />
<meta name='360-fullscreen' content='true' />
<meta name='laya' screenorientation='landscape' />
<meta http-equiv='expires' content='0' />
<meta http-equiv='X-UA-Compatible' content='IE=edge,chrome=1' />
<meta http-equiv='expires' content='0' />
<meta http-equiv='Cache-Control' content='no-siteapp' />
</head>
<body>
<script type="text/javascript">
function loadLib(url) {
var script = document.createElement("script");
script.async = false;
script.src = url;
document.body.appendChild(script);
}
</script>
<script type="text/javascript" src="index.js"></script>
</body>
</html>

View File

@ -0,0 +1,15 @@
/**
* 设置LayaNative屏幕方向可设置以下值
* landscape 横屏
* portrait 竖屏
* sensor_landscape 横屏(双方向)
* sensor_portrait 竖屏(双方向)
*/
window.screenOrientation = "sensor_landscape";
//-----libs-begin-----
loadLib("libs/laya.core.js")
loadLib("libs/laya.ui.js")
loadLib("libs/laya.physics.js")
//-----libs-end-------
loadLib("js/bundle.js");

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,678 @@
(function (exports, Laya) {
'use strict';
class AccelerationInfo {
constructor() {
}
}
class RotationInfo {
constructor() {
}
}
class Accelerator extends Laya.EventDispatcher {
constructor(singleton) {
super();
this.onDeviceOrientationChange = this.onDeviceOrientationChange.bind(this);
}
static get instance() {
Accelerator._instance = Accelerator._instance || new Accelerator(0);
return Accelerator._instance;
}
on(type, caller, listener, args = null) {
super.on(type, caller, listener, args);
Laya.ILaya.Browser.window.addEventListener('devicemotion', this.onDeviceOrientationChange);
return this;
}
off(type, caller, listener, onceOnly = false) {
if (!this.hasListener(type))
Laya.ILaya.Browser.window.removeEventListener('devicemotion', this.onDeviceOrientationChange);
return super.off(type, caller, listener, onceOnly);
}
onDeviceOrientationChange(e) {
var interval = e.interval;
Accelerator.acceleration.x = e.acceleration.x;
Accelerator.acceleration.y = e.acceleration.y;
Accelerator.acceleration.z = e.acceleration.z;
Accelerator.accelerationIncludingGravity.x = e.accelerationIncludingGravity.x;
Accelerator.accelerationIncludingGravity.y = e.accelerationIncludingGravity.y;
Accelerator.accelerationIncludingGravity.z = e.accelerationIncludingGravity.z;
Accelerator.rotationRate.alpha = e.rotationRate.gamma * -1;
Accelerator.rotationRate.beta = e.rotationRate.alpha * -1;
Accelerator.rotationRate.gamma = e.rotationRate.beta;
if (Laya.ILaya.Browser.onAndroid) {
if (Laya.ILaya.Browser.userAgent.indexOf("Chrome") > -1) {
Accelerator.rotationRate.alpha *= 180 / Math.PI;
Accelerator.rotationRate.beta *= 180 / Math.PI;
Accelerator.rotationRate.gamma *= 180 / Math.PI;
}
Accelerator.acceleration.x *= -1;
Accelerator.accelerationIncludingGravity.x *= -1;
}
else if (Laya.ILaya.Browser.onIOS) {
Accelerator.acceleration.y *= -1;
Accelerator.acceleration.z *= -1;
Accelerator.accelerationIncludingGravity.y *= -1;
Accelerator.accelerationIncludingGravity.z *= -1;
interval *= 1000;
}
this.event(Laya.Event.CHANGE, [Accelerator.acceleration, Accelerator.accelerationIncludingGravity, Accelerator.rotationRate, interval]);
}
static getTransformedAcceleration(acceleration) {
Accelerator.transformedAcceleration = Accelerator.transformedAcceleration || new AccelerationInfo();
Accelerator.transformedAcceleration.z = acceleration.z;
if (Laya.ILaya.Browser.window.orientation == 90) {
Accelerator.transformedAcceleration.x = acceleration.y;
Accelerator.transformedAcceleration.y = -acceleration.x;
}
else if (Laya.ILaya.Browser.window.orientation == -90) {
Accelerator.transformedAcceleration.x = -acceleration.y;
Accelerator.transformedAcceleration.y = acceleration.x;
}
else if (!Laya.ILaya.Browser.window.orientation) {
Accelerator.transformedAcceleration.x = acceleration.x;
Accelerator.transformedAcceleration.y = acceleration.y;
}
else if (Laya.ILaya.Browser.window.orientation == 180) {
Accelerator.transformedAcceleration.x = -acceleration.x;
Accelerator.transformedAcceleration.y = -acceleration.y;
}
var tx;
if (Laya.ILaya.stage.canvasDegree == -90) {
tx = Accelerator.transformedAcceleration.x;
Accelerator.transformedAcceleration.x = -Accelerator.transformedAcceleration.y;
Accelerator.transformedAcceleration.y = tx;
}
else if (Laya.ILaya.stage.canvasDegree == 90) {
tx = Accelerator.transformedAcceleration.x;
Accelerator.transformedAcceleration.x = Accelerator.transformedAcceleration.y;
Accelerator.transformedAcceleration.y = -tx;
}
return Accelerator.transformedAcceleration;
}
}
Accelerator.acceleration = new AccelerationInfo();
Accelerator.accelerationIncludingGravity = new AccelerationInfo();
Accelerator.rotationRate = new RotationInfo();
class Shake extends Laya.EventDispatcher {
constructor() {
super();
}
static get instance() {
Shake._instance = Shake._instance || new Shake();
return Shake._instance;
}
start(throushold, interval) {
this.throushold = throushold;
this.shakeInterval = interval;
this.lastX = this.lastY = this.lastZ = NaN;
Accelerator.instance.on(Laya.Event.CHANGE, this, this.onShake);
}
stop() {
Accelerator.instance.off(Laya.Event.CHANGE, this, this.onShake);
}
onShake(acceleration, accelerationIncludingGravity, rotationRate, interval) {
if (isNaN(this.lastX)) {
this.lastX = accelerationIncludingGravity.x;
this.lastY = accelerationIncludingGravity.y;
this.lastZ = accelerationIncludingGravity.z;
this.lastMillSecond = Laya.ILaya.Browser.now();
return;
}
var deltaX = Math.abs(this.lastX - accelerationIncludingGravity.x);
var deltaY = Math.abs(this.lastY - accelerationIncludingGravity.y);
var deltaZ = Math.abs(this.lastZ - accelerationIncludingGravity.z);
if (this.isShaked(deltaX, deltaY, deltaZ)) {
var deltaMillSecond = Laya.ILaya.Browser.now() - this.lastMillSecond;
if (deltaMillSecond > this.shakeInterval) {
this.event(Laya.Event.CHANGE);
this.lastMillSecond = Laya.ILaya.Browser.now();
}
}
this.lastX = accelerationIncludingGravity.x;
this.lastY = accelerationIncludingGravity.y;
this.lastZ = accelerationIncludingGravity.z;
}
isShaked(deltaX, deltaY, deltaZ) {
return (deltaX > this.throushold && deltaY > this.throushold) ||
(deltaX > this.throushold && deltaZ > this.throushold) ||
(deltaY > this.throushold && deltaZ > this.throushold);
}
}
class GeolocationInfo {
setPosition(pos) {
this.pos = pos;
this.coords = pos.coords;
}
get latitude() {
return this.coords.latitude;
}
get longitude() {
return this.coords.longitude;
}
get altitude() {
return this.coords.altitude;
}
get accuracy() {
return this.coords.accuracy;
}
get altitudeAccuracy() {
return this.coords.altitudeAccuracy;
}
get heading() {
return this.coords.heading;
}
get speed() {
return this.coords.speed;
}
get timestamp() {
return this.pos.timestamp;
}
}
class Geolocation {
constructor() {
}
static getCurrentPosition(onSuccess, onError = null) {
Geolocation.navigator.geolocation.getCurrentPosition(function (pos) {
Geolocation.position.setPosition(pos);
onSuccess.runWith(Geolocation.position);
}, function (error) {
onError.runWith(error);
}, {
enableHighAccuracy: Geolocation.enableHighAccuracy,
timeout: Geolocation.timeout,
maximumAge: Geolocation.maximumAge
});
}
static watchPosition(onSuccess, onError) {
return Geolocation.navigator.geolocation.watchPosition(function (pos) {
Geolocation.position.setPosition(pos);
onSuccess.runWith(Geolocation.position);
}, function (error) {
onError.runWith(error);
}, {
enableHighAccuracy: Geolocation.enableHighAccuracy,
timeout: Geolocation.timeout,
maximumAge: Geolocation.maximumAge
});
}
static clearWatch(id) {
Geolocation.navigator.geolocation.clearWatch(id);
}
}
Geolocation.navigator = navigator;
Geolocation.position = new GeolocationInfo();
Geolocation.PERMISSION_DENIED = 1;
Geolocation.POSITION_UNAVAILABLE = 2;
Geolocation.TIMEOUT = 3;
Geolocation.supported = !!Geolocation.navigator.geolocation;
Geolocation.enableHighAccuracy = false;
Geolocation.timeout = 1E10;
Geolocation.maximumAge = 0;
class HtmlVideo extends Laya.Bitmap {
constructor() {
super();
this._w = 0;
this._h = 0;
this._width = 1;
this._height = 1;
this.createDomElement();
}
createDomElement() {
this._source = this.video = Laya.ILaya.Browser.createElement("video");
var style = this.video.style;
style.position = 'absolute';
style.top = '0px';
style.left = '0px';
this.video.addEventListener("loadedmetadata", () => {
this._w = this.video.videoWidth;
this._h = this.video.videoHeight;
});
}
setSource(url, extension) {
while (this.video.childElementCount)
this.video.firstChild.remove();
if (extension & 1)
this.appendSource(url, "video/mp4");
if (extension & 2)
this.appendSource(url + ".ogg", "video/ogg");
}
appendSource(source, type) {
var sourceElement = Laya.ILaya.Browser.createElement("source");
sourceElement.src = source;
sourceElement.type = type;
this.video.appendChild(sourceElement);
}
getVideo() {
return this.video;
}
_getSource() {
return this._source;
}
destroy() {
super.destroy();
var isConchApp = Laya.ILaya.Render.isConchApp;
if (isConchApp) {
this.video._destroy();
}
}
}
HtmlVideo.create = function () {
return new HtmlVideo();
};
class Media {
constructor() {
}
static supported() {
return !!Laya.ILaya.Browser.window.navigator.getUserMedia;
}
static getMedia(options, onSuccess, onError) {
if (Laya.ILaya.Browser.window.navigator.getUserMedia) {
Laya.ILaya.Browser.window.navigator.getUserMedia(options, function (stream) {
onSuccess.runWith(Laya.ILaya.Browser.window.URL.createObjectURL(stream));
}, function (err) {
onError.runWith(err);
});
}
}
}
class WebGLVideo extends HtmlVideo {
constructor() {
super();
var gl = Laya.LayaGL.instance;
this.gl = Laya.ILaya.Render.isConchApp ? window.LayaGLContext.instance : Laya.WebGLContext.mainContext;
this._source = this.gl.createTexture();
Laya.WebGLContext.bindTexture(this.gl, gl.TEXTURE_2D, this._source);
this.gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
this.gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
this.gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
this.gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
Laya.WebGLContext.bindTexture(this.gl, gl.TEXTURE_2D, null);
}
updateTexture() {
var gl = Laya.LayaGL.instance;
Laya.WebGLContext.bindTexture(this.gl, gl.TEXTURE_2D, this._source);
this.gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true);
this.gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, this.video);
this.gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false);
WebGLVideo.curBindSource = this._source;
}
get _glTexture() {
return this._source;
}
destroy() {
if (this._source) {
this.gl = Laya.ILaya.Render.isConchApp ? window.LayaGLContext.instance : Laya.WebGLContext.mainContext;
if (this.gl) {
if (WebGLVideo.curBindSource == this._source) {
Laya.WebGLContext.bindTexture(this.gl, this.gl.TEXTURE_2D, null);
WebGLVideo.curBindSource = null;
}
this.gl.deleteTexture(this._source);
}
}
super.destroy();
}
}
class Video extends Laya.Sprite {
constructor(width = 320, height = 240) {
super();
this.htmlVideo = new WebGLVideo();
this.videoElement = this.htmlVideo.getVideo();
this.videoElement.layaTarget = this;
this.internalTexture = new Laya.Texture(this.htmlVideo);
this.videoElement.addEventListener("abort", Video.onAbort);
this.videoElement.addEventListener("canplay", Video.onCanplay);
this.videoElement.addEventListener("canplaythrough", Video.onCanplaythrough);
this.videoElement.addEventListener("durationchange", Video.onDurationchange);
this.videoElement.addEventListener("emptied", Video.onEmptied);
this.videoElement.addEventListener("error", Video.onError);
this.videoElement.addEventListener("loadeddata", Video.onLoadeddata);
this.videoElement.addEventListener("loadedmetadata", Video.onLoadedmetadata);
this.videoElement.addEventListener("loadstart", Video.onLoadstart);
this.videoElement.addEventListener("pause", Video.onPause);
this.videoElement.addEventListener("play", Video.onPlay);
this.videoElement.addEventListener("playing", Video.onPlaying);
this.videoElement.addEventListener("progress", Video.onProgress);
this.videoElement.addEventListener("ratechange", Video.onRatechange);
this.videoElement.addEventListener("seeked", Video.onSeeked);
this.videoElement.addEventListener("seeking", Video.onSeeking);
this.videoElement.addEventListener("stalled", Video.onStalled);
this.videoElement.addEventListener("suspend", Video.onSuspend);
this.videoElement.addEventListener("timeupdate", Video.onTimeupdate);
this.videoElement.addEventListener("volumechange", Video.onVolumechange);
this.videoElement.addEventListener("waiting", Video.onWaiting);
this.videoElement.addEventListener("ended", this.onPlayComplete['bind'](this));
this.size(width, height);
if (Laya.ILaya.Browser.onMobile) {
this.videoElement["x5-playsInline"] = true;
this.videoElement["x5-playsinline"] = true;
this.videoElement.x5PlaysInline = true;
this.videoElement.playsInline = true;
this.videoElement["webkit-playsInline"] = true;
this.videoElement["webkit-playsinline"] = true;
this.videoElement.webkitPlaysInline = true;
this.videoElement.playsinline = true;
this.videoElement.style.playsInline = true;
this.videoElement.crossOrigin = "anonymous";
this.videoElement.setAttribute('crossorigin', "anonymous");
this.videoElement.setAttribute('playsinline', 'true');
this.videoElement.setAttribute('x5-playsinline', 'true');
this.videoElement.setAttribute('webkit-playsinline', 'true');
this.videoElement.autoplay = true;
this._clickhandle = this.onDocumentClick.bind(this);
Laya.ILaya.Browser.document.addEventListener("touchend", this._clickhandle);
}
}
static onAbort(e) { e.target.layaTarget.event("abort"); }
static onCanplay(e) { e.target.layaTarget.event("canplay"); }
static onCanplaythrough(e) { e.target.layaTarget.event("canplaythrough"); }
static onDurationchange(e) { e.target.layaTarget.event("durationchange"); }
static onEmptied(e) { e.target.layaTarget.event("emptied"); }
static onError(e) { e.target.layaTarget.event("error"); }
static onLoadeddata(e) { e.target.layaTarget.event("loadeddata"); }
static onLoadedmetadata(e) { e.target.layaTarget.event("loadedmetadata"); }
static onLoadstart(e) { e.target.layaTarget.event("loadstart"); }
static onPause(e) { e.target.layaTarget.event("pause"); }
static onPlay(e) { e.target.layaTarget.event("play"); }
static onPlaying(e) { e.target.layaTarget.event("playing"); }
static onProgress(e) { e.target.layaTarget.event("progress"); }
static onRatechange(e) { e.target.layaTarget.event("ratechange"); }
static onSeeked(e) { e.target.layaTarget.event("seeked"); }
static onSeeking(e) { e.target.layaTarget.event("seeking"); }
static onStalled(e) { e.target.layaTarget.event("stalled"); }
static onSuspend(e) { e.target.layaTarget.event("suspend"); }
static onTimeupdate(e) { e.target.layaTarget.event("timeupdate"); }
static onVolumechange(e) { e.target.layaTarget.event("volumechange"); }
static onWaiting(e) { e.target.layaTarget.event("waiting"); }
onPlayComplete(e) {
if (!Laya.ILaya.Render.isConchApp || !this.videoElement || !this.videoElement.loop)
Laya.ILaya.timer.clear(this, this.renderCanvas);
this.event("ended");
}
load(url) {
if (url.indexOf("blob:") == 0)
this.videoElement.src = url;
else
this.htmlVideo.setSource(url, 1);
}
play() {
this.videoElement.play();
Laya.ILaya.timer.frameLoop(1, this, this.renderCanvas);
}
pause() {
this.videoElement.pause();
Laya.ILaya.timer.clear(this, this.renderCanvas);
}
reload() {
this.videoElement.load();
}
canPlayType(type) {
var typeString;
switch (type) {
case 1:
typeString = "video/mp4";
break;
case 2:
typeString = "video/ogg";
break;
case 8:
typeString = "video/webm";
break;
}
return this.videoElement.canPlayType(typeString);
}
renderCanvas() {
if (this.readyState === 0)
return;
this.htmlVideo['updateTexture']();
this.graphics.clear();
this.graphics.drawTexture(this.internalTexture, 0, 0, this.width, this.height);
}
onDocumentClick() {
if (!this.videoElement || this.videoElement != 0)
return;
if (Laya.Browser.onIOS) {
this.videoElement.load();
}
else {
this.videoElement.play();
this.videoElement.pause();
}
Laya.ILaya.Browser.document.removeEventListener("touchend", this._clickhandle);
}
get buffered() {
return this.videoElement.buffered;
}
get currentSrc() {
return this.videoElement.currentSrc;
}
get currentTime() {
return this.videoElement.currentTime;
}
set currentTime(value) {
this.videoElement.currentTime = value;
this.renderCanvas();
}
set volume(value) {
this.videoElement.volume = value;
}
get volume() {
return this.videoElement.volume;
}
get readyState() {
return this.videoElement.readyState;
}
get videoWidth() {
return this.videoElement.videoWidth;
}
get videoHeight() {
return this.videoElement.videoHeight;
}
get duration() {
return this.videoElement.duration;
}
get ended() {
return this.videoElement.ended;
}
get error() {
return this.videoElement.error;
}
get loop() {
return this.videoElement.loop;
}
set loop(value) {
this.videoElement.loop = value;
}
set x(val) {
super.x = val;
if (Laya.ILaya.Render.isConchApp) {
var transform = Laya.ILaya.Utils.getTransformRelativeToWindow(this, 0, 0);
this.videoElement.style.left = transform.x;
}
}
get x() {
return super.x;
}
set y(val) {
super.y = val;
if (Laya.ILaya.Render.isConchApp) {
var transform = Laya.ILaya.Utils.getTransformRelativeToWindow(this, 0, 0);
this.videoElement.style.top = transform.y;
}
}
get y() {
return super.y;
}
get playbackRate() {
return this.videoElement.playbackRate;
}
set playbackRate(value) {
this.videoElement.playbackRate = value;
}
get muted() {
return this.videoElement.muted;
}
set muted(value) {
this.videoElement.muted = value;
}
get paused() {
return this.videoElement.paused;
}
get preload() {
return this.videoElement.preload;
}
set preload(value) {
this.videoElement.preload = value;
}
get seekable() {
return this.videoElement.seekable;
}
get seeking() {
return this.videoElement.seeking;
}
size(width, height) {
super.size(width, height);
if (Laya.ILaya.Render.isConchApp) {
var transform = Laya.ILaya.Utils.getTransformRelativeToWindow(this, 0, 0);
this.videoElement.width = width * transform.scaleX;
}
else {
this.videoElement.width = width / Laya.ILaya.Browser.pixelRatio;
this.videoElement.height = height / Laya.Browser.pixelRatio;
}
if (this.paused)
this.renderCanvas();
return this;
}
set width(value) {
if (Laya.ILaya.Render.isConchApp) {
var transform = Laya.ILaya.Utils.getTransformRelativeToWindow(this, 0, 0);
this.videoElement.width = value * transform.scaleX;
}
else {
this.videoElement.width = this.width / Laya.ILaya.Browser.pixelRatio;
}
super.width = value;
if (this.paused)
this.renderCanvas();
}
get width() {
return super.width;
}
set height(value) {
if (Laya.ILaya.Render.isConchApp) {
var transform = Laya.ILaya.Utils.getTransformRelativeToWindow(this, 0, 0);
this.videoElement.height = value * transform.scaleY;
}
else {
this.videoElement.height = this.height / Laya.ILaya.Browser.pixelRatio;
}
super.height = value;
}
get height() {
return super.height;
}
destroy(detroyChildren = true) {
super.destroy(detroyChildren);
this.videoElement.removeEventListener("abort", Video.onAbort);
this.videoElement.removeEventListener("canplay", Video.onCanplay);
this.videoElement.removeEventListener("canplaythrough", Video.onCanplaythrough);
this.videoElement.removeEventListener("durationchange", Video.onDurationchange);
this.videoElement.removeEventListener("emptied", Video.onEmptied);
this.videoElement.removeEventListener("error", Video.onError);
this.videoElement.removeEventListener("loadeddata", Video.onLoadeddata);
this.videoElement.removeEventListener("loadedmetadata", Video.onLoadedmetadata);
this.videoElement.removeEventListener("loadstart", Video.onLoadstart);
this.videoElement.removeEventListener("pause", Video.onPause);
this.videoElement.removeEventListener("play", Video.onPlay);
this.videoElement.removeEventListener("playing", Video.onPlaying);
this.videoElement.removeEventListener("progress", Video.onProgress);
this.videoElement.removeEventListener("ratechange", Video.onRatechange);
this.videoElement.removeEventListener("seeked", Video.onSeeked);
this.videoElement.removeEventListener("seeking", Video.onSeeking);
this.videoElement.removeEventListener("stalled", Video.onStalled);
this.videoElement.removeEventListener("suspend", Video.onSuspend);
this.videoElement.removeEventListener("timeupdate", Video.onTimeupdate);
this.videoElement.removeEventListener("volumechange", Video.onVolumechange);
this.videoElement.removeEventListener("waiting", Video.onWaiting);
this.videoElement.removeEventListener("ended", this.onPlayComplete);
this.pause();
this.videoElement.layaTarget = null;
this.videoElement = null;
this.htmlVideo.destroy();
}
syncVideoPosition() {
var stage = Laya.ILaya.stage;
var rec;
rec = Laya.ILaya.Utils.getGlobalPosAndScale(this);
var a = stage._canvasTransform.a, d = stage._canvasTransform.d;
var x = rec.x * stage.clientScaleX * a + stage.offset.x;
var y = rec.y * stage.clientScaleY * d + stage.offset.y;
this.videoElement.style.left = x + 'px';
this.videoElement.style.top = y + 'px';
this.videoElement.width = this.width / Laya.ILaya.Browser.pixelRatio;
this.videoElement.height = this.height / Laya.ILaya.Browser.pixelRatio;
}
}
Video.MP4 = 1;
Video.OGG = 2;
Video.CAMERA = 4;
Video.WEBM = 8;
Video.SUPPORT_PROBABLY = "probably";
Video.SUPPORT_MAYBY = "maybe";
Video.SUPPORT_NO = "";
class Gyroscope extends Laya.EventDispatcher {
constructor(singleton) {
super();
this.onDeviceOrientationChange = this.onDeviceOrientationChange.bind(this);
}
static get instance() {
Gyroscope._instance = Gyroscope._instance || new Gyroscope(0);
return Gyroscope._instance;
}
on(type, caller, listener, args = null) {
super.on(type, caller, listener, args);
Laya.ILaya.Browser.window.addEventListener('deviceorientation', this.onDeviceOrientationChange);
return this;
}
off(type, caller, listener, onceOnly = false) {
if (!this.hasListener(type))
Laya.ILaya.Browser.window.removeEventListener('deviceorientation', this.onDeviceOrientationChange);
return super.off(type, caller, listener, onceOnly);
}
onDeviceOrientationChange(e) {
Gyroscope.info.alpha = e.alpha;
Gyroscope.info.beta = e.beta;
Gyroscope.info.gamma = e.gamma;
if (e.webkitCompassHeading) {
Gyroscope.info.alpha = e.webkitCompassHeading * -1;
Gyroscope.info.compassAccuracy = e.webkitCompassAccuracy;
}
this.event(Laya.Event.CHANGE, [e.absolute, Gyroscope.info]);
}
}
Gyroscope.info = new RotationInfo();
exports.AccelerationInfo = AccelerationInfo;
exports.Accelerator = Accelerator;
exports.Geolocation = Geolocation;
exports.GeolocationInfo = GeolocationInfo;
exports.Gyroscope = Gyroscope;
exports.HtmlVideo = HtmlVideo;
exports.Media = Media;
exports.RotationInfo = RotationInfo;
exports.Shake = Shake;
exports.Video = Video;
exports.WebGLVideo = WebGLVideo;
}(window.Laya = window.Laya || {}, Laya));

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,635 @@
(function (exports, Laya) {
'use strict';
class ParticleSetting {
constructor() {
this.textureName = null;
this.textureCount = 1;
this.maxPartices = 100;
this.duration = 1;
this.ageAddScale = 0;
this.emitterVelocitySensitivity = 1;
this.minStartSize = 100;
this.maxStartSize = 100;
this.minEndSize = 100;
this.maxEndSize = 100;
this.minHorizontalVelocity = 0;
this.maxHorizontalVelocity = 0;
this.minVerticalVelocity = 0;
this.maxVerticalVelocity = 0;
this.endVelocity = 1;
this.gravity = new Float32Array([0, 0, 0]);
this.minRotateSpeed = 0;
this.maxRotateSpeed = 0;
this.minStartRadius = 0;
this.maxStartRadius = 0;
this.minEndRadius = 0;
this.maxEndRadius = 0;
this.minHorizontalStartRadian = 0;
this.maxHorizontalStartRadian = 0;
this.minVerticalStartRadian = 0;
this.maxVerticalStartRadian = 0;
this.useEndRadian = true;
this.minHorizontalEndRadian = 0;
this.maxHorizontalEndRadian = 0;
this.minVerticalEndRadian = 0;
this.maxVerticalEndRadian = 0;
this.minStartColor = new Float32Array([1, 1, 1, 1]);
this.maxStartColor = new Float32Array([1, 1, 1, 1]);
this.minEndColor = new Float32Array([1, 1, 1, 1]);
this.maxEndColor = new Float32Array([1, 1, 1, 1]);
this.colorComponentInter = false;
this.disableColor = false;
this.blendState = 0;
this.emitterType = "null";
this.emissionRate = 0;
this.pointEmitterPosition = new Float32Array([0, 0, 0]);
this.pointEmitterPositionVariance = new Float32Array([0, 0, 0]);
this.pointEmitterVelocity = new Float32Array([0, 0, 0]);
this.pointEmitterVelocityAddVariance = new Float32Array([0, 0, 0]);
this.boxEmitterCenterPosition = new Float32Array([0, 0, 0]);
this.boxEmitterSize = new Float32Array([0, 0, 0]);
this.boxEmitterVelocity = new Float32Array([0, 0, 0]);
this.boxEmitterVelocityAddVariance = new Float32Array([0, 0, 0]);
this.sphereEmitterCenterPosition = new Float32Array([0, 0, 0]);
this.sphereEmitterRadius = 1;
this.sphereEmitterVelocity = 0;
this.sphereEmitterVelocityAddVariance = 0;
this.ringEmitterCenterPosition = new Float32Array([0, 0, 0]);
this.ringEmitterRadius = 30;
this.ringEmitterVelocity = 0;
this.ringEmitterVelocityAddVariance = 0;
this.ringEmitterUp = 2;
this.positionVariance = new Float32Array([0, 0, 0]);
}
static checkSetting(setting) {
var key;
for (key in ParticleSetting._defaultSetting) {
if (!(key in setting)) {
setting[key] = ParticleSetting._defaultSetting[key];
}
}
setting.endVelocity = +setting.endVelocity;
setting.gravity[0] = +setting.gravity[0];
setting.gravity[1] = +setting.gravity[1];
setting.gravity[2] = +setting.gravity[2];
}
}
ParticleSetting._defaultSetting = new ParticleSetting();
class ParticleTemplateBase {
constructor() {
}
addParticleArray(position, velocity) {
}
}
class ParticleData {
constructor() {
}
static Create(settings, position, velocity, time) {
var particleData = new ParticleData();
particleData.position = position;
Laya.MathUtil.scaleVector3(velocity, settings.emitterVelocitySensitivity, ParticleData._tempVelocity);
var horizontalVelocity = Laya.MathUtil.lerp(settings.minHorizontalVelocity, settings.maxHorizontalVelocity, Math.random());
var horizontalAngle = Math.random() * Math.PI * 2;
ParticleData._tempVelocity[0] += horizontalVelocity * Math.cos(horizontalAngle);
ParticleData._tempVelocity[2] += horizontalVelocity * Math.sin(horizontalAngle);
ParticleData._tempVelocity[1] += Laya.MathUtil.lerp(settings.minVerticalVelocity, settings.maxVerticalVelocity, Math.random());
particleData.velocity = ParticleData._tempVelocity;
particleData.startColor = ParticleData._tempStartColor;
particleData.endColor = ParticleData._tempEndColor;
var i;
if (settings.disableColor) {
for (i = 0; i < 3; i++) {
particleData.startColor[i] = 1;
particleData.endColor[i] = 1;
}
particleData.startColor[i] = Laya.MathUtil.lerp(settings.minStartColor[i], settings.maxStartColor[i], Math.random());
particleData.endColor[i] = Laya.MathUtil.lerp(settings.minEndColor[i], settings.maxEndColor[i], Math.random());
}
else {
if (settings.colorComponentInter) {
for (i = 0; i < 4; i++) {
particleData.startColor[i] = Laya.MathUtil.lerp(settings.minStartColor[i], settings.maxStartColor[i], Math.random());
particleData.endColor[i] = Laya.MathUtil.lerp(settings.minEndColor[i], settings.maxEndColor[i], Math.random());
}
}
else {
Laya.MathUtil.lerpVector4(settings.minStartColor, settings.maxStartColor, Math.random(), particleData.startColor);
Laya.MathUtil.lerpVector4(settings.minEndColor, settings.maxEndColor, Math.random(), particleData.endColor);
}
}
particleData.sizeRotation = ParticleData._tempSizeRotation;
var sizeRandom = Math.random();
particleData.sizeRotation[0] = Laya.MathUtil.lerp(settings.minStartSize, settings.maxStartSize, sizeRandom);
particleData.sizeRotation[1] = Laya.MathUtil.lerp(settings.minEndSize, settings.maxEndSize, sizeRandom);
particleData.sizeRotation[2] = Laya.MathUtil.lerp(settings.minRotateSpeed, settings.maxRotateSpeed, Math.random());
particleData.radius = ParticleData._tempRadius;
var radiusRandom = Math.random();
particleData.radius[0] = Laya.MathUtil.lerp(settings.minStartRadius, settings.maxStartRadius, radiusRandom);
particleData.radius[1] = Laya.MathUtil.lerp(settings.minEndRadius, settings.maxEndRadius, radiusRandom);
particleData.radian = ParticleData._tempRadian;
particleData.radian[0] = Laya.MathUtil.lerp(settings.minHorizontalStartRadian, settings.maxHorizontalStartRadian, Math.random());
particleData.radian[1] = Laya.MathUtil.lerp(settings.minVerticalStartRadian, settings.maxVerticalStartRadian, Math.random());
var useEndRadian = settings.useEndRadian;
particleData.radian[2] = useEndRadian ? Laya.MathUtil.lerp(settings.minHorizontalEndRadian, settings.maxHorizontalEndRadian, Math.random()) : particleData.radian[0];
particleData.radian[3] = useEndRadian ? Laya.MathUtil.lerp(settings.minVerticalEndRadian, settings.maxVerticalEndRadian, Math.random()) : particleData.radian[1];
particleData.durationAddScale = settings.ageAddScale * Math.random();
particleData.time = time;
return particleData;
}
}
ParticleData._tempVelocity = new Float32Array(3);
ParticleData._tempStartColor = new Float32Array(4);
ParticleData._tempEndColor = new Float32Array(4);
ParticleData._tempSizeRotation = new Float32Array(3);
ParticleData._tempRadius = new Float32Array(2);
ParticleData._tempRadian = new Float32Array(4);
class ParticleTemplateWebGL extends ParticleTemplateBase {
constructor(parSetting) {
super();
this._floatCountPerVertex = 29;
this._firstActiveElement = 0;
this._firstNewElement = 0;
this._firstFreeElement = 0;
this._firstRetiredElement = 0;
this._currentTime = 0;
this.settings = parSetting;
}
reUse(context, pos) {
return 0;
}
initialize() {
var floatStride = 0;
this._vertices = this._mesh._vb.getFloat32Array();
floatStride = this._mesh._stride / 4;
var bufi = 0;
var bufStart = 0;
for (var i = 0; i < this.settings.maxPartices; i++) {
var random = Math.random();
var cornerYSegement = this.settings.textureCount ? 1.0 / this.settings.textureCount : 1.0;
var cornerY;
for (cornerY = 0; cornerY < this.settings.textureCount; cornerY += cornerYSegement) {
if (random < cornerY + cornerYSegement)
break;
}
this._vertices[bufi++] = -1;
this._vertices[bufi++] = -1;
this._vertices[bufi++] = 0;
this._vertices[bufi++] = cornerY;
bufi = (bufStart += floatStride);
this._vertices[bufi++] = 1;
this._vertices[bufi++] = -1;
this._vertices[bufi++] = 1;
this._vertices[bufi++] = cornerY;
bufi = bufStart += floatStride;
this._vertices[bufi++] = 1;
this._vertices[bufi++] = 1;
this._vertices[bufi++] = 1;
this._vertices[bufi++] = cornerY + cornerYSegement;
bufi = bufStart += floatStride;
this._vertices[bufi++] = -1;
this._vertices[bufi++] = 1;
this._vertices[bufi++] = 0;
this._vertices[bufi++] = cornerY + cornerYSegement;
bufi = bufStart += floatStride;
}
}
update(elapsedTime) {
this._currentTime += elapsedTime / 1000;
this.retireActiveParticles();
this.freeRetiredParticles();
if (this._firstActiveElement == this._firstFreeElement)
this._currentTime = 0;
if (this._firstRetiredElement == this._firstActiveElement)
this._drawCounter = 0;
}
retireActiveParticles() {
const epsilon = 0.0001;
var particleDuration = this.settings.duration;
while (this._firstActiveElement != this._firstNewElement) {
var offset = this._firstActiveElement * this._floatCountPerVertex * 4;
var index = offset + 28;
var particleAge = this._currentTime - this._vertices[index];
particleAge *= (1.0 + this._vertices[offset + 27]);
if (particleAge + epsilon < particleDuration)
break;
this._vertices[index] = this._drawCounter;
this._firstActiveElement++;
if (this._firstActiveElement >= this.settings.maxPartices)
this._firstActiveElement = 0;
}
}
freeRetiredParticles() {
while (this._firstRetiredElement != this._firstActiveElement) {
var age = this._drawCounter - this._vertices[this._firstRetiredElement * this._floatCountPerVertex * 4 + 28];
if (age < 3)
break;
this._firstRetiredElement++;
if (this._firstRetiredElement >= this.settings.maxPartices)
this._firstRetiredElement = 0;
}
}
addNewParticlesToVertexBuffer() {
}
addParticleArray(position, velocity) {
var nextFreeParticle = this._firstFreeElement + 1;
if (nextFreeParticle >= this.settings.maxPartices)
nextFreeParticle = 0;
if (nextFreeParticle === this._firstRetiredElement)
return;
var particleData = ParticleData.Create(this.settings, position, velocity, this._currentTime);
var startIndex = this._firstFreeElement * this._floatCountPerVertex * 4;
for (var i = 0; i < 4; i++) {
var j, offset;
for (j = 0, offset = 4; j < 3; j++)
this._vertices[startIndex + i * this._floatCountPerVertex + offset + j] = particleData.position[j];
for (j = 0, offset = 7; j < 3; j++)
this._vertices[startIndex + i * this._floatCountPerVertex + offset + j] = particleData.velocity[j];
for (j = 0, offset = 10; j < 4; j++)
this._vertices[startIndex + i * this._floatCountPerVertex + offset + j] = particleData.startColor[j];
for (j = 0, offset = 14; j < 4; j++)
this._vertices[startIndex + i * this._floatCountPerVertex + offset + j] = particleData.endColor[j];
for (j = 0, offset = 18; j < 3; j++)
this._vertices[startIndex + i * this._floatCountPerVertex + offset + j] = particleData.sizeRotation[j];
for (j = 0, offset = 21; j < 2; j++)
this._vertices[startIndex + i * this._floatCountPerVertex + offset + j] = particleData.radius[j];
for (j = 0, offset = 23; j < 4; j++)
this._vertices[startIndex + i * this._floatCountPerVertex + offset + j] = particleData.radian[j];
this._vertices[startIndex + i * this._floatCountPerVertex + 27] = particleData.durationAddScale;
this._vertices[startIndex + i * this._floatCountPerVertex + 28] = particleData.time;
}
this._firstFreeElement = nextFreeParticle;
}
}
var parvs = "attribute vec4 a_CornerTextureCoordinate;\r\nattribute vec3 a_Position;\r\nattribute vec3 a_Velocity;\r\nattribute vec4 a_StartColor;\r\nattribute vec4 a_EndColor;\r\nattribute vec3 a_SizeRotation;\r\nattribute vec2 a_Radius;\r\nattribute vec4 a_Radian;\r\nattribute float a_AgeAddScale;\r\nattribute float a_Time;\r\n\r\nvarying vec4 v_Color;\r\nvarying vec2 v_TextureCoordinate;\r\n\r\nuniform float u_CurrentTime;\r\nuniform float u_Duration;\r\nuniform float u_EndVelocity;\r\nuniform vec3 u_Gravity;\r\n\r\nuniform vec2 size;\r\nuniform mat4 u_mmat;\r\n\r\nvec4 ComputeParticlePosition(in vec3 position, in vec3 velocity,in float age,in float normalizedAge)\r\n{\r\n\r\n float startVelocity = length(velocity);//起始标量速度\r\n float endVelocity = startVelocity * u_EndVelocity;//结束标量速度\r\n\r\n float velocityIntegral = startVelocity * normalizedAge +(endVelocity - startVelocity) * normalizedAge *normalizedAge/2.0;//计算当前速度的标量单位空间vt=v0*t+(1/2)*a*(t^2)\r\n \r\n vec3 addPosition = normalize(velocity) * velocityIntegral * u_Duration;//计算受自身速度影响的位置,转换标量到矢量 \r\n addPosition += u_Gravity * age * normalizedAge;//计算受重力影响的位置\r\n \r\n float radius=mix(a_Radius.x, a_Radius.y, normalizedAge); //计算粒子受半径和角度影响(无需计算角度和半径时,可用宏定义优化屏蔽此计算)\r\n float radianHorizontal =mix(a_Radian.x,a_Radian.z,normalizedAge);\r\n float radianVertical =mix(a_Radian.y,a_Radian.w,normalizedAge);\r\n \r\n float r =cos(radianVertical)* radius;\r\n addPosition.y += sin(radianVertical) * radius;\r\n\t\r\n addPosition.x += cos(radianHorizontal) *r;\r\n addPosition.z += sin(radianHorizontal) *r;\r\n \r\n addPosition.y=-addPosition.y;//2D粒子位置更新需要取负2D粒子坐标系Y轴正向朝上\r\n position+=addPosition;\r\n return vec4(position,1.0);\r\n}\r\n\r\nfloat ComputeParticleSize(in float startSize,in float endSize, in float normalizedAge)\r\n{ \r\n float size = mix(startSize, endSize, normalizedAge);\r\n return size;\r\n}\r\n\r\nmat2 ComputeParticleRotation(in float rot,in float age)\r\n{ \r\n float rotation =rot * age;\r\n //计算2x2旋转矩阵.\r\n float c = cos(rotation);\r\n float s = sin(rotation);\r\n return mat2(c, -s, s, c);\r\n}\r\n\r\nvec4 ComputeParticleColor(in vec4 startColor,in vec4 endColor,in float normalizedAge)\r\n{\r\n\tvec4 color=mix(startColor,endColor,normalizedAge);\r\n //硬编码设置,使粒子淡入很快,淡出很慢,6.7的缩放因子把置归一在0到1之间可以谷歌x*(1-x)*(1-x)*6.7的制图表\r\n color.a *= normalizedAge * (1.0-normalizedAge) * (1.0-normalizedAge) * 6.7;\r\n \r\n return color;\r\n}\r\n\r\nvoid main()\r\n{\r\n float age = u_CurrentTime - a_Time;\r\n age *= 1.0 + a_AgeAddScale;\r\n float normalizedAge = clamp(age / u_Duration,0.0,1.0);\r\n gl_Position = ComputeParticlePosition(a_Position, a_Velocity, age, normalizedAge);//计算粒子位置\r\n float pSize = ComputeParticleSize(a_SizeRotation.x,a_SizeRotation.y, normalizedAge);\r\n mat2 rotation = ComputeParticleRotation(a_SizeRotation.z, age);\r\n\t\r\n mat4 mat=u_mmat;\r\n gl_Position=vec4((mat*gl_Position).xy,0.0,1.0);\r\n gl_Position.xy += (rotation*a_CornerTextureCoordinate.xy) * pSize*vec2(mat[0][0],mat[1][1]);\r\n gl_Position=vec4((gl_Position.x/size.x-0.5)*2.0,(0.5-gl_Position.y/size.y)*2.0,0.0,1.0);\r\n \r\n v_Color = ComputeParticleColor(a_StartColor,a_EndColor, normalizedAge);\r\n v_TextureCoordinate =a_CornerTextureCoordinate.zw;\r\n}\r\n\r\n";
var parps = "#if defined(GL_FRAGMENT_PRECISION_HIGH)\r\nprecision highp float;\r\n#else\r\nprecision mediump float;\r\n#endif\r\n\r\nvarying vec4 v_Color;\r\nvarying vec2 v_TextureCoordinate;\r\nuniform sampler2D u_texture;\r\n\r\nvoid main()\r\n{\t\r\n\tgl_FragColor=texture2D(u_texture,v_TextureCoordinate)*v_Color;\r\n\tgl_FragColor.xyz *= v_Color.w;\r\n}";
class ParticleShader extends Laya.Shader {
constructor() {
super(parvs, parps, "ParticleShader", null, ['a_CornerTextureCoordinate', 0, 'a_Position', 1, 'a_Velocity', 2, 'a_StartColor', 3,
'a_EndColor', 4, 'a_SizeRotation', 5, 'a_Radius', 6, 'a_Radian', 7, 'a_AgeAddScale', 8, 'a_Time', 9]);
}
}
ParticleShader.vs = parvs;
ParticleShader.ps = parps;
class ParticleShaderValue extends Laya.Value2D {
constructor() {
super(0, 0);
if (!ParticleShaderValue.pShader) {
ParticleShaderValue.pShader = new ParticleShader();
}
}
upload() {
var size = this.size;
size[0] = Laya.RenderState2D.width;
size[1] = Laya.RenderState2D.height;
this.alpha = this.ALPHA * Laya.RenderState2D.worldAlpha;
ParticleShaderValue.pShader.upload(this);
}
}
ParticleShaderValue.pShader = null;
class ParticleTemplate2D extends ParticleTemplateWebGL {
constructor(parSetting) {
super(parSetting);
this.x = 0;
this.y = 0;
this.sv = new ParticleShaderValue();
this._key = {};
var _this = this;
Laya.ILaya.loader.load(this.settings.textureName, Laya.Handler.create(null, function (texture) {
_this.texture = texture;
}), null, Laya.Loader.IMAGE);
this.sv.u_Duration = this.settings.duration;
this.sv.u_Gravity = this.settings.gravity;
this.sv.u_EndVelocity = this.settings.endVelocity;
this._blendFn = Laya.BlendMode.fns[parSetting.blendState];
this._mesh = Laya.MeshParticle2D.getAMesh(this.settings.maxPartices);
this.initialize();
}
getRenderType() { return -111; }
releaseRender() { }
addParticleArray(position, velocity) {
position[0] += this.x;
position[1] += this.y;
super.addParticleArray(position, velocity);
}
addNewParticlesToVertexBuffer() {
var _vertexBuffer2D = this._mesh._vb;
_vertexBuffer2D.clear();
_vertexBuffer2D.append(this._vertices);
var start;
if (this._firstNewElement < this._firstFreeElement) {
start = this._firstNewElement * 4 * this._floatCountPerVertex * 4;
_vertexBuffer2D.subUpload(start, start, start + (this._firstFreeElement - this._firstNewElement) * 4 * this._floatCountPerVertex * 4);
}
else {
start = this._firstNewElement * 4 * this._floatCountPerVertex * 4;
_vertexBuffer2D.subUpload(start, start, start + (this.settings.maxPartices - this._firstNewElement) * 4 * this._floatCountPerVertex * 4);
if (this._firstFreeElement > 0) {
_vertexBuffer2D.setNeedUpload();
_vertexBuffer2D.subUpload(0, 0, this._firstFreeElement * 4 * this._floatCountPerVertex * 4);
}
}
this._firstNewElement = this._firstFreeElement;
}
renderSubmit() {
if (this.texture && this.texture.getIsReady()) {
this.update(Laya.ILaya.timer._delta);
this.sv.u_CurrentTime = this._currentTime;
if (this._firstNewElement != this._firstFreeElement) {
this.addNewParticlesToVertexBuffer();
}
this.blend();
if (this._firstActiveElement != this._firstFreeElement) {
var gl = Laya.WebGLContext.mainContext;
this._mesh.useMesh(gl);
this.sv.u_texture = this.texture._getSource();
this.sv.upload();
if (this._firstActiveElement < this._firstFreeElement) {
gl.drawElements(gl.TRIANGLES, (this._firstFreeElement - this._firstActiveElement) * 6, gl.UNSIGNED_SHORT, this._firstActiveElement * 6 * 2);
}
else {
Laya.WebGLContext.mainContext.drawElements(gl.TRIANGLES, (this.settings.maxPartices - this._firstActiveElement) * 6, gl.UNSIGNED_SHORT, this._firstActiveElement * 6 * 2);
if (this._firstFreeElement > 0)
gl.drawElements(gl.TRIANGLES, this._firstFreeElement * 6, gl.UNSIGNED_SHORT, 0);
}
Laya.Stat.renderBatches++;
}
this._drawCounter++;
}
return 1;
}
updateParticleForNative() {
if (this.texture && this.texture.getIsReady()) {
this.update(Laya.ILaya.timer._delta);
this.sv.u_CurrentTime = this._currentTime;
if (this._firstNewElement != this._firstFreeElement) {
this._firstNewElement = this._firstFreeElement;
}
}
}
getMesh() {
return this._mesh;
}
getConchMesh() {
return this._conchMesh;
}
getFirstNewElement() {
return this._firstNewElement;
}
getFirstFreeElement() {
return this._firstFreeElement;
}
getFirstActiveElement() {
return this._firstActiveElement;
}
getFirstRetiredElement() {
return this._firstRetiredElement;
}
setFirstFreeElement(_value) {
this._firstFreeElement = _value;
}
setFirstNewElement(_value) {
this._firstNewElement = _value;
}
addDrawCounter() {
this._drawCounter++;
}
blend() {
if (Laya.BlendMode.activeBlendFunction !== this._blendFn) {
var gl = Laya.WebGLContext.mainContext;
gl.enable(gl.BLEND);
this._blendFn(gl);
Laya.BlendMode.activeBlendFunction = this._blendFn;
}
}
dispose() {
this._mesh.releaseMesh();
}
}
ParticleTemplate2D.activeBlendType = -1;
class EmitterBase {
constructor() {
this._frameTime = 0;
this._emissionRate = 60;
this._emissionTime = 0;
this.minEmissionTime = 1 / 60;
}
set particleTemplate(particleTemplate) {
this._particleTemplate = particleTemplate;
}
set emissionRate(_emissionRate) {
if (_emissionRate <= 0)
return;
this._emissionRate = _emissionRate;
(_emissionRate > 0) && (this.minEmissionTime = 1 / _emissionRate);
}
get emissionRate() {
return this._emissionRate;
}
start(duration = Number.MAX_VALUE) {
if (this._emissionRate != 0)
this._emissionTime = duration;
}
stop() {
this._emissionTime = 0;
}
clear() {
this._emissionTime = 0;
}
emit() {
}
advanceTime(passedTime = 1) {
this._emissionTime -= passedTime;
if (this._emissionTime < 0)
return;
this._frameTime += passedTime;
if (this._frameTime < this.minEmissionTime)
return;
while (this._frameTime > this.minEmissionTime) {
this._frameTime -= this.minEmissionTime;
this.emit();
}
}
}
class Emitter2D extends EmitterBase {
constructor(_template) {
super();
this.template = _template;
}
set template(template) {
this._particleTemplate = template;
if (!template) {
this._emitFun = null;
this.setting = null;
this._posRange = null;
}
this.setting = template.settings;
this._posRange = this.setting.positionVariance;
if (this._particleTemplate instanceof ParticleTemplate2D) {
this._emitFun = this.webGLEmit;
}
}
get template() {
return this._particleTemplate;
}
emit() {
super.emit();
if (this._emitFun != null)
this._emitFun();
}
getRandom(value) {
return (Math.random() * 2 - 1) * value;
}
webGLEmit() {
var pos = new Float32Array(3);
pos[0] = this.getRandom(this._posRange[0]);
pos[1] = this.getRandom(this._posRange[1]);
pos[2] = this.getRandom(this._posRange[2]);
var v = new Float32Array(3);
v[0] = 0;
v[1] = 0;
v[2] = 0;
this._particleTemplate.addParticleArray(pos, v);
}
canvasEmit() {
var pos = new Float32Array(3);
pos[0] = this.getRandom(this._posRange[0]);
pos[1] = this.getRandom(this._posRange[1]);
pos[2] = this.getRandom(this._posRange[2]);
var v = new Float32Array(3);
v[0] = 0;
v[1] = 0;
v[2] = 0;
this._particleTemplate.addParticleArray(pos, v);
}
}
class Particle2D extends Laya.Sprite {
constructor(setting) {
super();
this._matrix4 = new Float32Array([1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]);
this.autoPlay = true;
this.customRenderEnable = true;
if (setting)
this.setParticleSetting(setting);
}
set url(url) {
this.load(url);
}
load(url) {
Laya.ILaya.loader.load(url, Laya.Handler.create(this, this.setParticleSetting), null, Laya.ILaya.Loader.JSON);
}
setParticleSetting(setting) {
if (!setting)
return this.stop();
ParticleSetting.checkSetting(setting);
this.customRenderEnable = true;
this._particleTemplate = new ParticleTemplate2D(setting);
this.graphics._saveToCmd(null, Laya.DrawParticleCmd.create(this._particleTemplate));
if (!this._emitter) {
this._emitter = new Emitter2D(this._particleTemplate);
}
else {
this._emitter.template = this._particleTemplate;
}
if (this.autoPlay) {
this.emitter.start();
this.play();
}
}
get emitter() {
return this._emitter;
}
play() {
Laya.ILaya.timer.frameLoop(1, this, this._loop);
}
stop() {
Laya.ILaya.timer.clear(this, this._loop);
}
_loop() {
this.advanceTime(1 / 60);
}
advanceTime(passedTime = 1) {
if (this._canvasTemplate) {
this._canvasTemplate.advanceTime(passedTime);
}
if (this._emitter) {
this._emitter.advanceTime(passedTime);
}
}
customRender(context, x, y) {
this._matrix4[0] = context._curMat.a;
this._matrix4[1] = context._curMat.b;
this._matrix4[4] = context._curMat.c;
this._matrix4[5] = context._curMat.d;
this._matrix4[12] = context._curMat.tx;
this._matrix4[13] = context._curMat.ty;
var sv = this._particleTemplate.sv;
sv.u_mmat = this._matrix4;
if (this._canvasTemplate) {
this._canvasTemplate.render(context, x, y);
}
}
destroy(destroyChild = true) {
if (this._particleTemplate instanceof ParticleTemplate2D)
this._particleTemplate.dispose();
super.destroy(destroyChild);
}
}
Laya.ClassUtils.regClass("laya.particle.Particle2D", Particle2D);
Laya.ClassUtils.regClass("Laya.Particle2D", Particle2D);
Laya.ILaya.regClass(Particle2D);
class ParticleEmitter {
constructor(templet, particlesPerSecond, initialPosition) {
this._timeLeftOver = 0;
this._tempVelocity = new Float32Array([0, 0, 0]);
this._tempPosition = new Float32Array([0, 0, 0]);
this._templet = templet;
this._timeBetweenParticles = 1.0 / particlesPerSecond;
this._previousPosition = initialPosition;
}
update(elapsedTime, newPosition) {
elapsedTime = elapsedTime / 1000;
if (elapsedTime > 0) {
Laya.MathUtil.subtractVector3(newPosition, this._previousPosition, this._tempVelocity);
Laya.MathUtil.scaleVector3(this._tempVelocity, 1 / elapsedTime, this._tempVelocity);
var timeToSpend = this._timeLeftOver + elapsedTime;
var currentTime = -this._timeLeftOver;
while (timeToSpend > this._timeBetweenParticles) {
currentTime += this._timeBetweenParticles;
timeToSpend -= this._timeBetweenParticles;
Laya.MathUtil.lerpVector3(this._previousPosition, newPosition, currentTime / elapsedTime, this._tempPosition);
this._templet.addParticleArray(this._tempPosition, this._tempVelocity);
}
this._timeLeftOver = timeToSpend;
}
this._previousPosition[0] = newPosition[0];
this._previousPosition[1] = newPosition[1];
this._previousPosition[2] = newPosition[2];
}
}
exports.Emitter2D = Emitter2D;
exports.EmitterBase = EmitterBase;
exports.Particle2D = Particle2D;
exports.ParticleData = ParticleData;
exports.ParticleEmitter = ParticleEmitter;
exports.ParticleSetting = ParticleSetting;
exports.ParticleShader = ParticleShader;
exports.ParticleShaderValue = ParticleShaderValue;
exports.ParticleTemplate2D = ParticleTemplate2D;
exports.ParticleTemplateBase = ParticleTemplateBase;
exports.ParticleTemplateWebGL = ParticleTemplateWebGL;
}(window.Laya = window.Laya || {}, Laya));

View File

@ -0,0 +1,790 @@
(function (exports, Laya) {
'use strict';
const defaultOptions = {
autoRetryConnnect: true,
retryConnnectCount: 0,
retryConnnectDelay: 10000
};
let WebSocketCls = window.WebSocket;
class SocketManager {
constructor(host, port, name, type, options) {
this.clientId = 0;
this.socket = null;
this.isSupport = false;
this.status = 0;
this.retryConnnectCount = 0;
this.onClose = (ev) => {
let { onClose, autoRetryConnnect, retryConnnectCount } = this.options;
retryConnnectCount = retryConnnectCount || 0;
if (onClose) {
onClose(ev);
}
if (this.status === 0) {
if (autoRetryConnnect &&
(retryConnnectCount == 0 || this.retryConnnectCount < retryConnnectCount)) {
this.delayRetryConnnect();
}
}
};
this._delayRetryConnnectTimer = 0;
this._delayRetryConnnect = () => {
clearTimeout(this._delayRetryConnnectTimer);
this.retryConnnectCount++;
this.reConnect();
};
this.onMessage = (ev) => {
const { onMessage } = this.options;
if (onMessage) {
onMessage(ev);
}
};
this.onError = (ev) => {
const { onError } = this.options;
if (onError) {
onError(ev);
}
};
this.onOpen = (ev) => {
const { onOpen } = this.options;
if (onOpen) {
onOpen(ev);
}
this.retryConnnectCount = 0;
clearTimeout(this._delayRetryConnnectTimer);
};
this.url = 'ws://' + host + ":" + port + '?type=' + type + '&name=' + name;
if (options) {
Object.assign(options, defaultOptions);
this.options = options;
}
else {
this.options = defaultOptions;
}
WebSocketCls = window.WebSocket;
this.isSupport = (typeof WebSocketCls != 'undefined');
if (this.isSupport) {
this.reConnect();
}
else {
console.log('not support websocket');
}
}
closeConnect() {
this.retryConnnectCount = 0;
if (this.socket) {
let socket = this.socket;
socket.onclose = null;
socket.onmessage = null;
socket.onerror = null;
socket.onopen = null;
socket.close();
this.socket = null;
}
this.status = 0;
}
delayRetryConnnect() {
clearTimeout(this._delayRetryConnnectTimer);
if (ProfileHelper.enable) {
this._delayRetryConnnectTimer = setTimeout(this._delayRetryConnnect, this.options.retryConnnectDelay);
}
}
reConnect() {
let socket = new WebSocketCls(this.url);
this.socket = socket;
socket.onclose = this.onClose;
socket.onmessage = this.onMessage;
socket.onerror = this.onError;
socket.onopen = this.onOpen;
}
dispose() {
this.closeConnect();
}
send(msg) {
if (this.socket && this.socket.readyState === 1) {
this.socket.send(msg);
return true;
}
return false;
}
}
const getParameterByName = function (name, url) {
name = name.replace(/[\[\]]/g, '\\$&');
var regex = new RegExp('[?&]' + name + '(=([^&#]*)|&|#|$)'), results = regex.exec(url);
if (!results)
return null;
if (!results[2])
return '';
return decodeURIComponent(results[2].replace(/\+/g, ' '));
};
const idIsInList = (id, list) => {
for (let i = 0; i < list.length; i++) {
let info = list[i];
if (info.id == id) {
return true;
}
}
return false;
};
class ProfileHelper {
constructor() {
this.socketManager = null;
this.selectPlayerId = 0;
this.active = 0;
this.selectPlayerStatus = 0;
this.sendMsg = (type, data, toId = 0) => {
this.socketManager.send(JSON.stringify({
type: type,
data: data,
toId: toId
}));
};
this.sendInternalMsg = (type, data, toId = 0) => {
this.socketManager.send(JSON.stringify({
type: type,
data: data,
toId: toId
}));
};
this.frameDataList = [];
this.sendFramData = (data) => {
if (!this.active) {
return;
}
this.frameDataList.push(data);
if (this.frameDataList.length >= 30) {
this.sendFramDataList(this.frameDataList);
this.frameDataList.length = 0;
}
};
this.sendConfigData = (data = null) => {
let configData = this.performanceDataTool.getPathInfo();
this.sendInternalMsg('getPerformanceConf_back', configData);
};
this.sendFramDataList = (dataList) => {
let list = dataList.map((data) => {
return {
type: "frameData",
data: data
};
});
this.sendInternalMsg("msgList", list);
};
}
static set enable(value) {
if (ProfileHelper._enable === value) {
return;
}
ProfileHelper._enable = value;
if (value) {
const initOption = ProfileHelper.initOption;
if (!initOption) {
throw new Error('没有执行初始化init');
}
const { type, performanceDataTool, onOpen, onMessage, retryConnectCount, retryConnnectDelay } = initOption;
ProfileHelper.init(type, performanceDataTool, onOpen, onMessage, retryConnectCount, retryConnnectDelay);
}
else {
ProfileHelper.dispose();
}
}
static get enable() {
return ProfileHelper._enable;
}
init(type, performanceDataTool, onOpen, onMessage, retryConnectCount, retryConnnectDelay) {
this.frameDataList = [];
if (type === 'player' && !performanceDataTool) {
throw new Error("type为player时performanceDataTool不为空");
}
var host = '';
var url = '';
var href = '';
if (window && window.location && window.location.href) {
href = window.location.href;
}
var name = getParameterByName('profileName', href) || '';
var port = getParameterByName('profilePort', href) || '1050';
if (ProfileHelper.Host || getParameterByName('profileHost', href)) {
host = ProfileHelper.Host || getParameterByName('profileHost', href);
}
else {
if (href.startsWith('http')) {
var index1 = href.indexOf('//');
var index2 = href.indexOf('/', index1 + 3);
if (index2 === -1) {
index2 = href.length;
}
url = href.substring(index1 + 2, index2);
index2 = url.indexOf(':');
if (index2 >= 0) {
url = url.substring(0, index2);
}
host = url;
}
else {
host = 'localhost';
}
}
this.performanceDataTool = performanceDataTool;
this.heartIntervalHandler = setInterval(() => {
this.sendInternalMsg('heart', {});
}, 1000 * 10);
this.socketManager = new SocketManager(host, port, name, type, {
retryConnectCount: retryConnectCount || defaultOptions.retryConnnectCount,
retryConnnectDelay: retryConnnectDelay || defaultOptions.retryConnnectDelay,
onMessage: (ev) => {
if (!this.socketManager) {
return;
}
if (typeof ev.data == 'string') {
let data = JSON.parse(ev.data);
let msgList = [data];
if (data.type === 'msgList') {
msgList = data.data;
}
msgList.forEach((eventData) => {
switch (eventData.type) {
case 'onSelectMe':
this.sendInternalMsg('onSelectMe_back', eventData.data);
break;
case 'getPerformanceConf':
this.sendConfigData();
break;
case 'selectPlayer_back':
this.selectPlayerId = eventData.data.selectPlayer;
this.selectPlayerStatus = 0;
break;
case 'onReady':
this.socketManager.clientId = eventData.data.id;
this.sendInternalMsg('start', {});
break;
case 'active':
this.active = eventData.data.active;
break;
case 'playerList':
if (this.selectPlayerId) {
if (!idIsInList(this.selectPlayerId, eventData.data)) {
this.selectPlayerId = 0;
this.selectPlayerStatus = 0;
}
}
if (this.selectPlayerId && eventData.data.length > 0 && this.selectPlayerStatus == 0) {
let playerId = eventData.data[0].id;
this.selectPlayerStatus = 1;
this.sendMsg('selectPlayer', { id: playerId });
}
break;
}
});
if (onMessage) {
msgList.forEach((msgData) => {
onMessage(msgData);
});
}
}
},
onOpen: (ev) => {
if (onOpen) {
onOpen(ev);
}
},
onError: (ev) => {
},
onClose: (ev) => {
}
});
}
dispose() {
clearInterval(this.heartIntervalHandler);
if (this.socketManager) {
this.socketManager.dispose();
this.socketManager = null;
}
this.performanceDataTool = null;
}
static init(type, performanceDataTool, onOpen, onMessage, retryConnectCount, retryConnnectDelay) {
if (ProfileHelper.instance) {
ProfileHelper.instance.dispose();
}
ProfileHelper.initOption = {
type,
performanceDataTool,
onOpen,
onMessage,
retryConnectCount,
retryConnnectDelay
};
if (!ProfileHelper._enable) {
return;
}
ProfileHelper.instance = new ProfileHelper();
ProfileHelper.instance.init(type, performanceDataTool, onOpen, onMessage, retryConnectCount, retryConnnectDelay);
}
}
ProfileHelper.sendFramData = (data) => {
if (!ProfileHelper._enable) {
return;
}
if (ProfileHelper.instance) {
ProfileHelper.instance.sendFramData(data);
}
};
ProfileHelper.sendConfigData = (data) => {
if (!ProfileHelper._enable) {
return;
}
if (ProfileHelper.instance) {
ProfileHelper.instance.sendConfigData(data);
}
};
ProfileHelper.dispose = () => {
if (ProfileHelper.instance) {
ProfileHelper.instance.dispose();
}
ProfileHelper.instance = null;
};
class PerformanceDataTool {
constructor() {
this._enable = false;
this._AllPathMap = {};
this._pathColor = {};
this._pathCount = 0;
this._runtimeShowPathIndex = -1;
this._nodeList = [];
this.samplerFramStep = 6;
this._memoryDataMap = {};
this.pointArray = [];
this.fpsArray = [];
}
static InitLayaPerformanceInfo() {
PerformanceDataTool.instance.InitLayaPerformanceInfo();
}
InitLayaPerformanceInfo() {
this.setPathDataColor(PerformanceDataTool.PERFORMANCE_LAYA_2D, [255, 128, 128, 255]);
this.setPathDataColor(PerformanceDataTool.PERFORMANCE_LAYA_3D, [255, 255, 128, 255]);
this.setPathDataColor(PerformanceDataTool.PERFORMANCE_LAYA_3D_RENDER, [128, 255, 128, 255]);
this.setPathDataColor(PerformanceDataTool.PERFORMANCE_LAYA_3D_UPDATESCRIPT, [128, 255, 255, 255]);
this.setPathDataColor(PerformanceDataTool.PERFORMANCE_LAYA_3D_PHYSICS, [0, 128, 255, 255]);
this.setPathDataColor(PerformanceDataTool.PERFORMANCE_LAYA_3D_PHYSICS_SIMULATE, [255, 0, 0, 255]);
this.setPathDataColor(PerformanceDataTool.PERFORMANCE_LAYA_3D_PHYSICS_CHARACTORCOLLISION, [255, 128, 0, 255]);
this.setPathDataColor(PerformanceDataTool.PERFORMANCE_LAYA_3D_PHYSICS_EVENTSCRIPTS, [128, 0, 0, 255]);
this.setPathDataColor(PerformanceDataTool.PERFORMANCE_LAYA_3D_RENDER, [64, 128, 128, 255]);
this.setPathDataColor(PerformanceDataTool.PERFORMANCE_LAYA_3D_RENDER_SHADOWMAP, [192, 192, 192, 255]);
this.setPathDataColor(PerformanceDataTool.PERFORMANCE_LAYA_3D_RENDER_CLUSTER, [128, 64, 64, 255]);
this.setPathDataColor(PerformanceDataTool.PERFORMANCE_LAYA_3D_RENDER_CULLING, [0, 64, 128, 255]);
this.setPathDataColor(PerformanceDataTool.PERFORMANCE_LAYA_3D_RENDER_RENDERDEPTHMDOE, [128, 0, 64, 255]);
this.setPathDataColor(PerformanceDataTool.PERFORMANCE_LAYA_3D_RENDER_RENDEROPAQUE, [128, 0, 255, 255]);
this.setPathDataColor(PerformanceDataTool.PERFORMANCE_LAYA_3D_RENDER_RENDERCOMMANDBUFFER, [128, 128, 64, 255]);
this.setPathDataColor(PerformanceDataTool.PERFORMANCE_LAYA_3D_RENDER_RENDERTRANSPARENT, [128, 0, 255, 255]);
this.setPathDataColor(PerformanceDataTool.PERFORMANCE_LAYA_3D_RENDER_POSTPROCESS, [0, 255, 0, 255]);
}
set enable(value) {
if (value) {
this._startFram = Laya.Stat.loopCount;
this.resetReCordData();
this._sp = new Laya.Sprite();
this._sp.pos(0, 400).zOrder = 99;
Laya.Laya.stage.addChild(this._sp);
}
else {
Laya.Laya.stage.removeChild(this._sp);
}
this._enable = value;
}
get enable() {
return this._enable;
}
get enableDataExport() {
return this._enableDataExport;
}
set enableDataExport(value) {
if (value) {
ProfileHelper.init('player', this);
ProfileHelper.enable = value;
this.samplerFramStep = 1;
}
else {
ProfileHelper.enable = value;
}
this._enableDataExport = value;
}
set runtimeShowPath(path) {
let showPathIndex = this._AllPathMap[path];
for (let i in this.pointArray) {
delete this.pointArray[i];
delete PerformanceDataTool.stepLengthArrayMap[i];
}
if (showPathIndex != null)
this._runtimeShowPathIndex = showPathIndex;
else
this._runtimeShowPathIndex = -1;
}
getNodePathIndex(path) {
var id;
if (this._AllPathMap[path] != null)
id = this._AllPathMap[path];
else {
id = this._pathCount++;
this._AllPathMap[path] = id;
ProfileHelper.sendConfigData(this.getPathInfo());
}
return id;
}
getPathInfo() {
let pathInfo = {};
if (Object.keys(this._pathColor).length == 0) {
this.InitLayaPerformanceInfo();
}
pathInfo["_pathColor"] = this._pathColor;
pathInfo["_AllPathMap"] = this._AllPathMap;
return pathInfo;
}
exportPerformanceFile(fromProfiler = false) {
PerformanceDataTool.InitLayaPerformanceInfo();
if (!fromProfiler) {
this.enable = false;
}
let blockstr = [];
let blockStart = [];
let blocklength = [];
let tempNum = 0;
let blockStartPos;
let tempStartPos;
let tempEndPos;
let dataByte = new Laya.Byte();
dataByte.pos = 0;
dataByte.writeUTFString(PerformanceDataTool.VERSION);
blockstr.push("DataInfo01", "Color", "NodeInfo");
dataByte.writeUint16(blockstr.length);
for (let i = 0; i < blockstr.length; i++) {
dataByte.writeUTFString(blockstr[i]);
}
blockStart.length = blockstr.length;
blocklength.length = blockstr.length;
blockStartPos = dataByte.pos;
for (let i = 0; i < blockstr.length; i++) {
dataByte.writeInt32(0);
dataByte.writeInt32(0);
}
blockStart[0] = dataByte.pos;
dataByte.writeInt32(this._nodeList.length);
dataByte.writeInt32(this.samplerFramStep);
dataByte.writeInt32(this._pathCount);
for (let j in this._AllPathMap) {
dataByte.writeUTFString(j);
}
tempStartPos = dataByte.pos;
dataByte.writeInt32(0);
for (let k in this._memoryDataMap) {
dataByte.writeUTFString(k);
tempNum++;
}
tempEndPos = dataByte.pos;
dataByte.pos = tempStartPos;
dataByte.writeInt32(tempNum);
dataByte.pos = tempEndPos;
blocklength[0] = dataByte.pos - blockStart[0];
blockStart[1] = dataByte.pos;
tempStartPos = dataByte.pos;
tempNum = 0;
dataByte.writeInt32(0);
for (let l in this._pathColor) {
var vec4 = this._pathColor[l];
dataByte.writeUTFString(l);
dataByte.writeUint32(vec4[0]);
dataByte.writeUint32(vec4[1]);
dataByte.writeUint32(vec4[2]);
dataByte.writeUint32(vec4[3]);
tempNum++;
}
tempEndPos = dataByte.pos;
dataByte.pos = tempStartPos;
dataByte.writeInt32(tempNum);
dataByte.pos = tempEndPos;
blocklength[1] = dataByte.pos - blockStart[1];
blockStart[2] = dataByte.pos;
for (let n = 0; n < this._nodeList.length; n++) {
let node = this._nodeList[n];
dataByte.writeInt32(node.nodeNum);
for (var ii = 0; ii < node.nodeNum; ii++) {
dataByte.writeFloat32(node.nodeDelty[ii] ? node.nodeDelty[ii] : 0);
}
}
blocklength[2] = dataByte.pos - blockStart[2];
dataByte.pos = blockStartPos;
for (let v = 0; v < blockstr.length; v++) {
dataByte.writeInt32(blockStart[v]);
dataByte.writeInt32(blocklength[v]);
}
return dataByte;
}
BegainSample(samplePath) {
if (!this.enable)
return;
this.update();
this._runtimeNode.getFunStart(this.getNodePathIndex(samplePath));
}
EndSample(samplePath) {
if (!this.enable)
return 0;
return this._runtimeNode.getFunEnd(this.getNodePathIndex(samplePath));
}
AddMemory(memoryPath, size) {
this._memoryDataMap[memoryPath] = this._memoryDataMap[memoryPath] ? (this._memoryDataMap[memoryPath] + size) : size;
}
setPathDataColor(path, color) {
this._pathColor[path] = color;
}
resetReCordData() {
this._nodeList.forEach(element => {
PerforManceNode.revert(element);
});
this._nodeList = [];
this._runtimeNode = null;
this._AllPathMap = {};
this._memoryDataMap = {};
this._pathColor = {};
this._pathCount = 0;
}
exportFrontNode(ob, pathIndex) {
if (!ob || !ob.nodeDelty || pathIndex == -1) {
return;
}
const width = PerformanceDataTool.DrawWidth;
const height = PerformanceDataTool.DrawHeight;
const stepLength = PerformanceDataTool.StepLength;
const fullStepTime = 33;
const bgColor = "rgba(150, 150, 150, 0.8)";
let array, value, percent;
this._sp.graphics.clear();
this._sp.graphics.drawRect(0, 0, width, height, bgColor);
for (let i = 0, len = ob.nodeDelty.length; i < len; i++) {
if (i != pathIndex && i != this.getNodePathIndex(PerformanceDataTool.PERFORMANCE_DELTYTIME)) {
continue;
}
value = ob.nodeDelty[i];
percent = value / fullStepTime;
if (!this.pointArray[i]) {
this.pointArray[i] = [];
}
array = this.pointArray[i];
if (array.length >= stepLength) {
array.shift();
}
array.push(percent);
let color = i.toString(16);
let fillColor = `#${color}${color}C4${color}${color}`;
if (i == this.getNodePathIndex(PerformanceDataTool.PERFORMANCE_DELTYTIME)) {
fillColor = "#FFFFFF";
}
if (!PerformanceDataTool.stepLengthArrayMap[i]) {
PerformanceDataTool.stepLengthArrayMap[i] = new Array(PerformanceDataTool.StepLength * 2);
}
this.updatelineChart(width, height, stepLength, array, fillColor, 1, PerformanceDataTool.stepLengthArrayMap[i]);
}
this._sp.graphics.drawLine(0, height / 2, width, height / 2, "green", 1);
this._sp.graphics.drawLine(0, height / 4 * 3, width, height / 4 * 3, "red", 1);
}
updatelineChart(width, height, stepLength, array, fillColor, style, drawArray) {
switch (style) {
case 1:
let copy = drawArray;
for (let i = 0, len = array.length; i < len; i++) {
copy[i * 2] = width / stepLength * i;
copy[i * 2 + 1] = Math.max(height - array[i] * height / this.samplerFramStep, 0);
}
this._sp.graphics.drawLines(0, 0, copy, fillColor, 1);
break;
case 2:
let widthStep = width / stepLength;
for (let i = 0, len = array.length; i < len; i++) {
this._sp.graphics.drawRect(width / stepLength * i, height, widthStep, -Math.min(array[i] * height, height), fillColor);
}
}
}
update() {
let currentFrame = Laya.Stat.loopCount;
let nodelenth = ((currentFrame - this._startFram) / this.samplerFramStep) | 0;
if (!nodelenth) {
this._runtimeNode = PerforManceNode.create(this._pathCount);
this._runtimeNode.nodeDelty[this.getNodePathIndex(PerformanceDataTool.PERFORMANCE_STARTTIME)] = performance.now();
return;
}
if (nodelenth != this._nodeList.length) {
for (let i in this._memoryDataMap) {
this._runtimeNode.setMemory(this.getNodePathIndex(i), this._memoryDataMap[i]);
}
if (this._runtimeNode) {
this._runtimeNode.nodeDelty[this.getNodePathIndex(PerformanceDataTool.PERFORMANCE_DELTYTIME)] = performance.now() - this._runtimeNode.nodeDelty[this.getNodePathIndex(PerformanceDataTool.PERFORMANCE_STARTTIME)];
this.exportFrontNode(this._runtimeNode, this._runtimeShowPathIndex);
ProfileHelper.sendFramData(this._runtimeNode);
}
this._runtimeNode = PerforManceNode.create(this._pathCount);
this._runtimeNode.nodeDelty[this.getNodePathIndex(PerformanceDataTool.PERFORMANCE_STARTTIME)] = performance.now();
this._nodeList.push(this._runtimeNode);
}
}
static showMemoryData(memoryPath) {
}
static showFunSampleGroup(groupPath) {
}
showFunSampleFun(samplePath) {
this.runtimeShowPath = samplePath;
}
}
PerformanceDataTool.VERSION = "PERFORMANCEDATA:01";
PerformanceDataTool.instance = new PerformanceDataTool();
PerformanceDataTool.PERFORMANCE_DELTYTIME = "deltyTime";
PerformanceDataTool.PERFORMANCE_STARTTIME = "startTime";
PerformanceDataTool.PERFORMANCE_LAYA = "Laya";
PerformanceDataTool.PERFORMANCE_LAYA_3D = "Laya/3D";
PerformanceDataTool.PERFORMANCE_LAYA_2D = "Laya/2D";
PerformanceDataTool.PERFORMANCE_LAYA_3D_PRERENDER = "Laya/3D/PreRender";
PerformanceDataTool.PERFORMANCE_LAYA_3D_UPDATESCRIPT = "Laya/3D/UpdateScript";
PerformanceDataTool.PERFORMANCE_LAYA_3D_PHYSICS = "Laya/3D/Physics";
PerformanceDataTool.PERFORMANCE_LAYA_3D_PHYSICS_SIMULATE = "Laya/3D/Physics/simulate";
PerformanceDataTool.PERFORMANCE_LAYA_3D_PHYSICS_CHARACTORCOLLISION = "Laya/3D/Physics/updataCharacters&Collisions";
PerformanceDataTool.PERFORMANCE_LAYA_3D_PHYSICS_EVENTSCRIPTS = "Laya/3D/Physics/eventScripts";
PerformanceDataTool.PERFORMANCE_LAYA_3D_RENDER = "Laya/3D/Render";
PerformanceDataTool.PERFORMANCE_LAYA_3D_RENDER_SHADOWMAP = "Laya/3D/Render/ShadowMap";
PerformanceDataTool.PERFORMANCE_LAYA_3D_RENDER_CLUSTER = "Laya/3D/Render/Cluster";
PerformanceDataTool.PERFORMANCE_LAYA_3D_RENDER_CULLING = "Laya/3D/Render/Culling";
PerformanceDataTool.PERFORMANCE_LAYA_3D_RENDER_RENDERDEPTHMDOE = "Laya/3D/Render/RenderDepthMode";
PerformanceDataTool.PERFORMANCE_LAYA_3D_RENDER_RENDEROPAQUE = "Laya/3D/Render/RenderOpaque";
PerformanceDataTool.PERFORMANCE_LAYA_3D_RENDER_RENDERCOMMANDBUFFER = "Laya/3D/Render/RenderCommandBuffer";
PerformanceDataTool.PERFORMANCE_LAYA_3D_RENDER_RENDERTRANSPARENT = "Laya/3D/Render/RenderTransparent";
PerformanceDataTool.PERFORMANCE_LAYA_3D_RENDER_POSTPROCESS = "Laya/3D/Render/PostProcess";
PerformanceDataTool._surpport = false;
PerformanceDataTool.DrawWidth = 250;
PerformanceDataTool.DrawHeight = 250;
PerformanceDataTool.StepLength = 250;
PerformanceDataTool.stepLengthArrayMap = new Array();
class PerforManceNode {
constructor() {
this.inPool = false;
this.nodeNum = 0;
this.nodeStart = [];
this.nodeDelty = [];
this.applyCount = 0;
}
static create(nodeNum) {
let perNode;
perNode = this._pool.length > 0 ? this._pool.pop() : new PerforManceNode();
perNode.resetData(nodeNum);
perNode.inPool = false;
return perNode;
}
static revert(node) {
node.inPool = true;
this._pool.push(node);
node.clearData();
}
clearData() {
this.nodeStart.length = 0;
this.nodeDelty.length = 0;
}
resetData(nodeNum) {
this.nodeNum = nodeNum;
this.nodeStart.length = nodeNum;
this.nodeDelty.length = nodeNum;
}
getFunStart(index) {
this.applyCount++;
this.nodeStart[index] = performance.now();
}
getFunEnd(index) {
if (this.nodeDelty[index])
this.nodeDelty[index] += (this.nodeStart[index] != 0) ? (performance.now() - this.nodeStart[index]) : 0;
else {
this.nodeDelty[index] = (this.nodeStart[index] != 0) ? (performance.now() - this.nodeStart[index]) : 0;
this.nodeNum = this.nodeDelty.length;
}
return this.nodeDelty[index];
}
setMemory(index, value) {
this.nodeDelty[index] = value;
}
getPathData(index) {
return this.nodeDelty[index];
}
}
PerforManceNode._pool = [];
class PerformanceNodeParse {
static parsePerformanceFile(performance, outData) {
performance.pos = 0;
PerformanceNodeParse.performanceData = outData;
PerformanceNodeParse._readData = performance;
PerformanceNodeParse.READ_DATA();
for (let i = 0, n = PerformanceNodeParse._blockStr.length; i < n; i++) {
var blockName = PerformanceNodeParse._blockStr[i];
var fn = PerformanceNodeParse["READ_" + blockName];
if (fn == null)
throw new Error("model file err,no this function:" + blockName);
else {
PerformanceNodeParse._readData.pos = PerformanceNodeParse._blockStart[i];
fn.call(null);
}
}
}
static READ_DATA() {
let data = PerformanceNodeParse._readData;
let version = data.readUTFString();
if (version != "PERFORMANCEDATA:01") {
throw version + "is not standard Version";
}
let blocklenth = PerformanceNodeParse._blockStr.length = data.readUint16();
for (let i = 0; i < blocklenth; i++) {
PerformanceNodeParse._blockStr[i] = data.readUTFString();
}
for (let j = 0; j < blocklenth; j++) {
PerformanceNodeParse._blockStart[j] = data.readInt32();
PerformanceNodeParse._blocklength[j] = data.readInt32();
}
}
static READ_DataInfo01() {
let data = PerformanceNodeParse._readData;
let performanceData = PerformanceNodeParse.performanceData;
PerformanceNodeParse._nodeNums = data.readInt32();
performanceData.samplerFramStep = data.readInt32();
let pathCount = data.readInt32();
for (let i = 0; i < pathCount; i++) {
performanceData.getNodePathIndex(data.readUTFString());
}
let memoryPath = data.readInt32();
for (let j = 0; j < memoryPath; j++) {
performanceData._memoryDataMap[data.readUTFString()] = 1;
}
}
static READ_Color() {
let data = PerformanceNodeParse._readData;
let performanceData = PerformanceNodeParse.performanceData;
let colorlength = data.readInt32();
for (let i = 0; i < colorlength; i++)
performanceData.setPathDataColor(data.readUTFString(), [data.readUint32(), data.readUint32(), data.readUint32(), data.readUint32()]);
}
static READ_NodeInfo() {
let data = PerformanceNodeParse._readData;
let performanceData = PerformanceNodeParse.performanceData;
let perNode;
let length;
for (let i = 0; i < PerformanceNodeParse._nodeNums; i++) {
length = data.readInt32();
perNode = PerforManceNode.create(length);
for (let l = 0, n = length; l < n; l++)
perNode.nodeDelty[l] = data.readFloat32();
performanceData._nodeList[i] = perNode;
}
}
}
PerformanceNodeParse._blockStr = [];
PerformanceNodeParse._blockStart = [];
PerformanceNodeParse._blocklength = [];
PerformanceNodeParse.performanceData = new PerformanceDataTool();
exports.PerforManceNode = PerforManceNode;
exports.PerformanceDataTool = PerformanceDataTool;
exports.PerformanceNodeParse = PerformanceNodeParse;
}(window.Laya = window.Laya || {}, Laya));

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,10 @@
window.Physics3D = function(initialMemory, interactive) {
window.conch.setGetWorldTransformFunction(interactive.getWorldTransform);
window.conch.setSetWorldTransformFunction(interactive.setWorldTransform);
var conchBullet = window.layaConchBullet;
conchBullet.then = (complete) => {
complete();
};
window.Physics3D = conchBullet;
return conchBullet;
};

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,745 @@
(function (exports, Laya) {
'use strict';
class SpineGLTexture extends Laya.Texture {
constructor(tex) {
super(tex);
}
getImage() {
return {
width: this.sourceWidth,
height: this.sourceHeight
};
}
setFilters(minFilter, magFilter) {
}
setWraps(uWrap, vWrap) {
}
}
var Color = spine.Color;
var SkeletonClipping = spine.SkeletonClipping;
var Vector2 = spine.Vector2;
var Utils = spine.Utils;
var RegionAttachment = spine.RegionAttachment;
var MeshAttachment = spine.MeshAttachment;
var ClippingAttachment = spine.ClippingAttachment;
class Renderable {
constructor(vertices, numVertices, numFloats) {
this.vertices = vertices;
this.numVertices = numVertices;
this.numFloats = numFloats;
}
}
class SpineSkeletonRenderer {
constructor(twoColorTint = true) {
this.vertexEffect = null;
this.tempColor = new Color();
this.tempColor2 = new Color();
this.vertexSize = 2 + 2 + 4;
this.twoColorTint = false;
this.renderable = new Renderable(null, 0, 0);
this.clipper = new SkeletonClipping();
this.temp = new Vector2();
this.temp2 = new Vector2();
this.temp3 = new Color();
this.temp4 = new Color();
this.twoColorTint = twoColorTint;
if (twoColorTint)
this.vertexSize += 4;
this.vertices = Utils.newFloatArray(this.vertexSize * 1024);
}
draw(skeleton, slotRangeStart = -1, slotRangeEnd = -1, spineSkeletonIns, textureList) {
let clipper = this.clipper;
let premultipliedAlpha = this.premultipliedAlpha;
let twoColorTint = false;
let tempPos = this.temp;
let tempUv = this.temp2;
let tempLight = this.temp3;
let tempDark = this.temp4;
let renderable = this.renderable;
let uvs = null;
let triangles = null;
let drawOrder = skeleton.drawOrder;
let attachmentColor = null;
let skeletonColor = skeleton.color;
let vertexSize = 8;
let inRange = false;
if (slotRangeStart == -1)
inRange = true;
for (let i = 0, n = drawOrder.length; i < n; i++) {
let clippedVertexSize = clipper.isClipping() ? 2 : vertexSize;
let slot = drawOrder[i];
if (slotRangeStart >= 0 && slotRangeStart == slot.data.index) {
inRange = true;
}
if (!inRange) {
clipper.clipEndWithSlot(slot);
continue;
}
if (slotRangeEnd >= 0 && slotRangeEnd == slot.data.index) {
inRange = false;
}
let attachment = slot.getAttachment();
let name = null;
let texture;
if (attachment instanceof RegionAttachment) {
let region = attachment;
renderable.vertices = this.vertices;
renderable.numVertices = 4;
renderable.numFloats = clippedVertexSize << 2;
region.computeWorldVertices(slot.bone, renderable.vertices, 0, clippedVertexSize);
triangles = SpineSkeletonRenderer.QUAD_TRIANGLES;
uvs = region.uvs;
name = region.region.renderObject.page.name;
texture = textureList[name];
attachmentColor = region.color;
}
else if (attachment instanceof MeshAttachment) {
let mesh = attachment;
renderable.vertices = this.vertices;
renderable.numVertices = (mesh.worldVerticesLength >> 1);
renderable.numFloats = renderable.numVertices * clippedVertexSize;
if (renderable.numFloats > renderable.vertices.length) {
renderable.vertices = this.vertices = Utils.newFloatArray(renderable.numFloats);
}
mesh.computeWorldVertices(slot, 0, mesh.worldVerticesLength, renderable.vertices, 0, clippedVertexSize);
triangles = mesh.triangles;
name = mesh.region.renderObject.page.name;
texture = textureList[name];
uvs = mesh.uvs;
attachmentColor = mesh.color;
}
else if (attachment instanceof ClippingAttachment) {
let clip = (attachment);
clipper.clipStart(slot, clip);
continue;
}
else {
clipper.clipEndWithSlot(slot);
continue;
}
if (texture != null) {
let slotColor = slot.color;
let finalColor = this.tempColor;
finalColor.r = skeletonColor.r * slotColor.r * attachmentColor.r;
finalColor.g = skeletonColor.g * slotColor.g * attachmentColor.g;
finalColor.b = skeletonColor.b * slotColor.b * attachmentColor.b;
finalColor.a = skeletonColor.a * slotColor.a * attachmentColor.a;
if (premultipliedAlpha) {
finalColor.r *= finalColor.a;
finalColor.g *= finalColor.a;
finalColor.b *= finalColor.a;
}
let slotBlendMode = slot.data.blendMode;
if (clipper.isClipping()) {
clipper.clipTriangles(renderable.vertices, renderable.numFloats, triangles, triangles.length, uvs, finalColor, null, twoColorTint);
let clippedVertices = new Float32Array(clipper.clippedVertices);
let clippedTriangles = clipper.clippedTriangles;
let mVertices = [];
let mUVs = [];
let colors = [];
if (this.vertexEffect != null) {
let vertexEffect = this.vertexEffect;
let verts = clippedVertices;
{
for (let v = 0, n = clippedVertices.length; v < n; v += vertexSize) {
tempPos.x = verts[v];
tempPos.y = verts[v + 1];
tempLight.set(verts[v + 2], verts[v + 3], verts[v + 4], verts[v + 5]);
tempUv.x = verts[v + 6];
tempUv.y = verts[v + 7];
tempDark.set(0, 0, 0, 0);
vertexEffect.transform(tempPos, tempUv, tempLight, tempDark);
verts[v] = tempPos.x;
verts[v + 1] = tempPos.y;
verts[v + 2] = tempLight.r;
verts[v + 3] = tempLight.g;
verts[v + 4] = tempLight.b;
verts[v + 5] = tempLight.a;
verts[v + 6] = tempUv.x;
verts[v + 7] = tempUv.y;
mVertices.push(verts[v], -verts[v + 1]);
colors.push(verts[v + 2], verts[v + 3], verts[v + 4], verts[v + 5]);
mUVs.push(verts[v + 6], verts[v + 7]);
}
}
}
else {
let vi = 0;
while (Number.isFinite(clippedVertices[vi + 6]) && Number.isFinite(clippedVertices[vi + 7])) {
mVertices.push(clippedVertices[vi]);
mVertices.push(-clippedVertices[vi + 1]);
colors.push(clippedVertices[vi + 2]);
colors.push(clippedVertices[vi + 3]);
colors.push(clippedVertices[vi + 4]);
colors.push(clippedVertices[vi + 5]);
mUVs.push(clippedVertices[vi + 6]);
mUVs.push(clippedVertices[vi + 7]);
vi += this.vertexSize;
}
}
let alpha = 1;
let color = null;
let colorNum = null;
let blendMode;
switch (slotBlendMode) {
case 1:
blendMode = "light";
break;
case 2:
blendMode = "multiply";
break;
case 3:
blendMode = "screen";
break;
default:
blendMode = "normal";
}
colorNum = ((colors[3] * 255) << 24) + colors[0] * 255 | 0 + ((colors[1] * 255) << 8) + ((colors[2] * 255) << 16);
spineSkeletonIns.graphics.drawTriangles(texture, 0, 0, mVertices, mUVs, new Uint16Array(clippedTriangles), Laya.Matrix.EMPTY, alpha, color, blendMode, colorNum);
}
else {
let verts = renderable.vertices;
let mVertices = [];
let mUVs = [];
let colors = [];
if (this.vertexEffect != null) {
let vertexEffect = this.vertexEffect;
{
for (let v = 0, u = 0, n = renderable.numFloats; v < n; v += vertexSize, u += 2) {
tempPos.x = verts[v];
tempPos.y = verts[v + 1];
tempUv.x = uvs[u];
tempUv.y = uvs[u + 1];
tempLight.setFromColor(finalColor);
tempDark.set(0, 0, 0, 0);
vertexEffect.transform(tempPos, tempUv, tempLight, tempDark);
verts[v] = tempPos.x;
verts[v + 1] = tempPos.y;
verts[v + 2] = tempLight.r;
verts[v + 3] = tempLight.g;
verts[v + 4] = tempLight.b;
verts[v + 5] = tempLight.a;
verts[v + 6] = tempUv.x;
verts[v + 7] = tempUv.y;
mVertices.push(verts[v], -verts[v + 1]);
colors.push(verts[v + 2], verts[v + 3], verts[v + 4], verts[v + 5]);
mUVs.push(verts[v + 6], verts[v + 7]);
}
}
}
else {
{
for (let v = 2, u = 0, n = renderable.numFloats; v < n; v += vertexSize, u += 2) {
verts[v] = finalColor.r;
verts[v + 1] = finalColor.g;
verts[v + 2] = finalColor.b;
verts[v + 3] = finalColor.a;
verts[v + 4] = uvs[u];
verts[v + 5] = uvs[u + 1];
mVertices.push(verts[v - 2], -verts[v - 1]);
colors.push(verts[v], verts[v + 1], verts[v + 2], verts[v + 3]);
mUVs.push(verts[v + 4], verts[v + 5]);
}
}
}
let alpha = 1;
let color = null;
let colorNum = null;
let blendMode;
switch (slotBlendMode) {
case 1:
blendMode = "light";
break;
case 2:
blendMode = "multiply";
break;
case 3:
blendMode = "screen";
break;
default:
blendMode = "normal";
}
colorNum = ((colors[3] * 255) << 24) + colors[0] * 255 | 0 + ((colors[1] * 255) << 8) + ((colors[2] * 255) << 16);
spineSkeletonIns.graphics.drawTriangles(texture, 0, 0, mVertices, mUVs, new Uint16Array(triangles), Laya.Matrix.EMPTY, alpha, color, blendMode, colorNum);
}
}
clipper.clipEndWithSlot(slot);
}
clipper.clipEnd();
}
}
SpineSkeletonRenderer.QUAD_TRIANGLES = [0, 1, 2, 2, 3, 0];
var TimeKeeper = spine.TimeKeeper;
var Skeleton = spine.Skeleton;
var AnimationState = spine.AnimationState;
var AnimationStateData = spine.AnimationStateData;
class SpineSkeleton extends Laya.Sprite {
constructor(templet = null) {
super();
this.currentPlayTime = 0;
this._pause = true;
this._currAniName = null;
this._playbackRate = 1.0;
this._playAudio = true;
this._soundChannelArr = [];
this.trackIndex = 0;
if (templet)
this.init(templet);
this._ins = this;
}
init(templet) {
var that = this;
this._templet = templet;
this.skeleton = new Skeleton(this._templet.skeletonData);
this.stateData = new AnimationStateData(this.skeleton.data);
this.state = new AnimationState(this.stateData);
this.skeletonRenderer = new SpineSkeletonRenderer(false);
this.timeKeeper = new TimeKeeper();
this.skeletonRenderer.premultipliedAlpha = this._templet._spinePremultipliedAlpha;
this.state.addListener({
start: function (entry) {
},
interrupt: function (entry) {
},
end: function (entry) {
},
dispose: function (entry) {
},
complete: function (entry) {
if (entry.loop) {
that.event(Laya.Event.COMPLETE);
}
else {
that._currAniName = null;
that.event(Laya.Event.STOPPED);
}
},
event: function (entry, event) {
var eventData = {
audioValue: event.data.audioPath,
audioPath: event.data.audioPath,
floatValue: event.floatValue,
intValue: event.intValue,
name: event.data.name,
stringValue: event.stringValue,
time: event.time * 1000,
balance: event.balance,
volume: event.volume
};
that.event(Laya.Event.LABEL, eventData);
var _soundChannel;
if (that._playAudio && eventData.audioValue) {
_soundChannel = Laya.SoundManager.playSound(templet._textureDic.root + eventData.audioValue, 1, Laya.Handler.create(that, that._onAniSoundStoped), null, (that.currentPlayTime * 1000 - eventData.time) / 1000);
Laya.SoundManager.playbackRate = that._playbackRate;
_soundChannel && that._soundChannelArr.push(_soundChannel);
}
},
});
}
play(nameOrIndex, loop, force = true, start = 0, end = 0, freshSkin = true, playAudio = true) {
this._playAudio = playAudio;
start /= 1000;
end /= 1000;
var animationName = nameOrIndex;
if (start < 0 || end < 0)
throw new Error("SpineSkeleton: start and end must large than zero.");
if ((end !== 0) && (start > end))
throw new Error("SpineSkeleton: start must less than end.");
if (typeof animationName == "number") {
animationName = this.getAniNameByIndex(nameOrIndex);
}
if (force || this._pause || this._currAniName != animationName) {
this._currAniName = animationName;
this.state.setAnimation(this.trackIndex, animationName, loop);
let trackEntry = this.state.getCurrent(this.trackIndex);
trackEntry.animationStart = start;
if (!!end && end < trackEntry.animationEnd)
trackEntry.animationEnd = end;
let animationDuration = trackEntry.animation.duration;
this._duration = animationDuration;
this._playStart = start;
this._playEnd = end <= animationDuration ? end : animationDuration;
if (this._pause) {
this._pause = false;
this.timer.frameLoop(1, this, this._update, null, true);
}
this._update();
}
}
_update() {
this.timeKeeper.update();
let delta = this.timeKeeper.delta * this._playbackRate;
let trackEntry = this.state.getCurrent(this.trackIndex);
this.state.update(delta);
this.state.apply(this.skeleton);
let animationLast = trackEntry.animationLast;
this.currentPlayTime = Math.max(0, animationLast);
if (!this.state || !this.skeleton) {
return;
}
this.skeleton.updateWorldTransform();
this._ins.graphics.clear();
this.skeletonRenderer.draw(this.skeleton, -1, -1, this._ins, this._templet._textureDic);
}
getAnimNum() {
return this._templet.skeletonData.animations.length;
}
getAniNameByIndex(index) {
return this._templet.getAniNameByIndex(index);
}
getSlotByName(slotName) {
return this.skeleton.findSlot(slotName);
}
playbackRate(value) {
this._playbackRate = value;
}
showSkinByName(name) {
this.showSkinByIndex(this._templet.getSkinIndexByName(name));
}
showSkinByIndex(skinIndex) {
let newSkine = this.skeleton.data.skins[skinIndex];
this.skeleton.setSkin(newSkine);
this.skeleton.setSlotsToSetupPose();
}
stop() {
if (!this._pause) {
this._pause = true;
this._currAniName = null;
this.timer.clear(this, this._update);
this.state.update(-this.currentPlayTime);
this.currentPlayTime = 0;
this.event(Laya.Event.STOPPED);
if (this._soundChannelArr.length > 0) {
this._onAniSoundStoped(true);
}
}
}
paused() {
if (!this._pause) {
this._pause = true;
this.timer.clear(this, this._update);
this.event(Laya.Event.PAUSED);
if (this._soundChannelArr.length > 0) {
var _soundChannel;
for (var len = this._soundChannelArr.length, i = 0; i < len; i++) {
_soundChannel = this._soundChannelArr[i];
if (!_soundChannel.isStopped) {
_soundChannel.pause();
}
}
}
}
}
resume() {
if (this._pause) {
this._pause = false;
this.timer.frameLoop(1, this, this._update, null, true);
if (this._soundChannelArr.length > 0) {
var _soundChannel;
for (var len = this._soundChannelArr.length, i = 0; i < len; i++) {
_soundChannel = this._soundChannelArr[i];
if (_soundChannel.audioBuffer) {
_soundChannel.resume();
}
}
}
}
}
_onAniSoundStoped(force) {
var _channel;
for (var len = this._soundChannelArr.length, i = 0; i < len; i++) {
_channel = this._soundChannelArr[i];
if (_channel.isStopped || force) {
!_channel.isStopped && _channel.stop();
this._soundChannelArr.splice(i, 1);
len--;
i--;
}
}
}
destroy(destroyChild = true) {
super.destroy(destroyChild);
this._templet._removeReference(1);
this._templet = null;
this.timeKeeper = null;
this.skeleton = null;
this.state.clearListeners();
this.state = null;
this.skeletonRenderer = null;
this.timer.clear(this, this._update);
if (this._soundChannelArr.length > 0) {
this._onAniSoundStoped(true);
}
}
get templet() {
return this._templet;
}
addAnimation(nameOrIndex, loop = false, delay = 0) {
delay /= 1000;
var animationName = nameOrIndex;
if (typeof animationName == "number") {
animationName = this.getAniNameByIndex(animationName);
}
this._currAniName = animationName;
this.state.addAnimation(this.trackIndex, animationName, loop, delay);
}
setMix(fromNameOrIndex, toNameOrIndex, duration) {
duration /= 1000;
var fromName = fromNameOrIndex;
if (typeof fromName == "number") {
fromName = this.getAniNameByIndex(fromName);
}
var toName = toNameOrIndex;
if (typeof toName == "number") {
toName = this.getAniNameByIndex(toName);
}
this.stateData.setMix(fromName, toName, duration);
}
getBoneByName(boneName) {
return this.skeleton.findBone(boneName);
}
getSkeleton() {
return this.skeleton;
}
setSlotAttachment(slotName, attachmentName) {
this.skeleton.setAttachment(slotName, attachmentName);
}
set currentTime(value) {
if (!this._currAniName || !this._templet)
return;
value /= 1000;
if (value < this._playStart || (!!this._playEnd && value > this._playEnd) || value > this._duration)
throw new Error("AnimationPlayer: value must large than playStartTime,small than playEndTime.");
this.state.update(value - this.currentPlayTime);
this.currentPlayTime = value;
}
get playState() {
if (!this._currAniName)
return SpineSkeleton.stopped;
if (this._pause)
return SpineSkeleton.paused;
return SpineSkeleton.playing;
}
}
SpineSkeleton.stopped = 0;
SpineSkeleton.paused = 1;
SpineSkeleton.playing = 2;
Laya.ILaya.regClass(SpineSkeleton);
Laya.ClassUtils.regClass("laya.layaspine.SpineSkeleton", SpineSkeleton);
Laya.ClassUtils.regClass("Laya.SpineSkeleton", SpineSkeleton);
var SharedAssetManager = spine.SharedAssetManager;
var TextureAtlas = spine.TextureAtlas;
var AtlasAttachmentLoader = spine.AtlasAttachmentLoader;
var SkeletonJson = spine.SkeletonJson;
class SpineTemplet extends Laya.Resource {
constructor() {
super();
this._textureDic = {};
this._isDestroyed = false;
this._layaPremultipliedAlpha = true;
this._spinePremultipliedAlpha = false;
}
loadAni(jsonUrl, textureUrlList = null) {
let splitIndex = jsonUrl.lastIndexOf("/") + 1;
let clientId = jsonUrl.slice(0, splitIndex);
jsonUrl = jsonUrl.slice(splitIndex);
let atlasUrl = jsonUrl.replace(".json", ".atlas");
if (!textureUrlList) {
textureUrlList = [jsonUrl.replace(".json", ".png")];
}
this._textureDic.root = clientId;
this._textureUrlList = textureUrlList;
this.clientId = clientId;
this.atlasUrl = atlasUrl;
this.jsonUrl = jsonUrl;
this.assetManager = new SharedAssetManager(clientId);
this.assetManager.loadJson(clientId, jsonUrl);
this.assetManager.loadText(clientId, atlasUrl);
for (var i = 0, len = textureUrlList.length, texture; i < len; i++) {
texture = textureUrlList[i];
this.assetManager.loadTexture(clientId, this.textureLoader.bind(this), texture);
}
window.requestAnimationFrame(this.loop.bind(this));
}
textureLoader(tex) {
var src = tex.url;
var tTextureName, item, textureUrlList = this._textureUrlList;
for (var i = 0, len = textureUrlList.length; i < len; i++) {
item = textureUrlList[i];
if (src.endsWith(`/${item}`)) {
tTextureName = item;
break;
}
}
var tTexture = this._textureDic[tTextureName] = new SpineGLTexture(tex.bitmap);
return tTexture;
}
loop() {
if (this.assetManager.isLoadingComplete(this.clientId)) {
this.parseSpineAni();
return;
}
if (this.assetManager.hasErrors()) {
this.event(Laya.Event.ERROR, "load failed:" + this.assetManager.getErrors());
return;
}
window.requestAnimationFrame(this.loop.bind(this));
}
parseSpineAni() {
if (this._isDestroyed) {
this.destroy();
return;
}
var _this = this;
var atlas = new TextureAtlas(this.assetManager.get(this.clientId, this.atlasUrl), function (path) {
return _this.assetManager.get(_this.clientId, path);
});
var atlasLoader = new AtlasAttachmentLoader(atlas);
this.skeletonJson = new SkeletonJson(atlasLoader);
this.skeletonData = this.skeletonJson.readSkeletonData(this.assetManager.get(this.clientId, this.jsonUrl));
this.event(Laya.Event.COMPLETE, this);
}
buildArmature() {
return new SpineSkeleton(this);
}
getAniNameByIndex(index) {
var tAni = this.skeletonData.animations[index];
if (tAni)
return tAni.name;
return null;
}
getSkinIndexByName(skinName) {
var skins = this.skeletonData.skins;
var tSkinData;
for (var i = 0, n = skins.length; i < n; i++) {
tSkinData = skins[i];
if (tSkinData.name == skinName) {
return i;
}
}
return -1;
}
destroy() {
this._isDestroyed = true;
var tTexture;
for (tTexture in this._textureDic) {
if (tTexture == "root")
continue;
if (tTexture) {
this._textureDic[tTexture].destroy();
}
}
super.destroy();
}
}
var AssetManager = spine.AssetManager;
var AtlasAttachmentLoader$1 = spine.AtlasAttachmentLoader;
var SkeletonBinary = spine.SkeletonBinary;
class SpineTempletBinary extends Laya.Resource {
constructor() {
super();
this._textureDic = {};
this._isDestroyed = false;
this._layaPremultipliedAlpha = true;
this._spinePremultipliedAlpha = false;
}
loadAni(skelUrl, textureUrlList = null) {
let splitIndex = skelUrl.lastIndexOf("/") + 1;
let pathPrefix = skelUrl.slice(0, splitIndex);
skelUrl = skelUrl.slice(splitIndex);
this.skelUrl = skelUrl;
skelUrl = skelUrl.replace(".json", ".skel");
let atlasUrl = skelUrl.replace(".skel", ".atlas");
if (!textureUrlList) {
textureUrlList = [skelUrl.replace(".skel", ".png")];
}
this._textureDic.root = pathPrefix;
this.pathPrefix = pathPrefix;
this.atlasUrl = atlasUrl;
this.textureUrlList = textureUrlList;
this.assetManager = new AssetManager(this.textureLoader.bind(this), pathPrefix);
this.assetManager.loadBinary(this.skelUrl);
this.assetManager.loadTextureAtlas(atlasUrl);
Laya.Laya.timer.frameOnce(1, this, this.loop);
}
textureLoader(tex) {
let src = tex.url;
let tTextureName, item, textureUrlList = this.textureUrlList;
for (let i = 0, len = textureUrlList.length; i < len; i++) {
item = textureUrlList[i];
if (src.endsWith(item)) {
tTextureName = item;
break;
}
}
let tTexture = this._textureDic[tTextureName] = new SpineGLTexture(tex.bitmap);
return tTexture;
}
loop() {
if (this.assetManager.isLoadingComplete()) {
this.parseSpineAni();
return;
}
if (this.assetManager.hasErrors()) {
this.event(Laya.Event.ERROR, "load failed:" + this.assetManager.getErrors());
return;
}
window.requestAnimationFrame(this.loop.bind(this));
}
parseSpineAni() {
if (this._isDestroyed) {
this.destroy();
return;
}
let atlas = this.assetManager.get(this.atlasUrl);
let atlasLoader = new AtlasAttachmentLoader$1(atlas);
this.skeletonBinary = new SkeletonBinary(atlasLoader);
this.skeletonData = this.skeletonBinary.readSkeletonData(this.assetManager.get(this.skelUrl));
this.event(Laya.Event.COMPLETE, this);
}
buildArmature() {
return new SpineSkeleton(this);
}
getAniNameByIndex(index) {
let tAni = this.skeletonData.animations[index];
if (tAni)
return tAni.name;
return null;
}
getSkinIndexByName(skinName) {
let skins = this.skeletonData.skins;
let tSkinData;
for (let i = 0, n = skins.length; i < n; i++) {
tSkinData = skins[i];
if (tSkinData.name == skinName) {
return i;
}
}
return -1;
}
destroy() {
this._isDestroyed = true;
let tTexture;
for (tTexture in this._textureDic) {
if (tTexture == "root")
continue;
if (tTexture) {
this._textureDic[tTexture].destroy();
}
}
super.destroy();
}
}
exports.SpineGLTexture = SpineGLTexture;
exports.SpineSkeleton = SpineSkeleton;
exports.SpineSkeletonRenderer = SpineSkeletonRenderer;
exports.SpineTemplet = SpineTemplet;
exports.SpineTempletBinary = SpineTempletBinary;
}(window.Laya = window.Laya || {}, Laya));

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
window.Physics3D=function(n,o){window.conch.setGetWorldTransformFunction(o.getWorldTransform),window.conch.setSetWorldTransformFunction(o.setWorldTransform);var r=window.layaConchBullet;return r.then=n=>{n()},window.Physics3D=r,r};

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Some files were not shown because too many files have changed in this diff Show More