Launcher.ts 13.1 KB
import { SDK } from "simba-sdk";
import { GameRecord, initAVG, PlotManager } from "../avg/AVG";
import { DummyLabel, DummyNode, DummyProgressBar, DummySprite } from "../common/CCDummyObjects";
import { AudioManager } from "simba-cc-audio-manager";
import { UIManager } from "../common/gameplay/managers/UIManager";
import { AnimationUtils } from "../common/utils/AnimationUtils";
import { GameConfig } from "../GameConfig";
import { LoadingState } from "./Enums";
import GameDotMgr from "./GameDotMgr";
import { GameModelManager } from "./model/GameModelManager";
import AlertDialogViewPresenter from "./ui/presenter/AlertDialogViewPresenter";
import MainViewPresenter from "./ui/presenter/MainViewPresenter";
import { AlertDialogViewProps } from "./ui/view/type/AlertDialogView";
import PortraitFixComponent from "../common/components/PortraitFixComponent";
import { ResUtils } from "simba-cc-resutils";
import CCGameCenterComponent from "../cooperation/script/CCGameCenterComponent";
import CCGameCenterNodeFactory from "../cooperation/script/CCGameCenterNodeFactory";
import CustomerServiceDataCenter from "../customerService/script/CustomerServiceDataCenter";
import { EventCenter } from "../cooperation/event/EventCenter";
import { CompositeDisposable } from "../cooperation/event/EventKit";
import UnlockSpecialPlotEventManager from "./model/UnlockSpecialPlotEventManager";
import { initExchangeCode } from "simba-sdk-exchangecode";

const { ccclass, property } = cc._decorator;


@ccclass
export default class Launcher extends cc.Component {

    @property({ type: cc.ProgressBar, displayName: "进度条" })
    progressBar: cc.ProgressBar = DummyProgressBar;

    @property({ type: cc.Label, displayName: "进度展示文本" })
    progressLabel: cc.Label = DummyLabel;

    @property({ type: cc.Node, displayName: "UI根结点" })
    uiRootNode: cc.Node = DummyNode;

    @property({ type: cc.Node, displayName: "场景最上层弱提示根结点" })
    toastParentNode: cc.Node = DummyNode;

    @property({ type: cc.Node, displayName: "加载界面节点" })
    loadingNode: cc.Node = DummyNode;

    @property({ type: cc.Node, displayName: "加载界面人物图" })
    loadingRoleNode: cc.Node = DummyNode;

    @property({ type: cc.Node })
    VerbRoot: cc.Node = DummyNode;

    @property({ tooltip: "是否加载导量UI" })
    isLoadGameCenter: boolean = false;

    @property({ type: cc.Label, displayName: "玩家ID文本" })
    userIdLabel: cc.Label = DummyLabel;

    @property({ type: cc.Node, displayName: "热更节点" })
    hotUpdateNode: cc.Node = DummyNode;

    @property(cc.Sprite)
    bgSpr: cc.Sprite = DummySprite;

    loginCount: number = 0;
    private _gameCenterViewNode: cc.Node = DummyNode;
    private _disposable: CompositeDisposable = new CompositeDisposable;

    async onLoad() {
        this.screenAdapter();
        if (cc.sys.isNative) {
            this._disposable.add(EventCenter.GameStart.on(this.onGameStart));
            let hotNode = await ResUtils.createWithPrefab('prefab/HotUpdate');
            hotNode.parent = this.hotUpdateNode;
        }

        this.scheduleOnce(() => {
            this.preloadView();
            this.preloadDir();
        });
        //关闭fps展示
        cc.debug.setDisplayStats(GameConfig.showFPS);
        /**关闭多点触摸 特效层将不能使用 */
        cc.macro.ENABLE_MULTI_TOUCH = false;
        this.fixScreenSize();
        this.scheduleOnce(async () => {
            try {
                let node = await ResUtils.createWithPrefab('prefab/ui/VerbView');
                node.parent = this.VerbRoot;
            } catch (error) {
                console.error(error);
            }
            if (!this.isLoadGameCenter) return;
            //加载矩阵导量UI
            try {
                this._disposable.add(EventCenter.SHOW_GAME_CENTER_LIST_VIEW.on(this.onShowGameCenterListView));
                let gameCenterMomentItem = await ResUtils.loadRes('prefab/cooperation/GameCenterMomentItem', cc.Prefab);
                CCGameCenterNodeFactory.getInstance().registerMomentPrefab(gameCenterMomentItem);
                let gameCenterBtn = await ResUtils.loadRes('prefab/cooperation/GameCenterBtn', cc.Prefab);
                let gameCenterView = await ResUtils.loadRes('prefab/cooperation/GameCenterView', cc.Prefab);
                let cooperationItem = await ResUtils.loadRes('prefab/cooperation/CooperationItem', cc.Prefab);
                let cCGameCenterComponent = this.node.addComponent(CCGameCenterComponent);
                cCGameCenterComponent.gameCenterBtnPrefab = gameCenterBtn;
                cCGameCenterComponent.gameCenterViewPrefab = gameCenterView;
                cCGameCenterComponent.gameCenterItemPrefab = cooperationItem;
                cCGameCenterComponent.gameCenterMomentPrefab = gameCenterMomentItem;
                cCGameCenterComponent.gameCenterParentNode = this.node;
                cCGameCenterComponent.appID = "wx7a067b995e670485";
                cCGameCenterComponent.gameID = "yybs";
                cCGameCenterComponent.gameChannel = "wechat";
                cCGameCenterComponent.isRelease = !GameConfig.debug;

                cCGameCenterComponent.init();
            } catch (error) {
                console.error(error);
            }
        });
        CustomerServiceDataCenter.getInstance().init();
        ResUtils.loadRes("audio/bgm/bayinhe", cc.AudioClip);
        ResUtils.loadRes("audio/bgm/wanshengj", cc.AudioClip);
    }

    /**创建prefab对应的节点 */
    createNode(gameCenterViewPrefab: cc.Prefab) {
        if (!gameCenterViewPrefab) {
            cc.error("gameCenterViewPrefab is not set , please check it over");
        } else {
            this._gameCenterViewNode = cc.instantiate(gameCenterViewPrefab);
        }
        let parentNode: cc.Node = cc.director.getScene();
        this._gameCenterViewNode.parent = parentNode;
        this._gameCenterViewNode.position = cc.v3(cc.winSize.width / 2, cc.winSize.height / 2, 0);
    }
    /**控制游戏列表是否展示 */
    onShowGameCenterListView = (isShow: boolean) => {
        if (!this._gameCenterViewNode) {
            return;
        }
        this._gameCenterViewNode.active = isShow;
    }
    fixScreenSize() {
        // let comp = this.loadingRoleNode.getComponent(PortraitFixComponent);
        // if (comp) {
        //     comp.fixScreenSize(false);
        // }
        let sf = this.bgSpr.spriteFrame;
        this.node.getComponent(cc.Widget).updateAlignment();
        let sizeSF = sf.getOriginalSize();
        let nodeSize = cc.size(this.node.width, this.node.height);
        let scaleTemp = 1;
        let scaleX = nodeSize.width / sizeSF.width;
        let scaleY = nodeSize.height / sizeSF.height;
        scaleTemp = Math.max(scaleX, scaleY);
        this.bgSpr.node.scale = scaleTemp;
    }

    preloadView() {
        // let viewList: string[] = [
        //     'prefab/ui/MainView',
        //     'prefab/ui/MessageView',
        //     'prefab/ui/message/MessageEntryItem',
        //     'prefab/ui/BedroomView',
        //     'prefab/ui/discover/SettingView'
        // ]
        let viewList: string[] = [
            'prefab/ui/MainView',
            'prefab/ui/MessageView',
            'prefab/ui/message/MessageEntryItem'
        ]
        cc.resources.preload(viewList, (error: Error, items: any[]) => {
        });
    }

    preloadDir() {
        cc.resources.preloadDir('plots');//剧情数据
        cc.resources.preloadDir('userdata/language');//语言配置
        cc.resources.preloadDir('config');//剧情配置
        // cc.resources.preloadDir('textures/items');
    }

    screenAdapter() {
        let winSize = cc.winSize;
        if (winSize.width / winSize.height > 720 / 1280) {
            let canvas = this.node.getComponent(cc.Canvas);
            canvas.fitWidth = true;
            canvas.fitHeight = true;
        }
    }

    start() {
        if (!cc.sys.isNative)
            this.initializeGame();
    }

    onGameStart = () => {
        this.initializeGame();
    }

    async initializeGame() {
        AudioManager.init("audio/bgm/", "audio/effect/", "audio/voice/");
        while (true) {
            try {
                await UIManager.init(this.uiRootNode!, this.toastParentNode!);
                break;
            } catch (e) {
                console.error(e);
            }
        }

        AnimationUtils.animateProgress(this.progressBar!, 0.2);
        let ret = false;
        let tryCount = 0;
        while (!ret && tryCount < 3) {
            tryCount++;
            ret = await SDK.init();
            // initExchangeCode();
        }
        if (!ret) {
            UIManager.showToast("SDK init failed. sdk初始化失败");
            return;
        }
        AnimationUtils.animateProgress(this.progressBar, 0.4, 1, this.progressLabel);
        await this.loginGame();
    }

    lateInit = async () => {
        let mainViewPromise = UIManager.pushPresenter(MainViewPresenter, undefined);
        AnimationUtils.animateProgress(this.progressBar, 0.6, 1, this.progressLabel);
        if (CC_DEV) {
            globalThis['PlotManager'] = PlotManager;
            globalThis['GameRecord'] = GameRecord;
            let ConfigManager = require('simba-config-manager')
            globalThis['ConfigManager'] = ConfigManager;
        }
        await initAVG();
        //解决清档
        await this.dealEmptyRecord();
        if (GameConfig.EMPTY_RECORD_WHEN_LOGIN) {
            PlotManager.stop();
            await GameRecord.emptyRecords();
        }
        AnimationUtils.animateProgress(this.progressBar, 0.8, 1, this.progressLabel);
        await PlotManager.start(0, false);
        AnimationUtils.animateProgress(this.progressBar, 0.9, 1, this.progressLabel);
        await initExchangeCode();
        // init game data
        await GameModelManager.init((value: number) => {
            AnimationUtils.animateProgress(this.progressBar, value, 1, this.progressLabel);
        });
        GameDotMgr.getInstance().dotLoading(LoadingState.LoadingStart);
        AnimationUtils.animateProgress(this.progressBar, 0.95, 1, this.progressLabel);
        GameDotMgr.getInstance().dotLoading(LoadingState.LoadingEnd);
        (await mainViewPromise).start();
        AnimationUtils.animateProgress(this.progressBar, 1.0, 1, this.progressLabel);
        // GameDotMgr.getInstance().dotLoading(LoadingState.EnterLobby);
        this.loadingNode.active = false;
        //检查是否解锁手表次留番外
        UnlockSpecialPlotEventManager.getInstance().nextDayUnlockedSpecialPlot(4);
    }

    loginGame = async () => {
        return new Promise<void>(async (resolve, reject) => {
            this.loginCount++;
            try {
                let ret = await SDK.login();
                if (ret) {
                    this.userIdLabel.string = ret.playerId;
                    await this.lateInit();
                    resolve();
                }
            } catch (error) {
                if (this.loginCount > 3) {
                    this.showLoginFailed();
                    reject(new Error("登录失败"));
                } else if (error == "timeout") {
                    this.loginGame();
                }
            }
        });
    }

    showLoginFailed() {
        let temp: AlertDialogViewProps =
        {
            dataptr: {},
            titlecontent: "网络错误",
            content: "是否重新连接?",
            ishasad: false,
            istwobtn: true,
            adconfig: "",
            hasBanner: false,
            callback: (type, ret) => {
                if (ret) {
                    this.loginCount = 0;
                    this.loginGame();
                } else {
                    cc.director.end();
                }
            }
        };
        UIManager.pushPresenter(AlertDialogViewPresenter, temp);
    }

    async dealEmptyRecord() {
        /**此次执行清档操作的版本号 */
        let optionV = "1.0.2";
        /**需要清档的玩家注册版本号列表 */
        let needEmptyRegVersionArr: string[] = ["1.0.0", "1.0.1"];
        let emptyVersionRecordKey = "empty_record_versions";
        let needEmpty: boolean = this.checkIsNeedEmptyRecord(optionV, emptyVersionRecordKey, needEmptyRegVersionArr);
        console.log("是否需要清档操作:", needEmpty);
        if (needEmpty) {
            await GameRecord.emptyRecords();
            GameRecord.globalVariables[emptyVersionRecordKey] = optionV;
            GameRecord.saveRecord();
        }
    }

    checkIsNeedEmptyRecord(optionV: string, emptyVersionRecordKey: string, needEmptyRegVersionArr: string[]): boolean {
        let empty = false;
        let regV = GameRecord.globalVariables["register_version"] as string;
        //不存在或者当前注册版本不在需要清档的版本内容中,则直接返回不需要清档
        if (!regV || needEmptyRegVersionArr.findIndex((v) => v == regV) === (-1)) {
            return false;
        }

        let emptyRecordVersionString: string = GameRecord.globalVariables[emptyVersionRecordKey] as string;
        if (!emptyRecordVersionString || "" === emptyRecordVersionString.trim()) {
            return true;
        }
        empty = emptyRecordVersionString != optionV;
        return empty;
    }
}