layaair-example
This commit is contained in:
parent
c3aa1f918e
commit
4bfe797a89
30
examples/layaair/backend/.vscode/launch.json
vendored
Normal file
30
examples/layaair/backend/.vscode/launch.json
vendored
Normal 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"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
3
examples/layaair/backend/.vscode/settings.json
vendored
Normal file
3
examples/layaair/backend/.vscode/settings.json
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"typescript.tsdk": "node_modules\\typescript\\lib"
|
||||||
|
}
|
35
examples/layaair/backend/README.md
Normal file
35
examples/layaair/backend/README.md
Normal 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.
|
23
examples/layaair/backend/package.json
Normal file
23
examples/layaair/backend/package.json
Normal 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"
|
||||||
|
}
|
||||||
|
}
|
26
examples/layaair/backend/src/api/ApiAddData.ts
Normal file
26
examples/layaair/backend/src/api/ApiAddData.ts
Normal 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
|
||||||
|
});
|
||||||
|
}
|
13
examples/layaair/backend/src/api/ApiGetData.ts
Normal file
13
examples/layaair/backend/src/api/ApiGetData.ts
Normal 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 }[] = [];
|
60
examples/layaair/backend/src/index copy.ts
Normal file
60
examples/layaair/backend/src/index copy.ts
Normal 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);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
38
examples/layaair/backend/src/index.ts
Normal file
38
examples/layaair/backend/src/index.ts
Normal 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);
|
||||||
|
});
|
10
examples/layaair/backend/src/shared/protocols/PtlAddData.ts
Normal file
10
examples/layaair/backend/src/shared/protocols/PtlAddData.ts
Normal 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
|
||||||
|
}
|
13
examples/layaair/backend/src/shared/protocols/PtlGetData.ts
Normal file
13
examples/layaair/backend/src/shared/protocols/PtlGetData.ts
Normal 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
|
||||||
|
}[]
|
||||||
|
}
|
@ -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"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
18
examples/layaair/backend/tsconfig.json
Normal file
18
examples/layaair/backend/tsconfig.json
Normal 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
2
examples/layaair/frontend/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
.rpt2_cache
|
||||||
|
node_modules
|
75
examples/layaair/frontend/.laya/compile.js
Normal file
75
examples/layaair/frontend/.laya/compile.js
Normal 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);
|
||||||
|
});
|
||||||
|
});
|
1
examples/layaair/frontend/.laya/layame/account.info
Normal file
1
examples/layaair/frontend/.laya/layame/account.info
Normal file
@ -0,0 +1 @@
|
|||||||
|
{"username":null,"gameId":null}
|
92
examples/layaair/frontend/.laya/pub_utils.js
Normal file
92
examples/layaair/frontend/.laya/pub_utils.js
Normal 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 }
|
794
examples/layaair/frontend/.laya/publish.js
Normal file
794
examples/layaair/frontend/.laya/publish.js
Normal 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));
|
||||||
|
});
|
||||||
|
|
||||||
|
// 压缩png,jpg
|
||||||
|
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!");
|
||||||
|
});
|
117
examples/layaair/frontend/.laya/publish_alipaygame.js
Normal file
117
examples/layaair/frontend/.laya/publish_alipaygame.js
Normal 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");
|
||||||
|
});
|
163
examples/layaair/frontend/.laya/publish_bdgame.js
Normal file
163
examples/layaair/frontend/.laya/publish_bdgame.js
Normal 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");
|
||||||
|
});
|
106
examples/layaair/frontend/.laya/publish_biligame.js
Normal file
106
examples/layaair/frontend/.laya/publish_biligame.js
Normal 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");
|
||||||
|
});
|
325
examples/layaair/frontend/.laya/publish_bytedancegame.js
Normal file
325
examples/layaair/frontend/.laya/publish_bytedancegame.js
Normal 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");
|
||||||
|
});
|
663
examples/layaair/frontend/.laya/publish_hwgame.js
Normal file
663
examples/layaair/frontend/.laya/publish_hwgame.js
Normal 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");
|
||||||
|
});
|
453
examples/layaair/frontend/.laya/publish_layame.js
Normal file
453
examples/layaair/frontend/.laya/publish_layame.js
Normal 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");
|
||||||
|
});
|
813
examples/layaair/frontend/.laya/publish_oppogame.js
Normal file
813
examples/layaair/frontend/.laya/publish_oppogame.js
Normal 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");
|
||||||
|
});
|
296
examples/layaair/frontend/.laya/publish_qqgame.js
Normal file
296
examples/layaair/frontend/.laya/publish_qqgame.js
Normal 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");
|
||||||
|
});
|
265
examples/layaair/frontend/.laya/publish_taobaominiapp.js
Normal file
265
examples/layaair/frontend/.laya/publish_taobaominiapp.js
Normal 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");
|
||||||
|
});
|
177
examples/layaair/frontend/.laya/publish_taobaowidget.js
Normal file
177
examples/layaair/frontend/.laya/publish_taobaowidget.js
Normal 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");
|
||||||
|
});
|
1003
examples/layaair/frontend/.laya/publish_vivogame.js
Normal file
1003
examples/layaair/frontend/.laya/publish_vivogame.js
Normal file
File diff suppressed because it is too large
Load Diff
384
examples/layaair/frontend/.laya/publish_wxgame.js
Normal file
384
examples/layaair/frontend/.laya/publish_wxgame.js
Normal 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");
|
||||||
|
});
|
379
examples/layaair/frontend/.laya/publish_xmgame.js
Normal file
379
examples/layaair/frontend/.laya/publish_xmgame.js
Normal 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}`);
|
||||||
|
// 输出pid,macos要用: 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");
|
||||||
|
});
|
118
examples/layaair/frontend/.laya/publish_youkugame.js
Normal file
118
examples/layaair/frontend/.laya/publish_youkugame.js
Normal 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");
|
||||||
|
});
|
26
examples/layaair/frontend/.vscode/launch.json
vendored
Normal file
26
examples/layaair/frontend/.vscode/launch.json
vendored
Normal 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/*"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
9
examples/layaair/frontend/README.md
Normal file
9
examples/layaair/frontend/README.md
Normal 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` 头部。
|
1
examples/layaair/frontend/bin/fileconfig.json
Normal file
1
examples/layaair/frontend/bin/fileconfig.json
Normal 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"]]}
|
32
examples/layaair/frontend/bin/index.html
Normal file
32
examples/layaair/frontend/bin/index.html
Normal 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>
|
15
examples/layaair/frontend/bin/index.js
Normal file
15
examples/layaair/frontend/bin/index.js
Normal 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");
|
4951
examples/layaair/frontend/bin/js/bundle.js
Normal file
4951
examples/layaair/frontend/bin/js/bundle.js
Normal file
File diff suppressed because it is too large
Load Diff
3746
examples/layaair/frontend/bin/libs/bytebuffer.js
Normal file
3746
examples/layaair/frontend/bin/libs/bytebuffer.js
Normal file
File diff suppressed because it is too large
Load Diff
2357
examples/layaair/frontend/bin/libs/domparserinone.js
Normal file
2357
examples/layaair/frontend/bin/libs/domparserinone.js
Normal file
File diff suppressed because it is too large
Load Diff
1825
examples/layaair/frontend/bin/libs/laya.Alipaymini.js
Normal file
1825
examples/layaair/frontend/bin/libs/laya.Alipaymini.js
Normal file
File diff suppressed because it is too large
Load Diff
4172
examples/layaair/frontend/bin/libs/laya.ani.js
Normal file
4172
examples/layaair/frontend/bin/libs/laya.ani.js
Normal file
File diff suppressed because it is too large
Load Diff
1829
examples/layaair/frontend/bin/libs/laya.bdmini.js
Normal file
1829
examples/layaair/frontend/bin/libs/laya.bdmini.js
Normal file
File diff suppressed because it is too large
Load Diff
1855
examples/layaair/frontend/bin/libs/laya.bilimini.js
Normal file
1855
examples/layaair/frontend/bin/libs/laya.bilimini.js
Normal file
File diff suppressed because it is too large
Load Diff
15198
examples/layaair/frontend/bin/libs/laya.cannonPhysics.js
Normal file
15198
examples/layaair/frontend/bin/libs/laya.cannonPhysics.js
Normal file
File diff suppressed because it is too large
Load Diff
26606
examples/layaair/frontend/bin/libs/laya.core.js
Normal file
26606
examples/layaair/frontend/bin/libs/laya.core.js
Normal file
File diff suppressed because it is too large
Load Diff
32166
examples/layaair/frontend/bin/libs/laya.d3.js
Normal file
32166
examples/layaair/frontend/bin/libs/laya.d3.js
Normal file
File diff suppressed because one or more lines are too long
7960
examples/layaair/frontend/bin/libs/laya.debugtool.js
Normal file
7960
examples/layaair/frontend/bin/libs/laya.debugtool.js
Normal file
File diff suppressed because one or more lines are too long
678
examples/layaair/frontend/bin/libs/laya.device.js
Normal file
678
examples/layaair/frontend/bin/libs/laya.device.js
Normal 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));
|
1339
examples/layaair/frontend/bin/libs/laya.gltf.js
Normal file
1339
examples/layaair/frontend/bin/libs/laya.gltf.js
Normal file
File diff suppressed because it is too large
Load Diff
1561
examples/layaair/frontend/bin/libs/laya.html.js
Normal file
1561
examples/layaair/frontend/bin/libs/laya.html.js
Normal file
File diff suppressed because it is too large
Load Diff
1508
examples/layaair/frontend/bin/libs/laya.hwmini.js
Normal file
1508
examples/layaair/frontend/bin/libs/laya.hwmini.js
Normal file
File diff suppressed because it is too large
Load Diff
635
examples/layaair/frontend/bin/libs/laya.particle.js
Normal file
635
examples/layaair/frontend/bin/libs/laya.particle.js
Normal 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));
|
790
examples/layaair/frontend/bin/libs/laya.performancetool.js
Normal file
790
examples/layaair/frontend/bin/libs/laya.performancetool.js
Normal 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));
|
17873
examples/layaair/frontend/bin/libs/laya.physics.js
Normal file
17873
examples/layaair/frontend/bin/libs/laya.physics.js
Normal file
File diff suppressed because it is too large
Load Diff
3053
examples/layaair/frontend/bin/libs/laya.physics3D.js
Normal file
3053
examples/layaair/frontend/bin/libs/laya.physics3D.js
Normal file
File diff suppressed because one or more lines are too long
10
examples/layaair/frontend/bin/libs/laya.physics3D.runtime.js
Normal file
10
examples/layaair/frontend/bin/libs/laya.physics3D.runtime.js
Normal 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;
|
||||||
|
};
|
3077
examples/layaair/frontend/bin/libs/laya.physics3D.wasm-wx.js
Normal file
3077
examples/layaair/frontend/bin/libs/laya.physics3D.wasm-wx.js
Normal file
File diff suppressed because it is too large
Load Diff
3076
examples/layaair/frontend/bin/libs/laya.physics3D.wasm.js
Normal file
3076
examples/layaair/frontend/bin/libs/laya.physics3D.wasm.js
Normal file
File diff suppressed because it is too large
Load Diff
BIN
examples/layaair/frontend/bin/libs/laya.physics3D.wasm.wasm
Normal file
BIN
examples/layaair/frontend/bin/libs/laya.physics3D.wasm.wasm
Normal file
Binary file not shown.
1855
examples/layaair/frontend/bin/libs/laya.qqmini.js
Normal file
1855
examples/layaair/frontend/bin/libs/laya.qqmini.js
Normal file
File diff suppressed because it is too large
Load Diff
1821
examples/layaair/frontend/bin/libs/laya.quickgamemini.js
Normal file
1821
examples/layaair/frontend/bin/libs/laya.quickgamemini.js
Normal file
File diff suppressed because it is too large
Load Diff
745
examples/layaair/frontend/bin/libs/laya.spine.js
Normal file
745
examples/layaair/frontend/bin/libs/laya.spine.js
Normal 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));
|
1573
examples/layaair/frontend/bin/libs/laya.tbmini.js
Normal file
1573
examples/layaair/frontend/bin/libs/laya.tbmini.js
Normal file
File diff suppressed because it is too large
Load Diff
1458
examples/layaair/frontend/bin/libs/laya.tbpluginmini.js
Normal file
1458
examples/layaair/frontend/bin/libs/laya.tbpluginmini.js
Normal file
File diff suppressed because it is too large
Load Diff
1601
examples/layaair/frontend/bin/libs/laya.tiledmap.js
Normal file
1601
examples/layaair/frontend/bin/libs/laya.tiledmap.js
Normal file
File diff suppressed because it is too large
Load Diff
1856
examples/layaair/frontend/bin/libs/laya.ttmini.js
Normal file
1856
examples/layaair/frontend/bin/libs/laya.ttmini.js
Normal file
File diff suppressed because it is too large
Load Diff
6176
examples/layaair/frontend/bin/libs/laya.ui.js
Normal file
6176
examples/layaair/frontend/bin/libs/laya.ui.js
Normal file
File diff suppressed because it is too large
Load Diff
1841
examples/layaair/frontend/bin/libs/laya.vvmini.js
Normal file
1841
examples/layaair/frontend/bin/libs/laya.vvmini.js
Normal file
File diff suppressed because it is too large
Load Diff
1778
examples/layaair/frontend/bin/libs/laya.wxmini.js
Normal file
1778
examples/layaair/frontend/bin/libs/laya.wxmini.js
Normal file
File diff suppressed because it is too large
Load Diff
1840
examples/layaair/frontend/bin/libs/laya.xmmini.js
Normal file
1840
examples/layaair/frontend/bin/libs/laya.xmmini.js
Normal file
File diff suppressed because it is too large
Load Diff
7
examples/layaair/frontend/bin/libs/min/bytebuffer.min.js
vendored
Normal file
7
examples/layaair/frontend/bin/libs/min/bytebuffer.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
examples/layaair/frontend/bin/libs/min/domparserinone.min.js
vendored
Normal file
1
examples/layaair/frontend/bin/libs/min/domparserinone.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
examples/layaair/frontend/bin/libs/min/laya.Alipaymini.min.js
vendored
Normal file
1
examples/layaair/frontend/bin/libs/min/laya.Alipaymini.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
examples/layaair/frontend/bin/libs/min/laya.ani.min.js
vendored
Normal file
1
examples/layaair/frontend/bin/libs/min/laya.ani.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
examples/layaair/frontend/bin/libs/min/laya.bdmini.min.js
vendored
Normal file
1
examples/layaair/frontend/bin/libs/min/laya.bdmini.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
examples/layaair/frontend/bin/libs/min/laya.bilimini.min.js
vendored
Normal file
1
examples/layaair/frontend/bin/libs/min/laya.bilimini.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
examples/layaair/frontend/bin/libs/min/laya.cannonPhysics.min.js
vendored
Normal file
1
examples/layaair/frontend/bin/libs/min/laya.cannonPhysics.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
examples/layaair/frontend/bin/libs/min/laya.core.min.js
vendored
Normal file
1
examples/layaair/frontend/bin/libs/min/laya.core.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
examples/layaair/frontend/bin/libs/min/laya.d3.min.js
vendored
Normal file
1
examples/layaair/frontend/bin/libs/min/laya.d3.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
examples/layaair/frontend/bin/libs/min/laya.debugtool.min.js
vendored
Normal file
1
examples/layaair/frontend/bin/libs/min/laya.debugtool.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
examples/layaair/frontend/bin/libs/min/laya.device.min.js
vendored
Normal file
1
examples/layaair/frontend/bin/libs/min/laya.device.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
examples/layaair/frontend/bin/libs/min/laya.gltf.min.js
vendored
Normal file
1
examples/layaair/frontend/bin/libs/min/laya.gltf.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
examples/layaair/frontend/bin/libs/min/laya.html.min.js
vendored
Normal file
1
examples/layaair/frontend/bin/libs/min/laya.html.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
examples/layaair/frontend/bin/libs/min/laya.hwmini.min.js
vendored
Normal file
1
examples/layaair/frontend/bin/libs/min/laya.hwmini.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
examples/layaair/frontend/bin/libs/min/laya.particle.min.js
vendored
Normal file
1
examples/layaair/frontend/bin/libs/min/laya.particle.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
examples/layaair/frontend/bin/libs/min/laya.performancetool.min.js
vendored
Normal file
1
examples/layaair/frontend/bin/libs/min/laya.performancetool.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
examples/layaair/frontend/bin/libs/min/laya.physics.min.js
vendored
Normal file
1
examples/layaair/frontend/bin/libs/min/laya.physics.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
examples/layaair/frontend/bin/libs/min/laya.physics3D.min.js
vendored
Normal file
1
examples/layaair/frontend/bin/libs/min/laya.physics3D.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
examples/layaair/frontend/bin/libs/min/laya.physics3D.runtime.min.js
vendored
Normal file
1
examples/layaair/frontend/bin/libs/min/laya.physics3D.runtime.min.js
vendored
Normal 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};
|
1
examples/layaair/frontend/bin/libs/min/laya.physics3D.wasm-wx.min.js
vendored
Normal file
1
examples/layaair/frontend/bin/libs/min/laya.physics3D.wasm-wx.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
examples/layaair/frontend/bin/libs/min/laya.physics3D.wasm.min.js
vendored
Normal file
1
examples/layaair/frontend/bin/libs/min/laya.physics3D.wasm.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
BIN
examples/layaair/frontend/bin/libs/min/laya.physics3D.wasm.wasm
Normal file
BIN
examples/layaair/frontend/bin/libs/min/laya.physics3D.wasm.wasm
Normal file
Binary file not shown.
1
examples/layaair/frontend/bin/libs/min/laya.qqmini.min.js
vendored
Normal file
1
examples/layaair/frontend/bin/libs/min/laya.qqmini.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
examples/layaair/frontend/bin/libs/min/laya.quickgamemini.min.js
vendored
Normal file
1
examples/layaair/frontend/bin/libs/min/laya.quickgamemini.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
examples/layaair/frontend/bin/libs/min/laya.spine.min.js
vendored
Normal file
1
examples/layaair/frontend/bin/libs/min/laya.spine.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
examples/layaair/frontend/bin/libs/min/laya.tbmini.min.js
vendored
Normal file
1
examples/layaair/frontend/bin/libs/min/laya.tbmini.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
examples/layaair/frontend/bin/libs/min/laya.tbpluginmini.min.js
vendored
Normal file
1
examples/layaair/frontend/bin/libs/min/laya.tbpluginmini.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
examples/layaair/frontend/bin/libs/min/laya.tiledmap.min.js
vendored
Normal file
1
examples/layaair/frontend/bin/libs/min/laya.tiledmap.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
examples/layaair/frontend/bin/libs/min/laya.ttmini.min.js
vendored
Normal file
1
examples/layaair/frontend/bin/libs/min/laya.ttmini.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
examples/layaair/frontend/bin/libs/min/laya.ui.min.js
vendored
Normal file
1
examples/layaair/frontend/bin/libs/min/laya.ui.min.js
vendored
Normal file
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
Loading…
Reference in New Issue
Block a user