聚爆Implosion - 画面没有如此酷炫 #iOS #Android

123123123123123.jpg

YARN DistributedShell源码分析与改

YARN版本:2.6.0


转载请讲明出处:http://www.cnblogs.com/BYRans/

要你对雷亚玩(Rayark
Games)这一个黑龙江玩支付公司不熟谙的话,那么相信您对「Cytus」和「Deemo」那有限独有口皆碑的精品游戏定会所有耳闻
~
雷亚产品的娱乐不论一致休给于及精品的价签,前几日设介绍的「Implosion聚爆」也未例外,而它们呢全然称得及精品手游这同一名称。尽管从前产品的戏都是音游,这是率先涂鸦尝试
ARPG
类角色扮演动作游戏,但该作表现可谓相当好,体验后被人会合看就不仅是如出一辙暂缓单机游戏,而是可以将它们当一部独立的科幻巨制电影。

1 概述

Hadoop
YARN项目从带一个异常简单的应用程序编程实例–DistributedShell。DistributedShell是一个构建以YARN之上的non-MapReduce应用示范。它的要功能是于Hadoop集群中之大半只节点,并行执行用户提供的shell命令或shell脚本(将用户提交的一模一样拧shell命令或者一个shell脚本,由ApplicationMaster控制,分配到不同之container中实施)。

02.jpg

2 YARN DistributedShell请勿克满意当下要求

— 游戏开首界面 —

2.1 效率需求

自我所插足的花色经过融合Hive、MapReduce、斯帕克(Spark)、Kafka等死数额开源组件,搭建了一个数目解析平台。
平台要新增一个效益:

  • 当聚集众多被甄选一个节点,执行用户提交的jar包。
  • 该意义要同平台早已部分因Hive、MR、Spark实现的事情与YARN相融合。
  • 简单,经分析以及调研,我们得基于YARN的DistributedShell实现该效用。

拖欠意义要实现:

  • 单机执行用户自己交到的jar包
  • 用户提交的jar包会有外jar包的倚重性
  • 用户提交的jar包只可以挑一个节点运行
  • 用户提交的jar包需要发出缓存数据的目录

03.jpg

2.2 YARN DistributedShell对急需的支撑状况

YARN的DistributedShell功能为:

  • 支撑实施用户提供的shell命令或脚本
  • 推行节点数可以经过参数num_containers设置,默认值为1
  • 不援助jar包的施行
  • 再也无协理因包的交
  • 未补助jar包缓存目录的安

玩背景设定也异星生物入侵、地球被损毁、人类不得不背井离乡逃至宇宙殖民世界,此时敢于也该上了!主人公杰克(Jack)通过「人机精神连结」的科幻机器人还回满目疮痍的地时,却不料发现地上具有众多未解的谜,比如使以争持异星物种
XADA
的又发现地毁灭的故,精晓人类存亡的基本点。游戏一样起来,主人公杰克(杰克)的叔伯留下了平等段子话也随后的剧情发展埋下伏笔,让故事充满重重悬念。游戏之剧情设置特别充沛,玩家体验的以会逐年精通之世界之一体化面貌,一些指导性对话吗汇合被游戏下找到有些晤潜移默化及今后的剧情发展还结果的蛛丝马迹的头脑。

2.3 需要针对YARN DistributedShell举办的修改

  • 追加辅助实施jar包效能
  • 增添补助缓存目录设置效用
  • 删除执行节点数设置效用,不允许用户设置进行节点数,将执节点数保证值为1

04.jpg

3 YARN DistributedShell源码获取

YARN DistributedShell源码可以在GitHub上apache/hadoop获取,hadoop
repository中DistributedShell的源代码路径也:
hadoop/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-applications-distributedshell/src/main/java/org/apache/hadoop/yarn/applications/distributedshell/
这边修改的是2.6.0版本源码。

— 游戏界面 —

4 YARN DistributedShell源码分析及修改

YARN DistributedShell包含4个java Class:

DistributedShell
    ├── Client.java
    ├── ApplicationMaster.java
    ├── DSConstants.java
    ├── Log4jPropertyHelper.java
  • Client:客户端提交application
  • ApplicationMaster:注册AM,申请分配container,启动container
  • DSConstants:Client类和ApplicationMaster类中之常量定义
  • Log4jPropertyHelper:加载Log4j配置

05.jpg

4.1 Client类

玩耍画面很华,细节及的迷你打磨带为玩家绝佳的视觉感受,起首分外酷炫的
CG
动画就生吸人眼球堪比动作大片。而转入游戏本身,手绘和写实风的距离也蛮明晃晃,游戏音效由格莱美奖得主录音师
约翰(John) Kurlander
亲自操刀制作,他从前已经负责过《指环王》和《暗黑破坏神3》的乐打造。体验过程被得感受及游戏音乐异常大方,各样打斗、跑动、开门、拾取道具等音效至极就了,整个经过行云流水毫不拖泥带水,玩起来酣畅淋漓,另一方面为弥补了动作游戏中出于触摸操作造成打击感体验不佳的不满。

4.1.1 Client源码逻辑

Client类是DistributedShell应用提交至YARN的客户端。Client将启动application
master,然后application
master启动多独containers用于运行shell命令或脚本。Client运行逻辑吗:

  1. 动ApplicationClientProtocol协议连接ResourceManager(也叫ApplicationsMaster或ASM),获取一个初的ApplicationId。(ApplicationClientProtocol提供给Client一个取得集群信息的方法)
  2. 每当一个job提交过程中,Client首先创立一个ApplicationSubmissionContext。ApplicationSubmissionContext定义了application的详细信息,例如:ApplicationId、application
    name、application分配的优先级、application分配的班。此外,ApplicationSubmissionContext还定义了一个Container,该Container用于启动ApplicationMaster。
  3. 在ContainerLaunchContext中需先导化启动ApplicationMaster的资源:
    • 运行ApplicationMaster的container的资源
    • jars(例:AppMaster.jar)、配置文件(例:log4j.properties)
    • 运转条件(例:hadoop特定的类路径、java classpath)
    • 启动ApplicationMaster的命令
  4. Client使用ApplicationSubmissionContext提交application到ResourceManager,并透过以周期为ResourceManager请求ApplicationReport,完成对applicatoin的督察。
  5. 而application运行时刻跨timeout的限定(默认为600000飞秒,可透过-timeout举行安装),client将发送KillApplicationRequest到ResourceManager,将application杀死。

现实代码如下(基于YARN2.6.0):

  • Cilent的入口main方法:

    public static void main(String[] args) {

        boolean result = false;
        try {
            DshellClient client = new DshellClient();
            LOG.info("Initializing Client");
            try {
                boolean doRun = client.init(args);
                if (!doRun) {
                    System.exit(0);
                }
            } catch (IllegalArgumentException e) {
                System.err.println(e.getLocalizedMessage());
                client.printUsage();
                System.exit(-1);
            }
            result = client.run();
        } catch (Throwable t) {
            LOG.fatal("Error running Client", t);
            System.exit(1);
        }
        if (result) {
            LOG.info("Application completed successfully");
            System.exit(0);
        }
        LOG.error("Application failed to complete successfully");
        System.exit(2);
    }
    

main方法:

  • 输入参数为用户CLI的执行命令,例如:hadoop jar hadoop-yarn-applications-distributedshell-2.0.5-alpha.jar org.apache.hadoop.yarn.applications.distributedshell.Client -jar hadoop-yarn-applications-distributedshell-2.0.5-alpha.jar -shell_command '/bin/date' -num_containers 10,该令提交的天职为:启动10个container,每个都施行date命令。
  • main方法将运行init方法,如若init方法再次来到true则运行run方法。
  • init方法分析用户提交的命令,解析用户命令中之参数值。
  • run方法将做到Client源码逻辑中讲述的功效。

06.jpg

4.1.2 对Client源码的改

以原有YARN DistributedShell的根基及做的改如下:

  • 在CLI为用户扩大了container_filescontainer_archives点滴个参数
    • container_files点名用户若实践之jar包的负包,多独依靠包以逗号分隔
    • container_archives点名用户执行的jar包的休息存目录,六只目录为逗号分隔
  • 删除num_containers参数
    • 莫允用户设置container的个数,使用默认值1

本着Client源码修改如下:

  • 变量

    • 充实变量用于保存container_filescontainer_archives零星个参数的价值

    // 扩充有限只变量,保存container_files、container_archives的参数值↓↓↓↓↓↓↓
    private String[] containerJarPaths = new String[0];
    private String[] containerArchivePaths = new String[0];
    // ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑

  • Client构造方法

    • 删除num_containers参数的初试化,扩展container_filescontainer_archives星星独参数
    • 改构造方法的ApplicationMaster类

    // 删除num_containers项,不同意用户安装containers个数,containers个数默认为1 ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
    //opts.addOption(“num_containers”, true, “No. of containers on which the shell command needs to be executed”);
    // ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
    // 添加container_files、container_archives的描述↓↓↓↓↓↓↓↓↓↓↓↓↓↓
    this.opts.addOption(“container_files”, true,”The files that containers will run . Separated by comma”);
    this.opts.addOption(“container_archives”, true,”The archives that containers will unzip. Separated by comma”);
    // ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑

    public DshellClient(Configuration conf) throws Exception {

        // 修改构造方法的ApplicationMaster类↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
        this("org.apache.hadoop.yarn.applications.distributedshell.DshellApplicationMaster",conf);
        // ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
    }
    
  • init方法

    • 增加container_filescontainer_archives点滴只参数的辨析

    // 伊始化选项container_files、container_archives↓↓↓↓↓↓↓
    this.opts.addOption(“container_files”, true,”The files that containers will run . Separated by comma”);
    this.opts.addOption(“container_archives”, true,”The archives that containers will unzip. Separated by comma”);
    // ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑

  • run方法

    • 上传container_filescontainer_archives有数单参数指定的指包跟缓存目录及HDFS

      // 上传container_files指定的jar包到HDFS ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
      if (this.containerJarPaths.length != 0)
      for (int i = 0; i < this.containerJarPaths.length; i++) {

      String hdfsJarLocation = "";
      String[] jarNameSplit = this.containerJarPaths[i].split("/");
      String jarName = jarNameSplit[(jarNameSplit.length - 1)];
      
      long hdfsJarLen = 0L;
      long hdfsJarTimestamp = 0L;
      if (!this.containerJarPaths[i].isEmpty()) {
          Path jarSrc = new Path(this.containerJarPaths[i]);
          String jarPathSuffix = this.appName + "/" + appId.toString() +
                  "/" + jarName;
          Path jarDst = new Path(fs.getHomeDirectory(), jarPathSuffix);
          fs.copyFromLocalFile(false, true, jarSrc, jarDst);
          hdfsJarLocation = jarDst.toUri().toString();
          FileStatus jarFileStatus = fs.getFileStatus(jarDst);
          hdfsJarLen = jarFileStatus.getLen();
          hdfsJarTimestamp = jarFileStatus.getModificationTime();
          env.put(DshellDSConstants.DISTRIBUTEDJARLOCATION + i,
                  hdfsJarLocation);
          env.put(DshellDSConstants.DISTRIBUTEDJARTIMESTAMP + i,
                  Long.toString(hdfsJarTimestamp));
          env.put(DshellDSConstants.DISTRIBUTEDJARLEN + i,
                  Long.toString(hdfsJarLen));
      }
      

      }
      // ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
      // 上传container_archives到HDFS↓↓↓↓↓↓↓↓↓↓↓↓↓↓
      long hdfsArchiveLen;
      String archivePathSuffix;
      Path archiveDst;
      FileStatus archiveFileStatus;
      if (this.containerArchivePaths.length != 0) {
      for (int i = 0; i < this.containerArchivePaths.length; i++) {

      String hdfsArchiveLocation = "";
      String[] archiveNameSplit = this.containerArchivePaths[i].split("/");
      String archiveName = archiveNameSplit[(archiveNameSplit.length - 1)];
      hdfsArchiveLen = 0L;
      long hdfsArchiveTimestamp = 0L;
      if (!this.containerArchivePaths[i].isEmpty()) {
          Path archiveSrc = new Path(this.containerArchivePaths[i]);
          archivePathSuffix = this.appName + "/" + appId.toString() +
                  "/" + archiveName;
          archiveDst = new Path(fs.getHomeDirectory(),
                  archivePathSuffix);
          fs.copyFromLocalFile(false, true, archiveSrc, archiveDst);
          hdfsArchiveLocation = archiveDst.toUri().toString();
          archiveFileStatus = fs.getFileStatus(archiveDst);
          hdfsArchiveLen = archiveFileStatus.getLen();
          hdfsArchiveTimestamp = archiveFileStatus
                  .getModificationTime();
          env.put(DshellDSConstants.DISTRIBUTEDARCHIVELOCATION + i,
                  hdfsArchiveLocation);
          env.put(DshellDSConstants.DISTRIBUTEDARCHIVETIMESTAMP + i,
                  Long.toString(hdfsArchiveTimestamp));
          env.put(DshellDSConstants.DISTRIBUTEDARCHIVELEN + i,
                  Long.toString(hdfsArchiveLen));
      }
      

      }
      }
      // ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑

以及一般的 ARPG
格斗一样,聚爆采用了卡形式有助于剧情,按钮布局也大致相同,对付许多异星生物只需要点击即会杀掉,不过要剧情发展与特世界观的建构而于它分一般的
ARPG。每一样关卡中还会见发新人物或新物种登场,剧情为跟着推动,所以说在聚爆的社会风气被无特是就的打打杀杀,要时时刻刻探索意识此世界藏的秘。对付敌人也毫不简单的点点点,由于各一样节节都起重型的
Boss
型仇敌,所以当合格的下用玩家用不同之军械配合来负它们,这为受游玩策略性大大提升乐趣至极。

4.2 ApplicationMaster类

07.jpg

4.2.1 ApplicationMaster源码逻辑

一个ApplicationMaster将当起步一个或过个container,在container上实施shell命令或脚本。ApplicationMaster运行逻辑吗:

  1. ResourceManager启动一个container用于运行ApplicationMaster。
  2. ApplicationMaster连接ResourceManager,向ResourceManager注册自己。
    • 望ResourceManager注册的音来:
      • ApplicationMaster的ip:port
      • ApplicationMaster所在主机的hostname
      • ApplicationMaster的tracking url。客户端可据此tracking
        url来跟任务之状态与历史记录。
    • 需要注意的凡:在DistributedShell中,不需新注册tracking url和
      appMasterHost:appMasterRpcPort,只需要装hostname。
  3. ApplicationMaster会遵照设定的光阴间隔为ResourceManager发送心跳。ResourceManager的ApplicationMasterService(Service)每一次收到ApplicationMaster的私心跳音讯后,会又以AMLivelinessMonitor更新其近日平浅发送心跳的年月。
  4. ApplicationMaster通过ContainerRequest方法向ResourceManager发送请求,申请相应数额的container。在发送申请container请求前,需要发轫化Request,需要伊始化的参数有:
    • Priority:请求的先期级
    • capability:当前支撑CPU和Memory
    • nodes:申请之container所在的host(假设不需要指定,则设为null)
    • racks:申请的container所在的rack(若是未待指定,则设为null)
  5. ResourceManager重返ApplicationMaster的提请之containers音信,按照container的状态-containerStatus,更新就报名成功和还免申请之container数目。
  6. 报名成功的container,ApplicationMaster则透过ContainerLaunchContext伊始化container的起步信息。起始化container后启动container。需要开始化的信发:
    • Container id
    • 实践资源(Shell脚本或指令、处理的数)
    • 运作环境
    • 运转命令
  7. container运行期间,ApplicationMaster对container举办监控。
  8. job运行了,ApplicationMaster发送FinishApplicationMasterRequest请求让ResourceManager,完成ApplicationMaster的撤销。

现实代码如下(基于YARN2.6.0):

  • ApplicationMaster的入口main方法:

    public static void main(String[] args) {

       boolean result = false;
       try {
           DshellApplicationMaster appMaster = new DshellApplicationMaster();
           LOG.info("Initializing ApplicationMaster");
           boolean doRun = appMaster.init(args);
           if (!doRun) {
               System.exit(0);
           }
           appMaster.run();
           result = appMaster.finish();
       } catch (Throwable t) {
           LOG.fatal("Error running ApplicationMaster", t);
           LogManager.shutdown();
           ExitUtil.terminate(1, t);
       }
       if (result) {
           LOG.info("Application Master completed successfully. exiting");
           System.exit(0);
       } else {
           LOG.info("Application Master failed. exiting");
           System.exit(2);
       }
    

    }

main方法:

  • 输入参数为Client提交的执行命令。
  • init方法好对执行命令的剖析,获取执行命令中参数指定的价值。
  • run方法好ApplicationMaster的启动、注册、containers的申请、分配、监控等功能的启航。
    • run方法吃树立了与ResourceManager通信的Handle-AMRMClientAsync,其中的CallbackHandler是由于RMCallbackHandler类实现的。
      • RMCallbackHandler类中落实了containers的提请、分配等艺术。
      • containers的分配方法onContainersAllocated中经LaunchContainerRunnable类中run方法成功container的启动。
  • finish方法就container的住、ApplicationMaster的撤除。

聚爆售价 60
元,可能会师受多数玩家当贵,可是同涂鸦打断全凭外选购相信会叫玩家有重新通畅的嬉戏体验。游戏被虽然无论是外购不过出提拔系统:ARK,不能用金钱拿到只可以借助你的戏操作来拿到,这为大大增加了一日游之新鲜感,使用了不同的政策情势得到的
ARK
也会具备转变,有时候这为汇合招致玩家重玩关卡的心情。而到位及后的徽章成效为要命首要,只有徽章数量达一定之后新机器人装甲才会开,获取更强大的
ARK 升级部件几带队也会合跟着大增。

4.2.2 对ApplicationMaster源码的改

于原有YARN DistributedShell的基础及召开的改动如下:

  • 每当ApplicationMaster初试化时,扩展对container_filescontainer_archives区区只参数指定值的支撑。即:起头化container_filescontainer_archives指定的周转资源以HDFS上的消息。
  • 在container运行时,从HDFS上加载container_filescontainer_archives指定的资源。

对ApplicationMaster源码修改如下:

  • 变量

    • 增添变量,用于保存container_filescontainer_archives指定的运作资源在HDFS上的音信。

    // 增加container_files、container_archives选项值变量 ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
    private ArrayList scistorJars = new ArrayList();
    private ArrayList scistorArchives = new ArrayList();
    // ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑

  • ApplicationMaster的init方法

    • 初始化container_filescontainer_archives有限独参数指定值信息。

    // 尽历envs,把拥有的jars、archivers的HDFS路径,时间穿,LEN全体封存至jarPaths对象往往组被 ↓↓↓↓↓↓↓↓↓↓
    for (String key : envs.keySet()) {

    if (key.contains(DshellDSConstants.DISTRIBUTEDJARLOCATION)) {
        DshellFile scistorJar = new DshellFile();
        scistorJar.setJarPath((String) envs.get(key));
        String num = key
                .split(DshellDSConstants.DISTRIBUTEDJARLOCATION)[1];
        scistorJar.setTimestamp(Long.valueOf(Long.parseLong(
                (String) envs
                        .get(DshellDSConstants.DISTRIBUTEDJARTIMESTAMP + num))));
        scistorJar.setSize(Long.valueOf(Long.parseLong(
                (String) envs
                        .get(DshellDSConstants.DISTRIBUTEDJARLEN + num))));
        this.scistorJars.add(scistorJar);
    }
    

    }

    for (String key : envs.keySet()) {

    if (key.contains(DshellDSConstants.DISTRIBUTEDARCHIVELOCATION)) {
        DshellArchive scistorArchive = new DshellArchive();
        scistorArchive.setArchivePath((String) envs.get(key));
        String num = key
                .split(DshellDSConstants.DISTRIBUTEDARCHIVELOCATION)[1];
        scistorArchive.setTimestamp(Long.valueOf(Long.parseLong(
                (String) envs
                        .get(DshellDSConstants.DISTRIBUTEDARCHIVETIMESTAMP +
                                num))));
        scistorArchive.setSize(Long.valueOf(Long.parseLong(
                (String) envs
                        .get(DshellDSConstants.DISTRIBUTEDARCHIVELEN + num))));
        this.scistorArchives.add(scistorArchive);
    }
    

    }
    // ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑

  • LaunchContainerRunnable的run方法(container线程的run方法)

    • 从HDFS上加载container_filescontainer_archives指定的资源。

    // 将HDFS中之jar、archive加载到container的LocalResources,也就是自从HDFS分发到container节点的历程 ↓↓↓↓↓↓↓↓↓↓↓↓↓
    for (DshellFile perJar : DshellApplicationMaster.this.scistorJars) {

    LocalResource jarRsrc = (LocalResource) Records.newRecord(LocalResource.class);
    jarRsrc.setType(LocalResourceType.FILE);
    jarRsrc.setVisibility(LocalResourceVisibility.APPLICATION);
    try {
        jarRsrc.setResource(
                ConverterUtils.getYarnUrlFromURI(new URI(perJar.getJarPath()
                        .toString())));
    } catch (URISyntaxException e1) {
        DshellApplicationMaster.LOG.error("Error when trying to use JAR path specified in env, path=" +
                perJar.getJarPath(), e1);
        DshellApplicationMaster.this.numCompletedContainers.incrementAndGet();
        DshellApplicationMaster.this.numFailedContainers.incrementAndGet();
        return;
    }
    jarRsrc.setTimestamp(perJar.getTimestamp().longValue());
    jarRsrc.setSize(perJar.getSize().longValue());
    String[] tmp = perJar.getJarPath().split("/");
    localResources.put(tmp[(tmp.length - 1)], jarRsrc);
    

    }
    String[] tmp;
    for (DshellArchive perArchive : DshellApplicationMaster.this.scistorArchives) {

    LocalResource archiveRsrc =
            (LocalResource) Records.newRecord(LocalResource.class);
    archiveRsrc.setType(LocalResourceType.ARCHIVE);
    archiveRsrc.setVisibility(LocalResourceVisibility.APPLICATION);
    try {
        archiveRsrc.setResource(
                ConverterUtils.getYarnUrlFromURI(new URI(perArchive
                        .getArchivePath().toString())));
    } catch (URISyntaxException e1) {
        DshellApplicationMaster.LOG.error("Error when trying to use ARCHIVE path specified in env, path=" +
                        perArchive.getArchivePath(),
                e1);
        DshellApplicationMaster.this.numCompletedContainers.incrementAndGet();
        DshellApplicationMaster.this.numFailedContainers.incrementAndGet();
        return;
    }
    archiveRsrc.setTimestamp(perArchive.getTimestamp().longValue());
    archiveRsrc.setSize(perArchive.getSize().longValue());
    tmp = perArchive.getArchivePath().split("/");
    String[] tmptmp = tmp[(tmp.length - 1)].split("[.]");
    localResources.put(tmptmp[0], archiveRsrc);
    

    }
    // ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑

08.jpg

4.3 DSConstants类

DSConstants类中凡当Client和ApplicationMaster中之常量,对DSConstants类的改动也:扩张了container_files、container_archives相关常量。修改代码如下:

// 增加container_files、container_archives相关常量 ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
public static final String DISTRIBUTEDJARLOCATION = "DISTRIBUTEDJARLOCATION";
public static final String DISTRIBUTEDJARTIMESTAMP = "DISTRIBUTEDJARTIMESTAMP";
public static final String DISTRIBUTEDJARLEN = "DISTRIBUTEDJARLEN";

public static final String DISTRIBUTEDARCHIVELOCATION = "DISTRIBUTEDARCHIVELOCATION";
public static final String DISTRIBUTEDARCHIVETIMESTAMP = "DISTRIBUTEDARCHIVETIMESTAMP";
public static final String DISTRIBUTEDARCHIVELEN = "DISTRIBUTEDARCHIVELEN";
// ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑

眼前聚爆只出四独章的始末,玩起来为人一齐犹未老,可是相信这样「完整、深远、精致」的动作角色扮演游戏继续版本会延续优异。精致的镜头、完整的剧情,这款体验一级的
ARPG 大作,诚意推荐给诸位玩家。(Android 版为免费 +
内购格局,请到官方网站或 谷歌 Play 中免费得正版)

4.4 Log4jPropertyHelper类

本着Log4jPropertyHelper类无其它变更。

▎适用于 Samsung & surface 设备 iOS 6.0 及重新胜似版本,价格 60 元,大小为 1.31
GB;Android 设备 4.0 及重新胜似版本,大小为 1.1 GB、、

爱屁屁,取自 APP(application)谐音,专注让移动
APPS(应用/游戏)个性化评测,意在让你生活之各国一样龙跟怦然心动的过人格调应用相遇。更多特别应用推荐可活动官网:http://www.appnz.com/
关注微信公众号:爱屁屁(ID:AppKeji)不定时发放兑换码等有利于!

发表评论

电子邮件地址不会被公开。 必填项已用*标注