游戏服务器设计-脚本系统设计

游戏项目中都会遇到以下的一些需求:

1.从内存里查询数据

2.修复个别玩家的异常数据

如何能最快捷的方式去实现,目前有两种脚本引擎可以选择:beanshell 和groovy.

经过比较得出如下结论:

 BeanShellGroovy
官网http://www.beanShell.org/http://www.groovy-lang.org/
介绍用Java写成的,一个小型的、免费的、可以下载的、嵌入式的Java源代码解释器,具有对象脚本语言特性,非常精简的解释器jar文件大小为175k是一种基于JVM(Java虚拟机)的敏捷开发语言,它结合了Python、Ruby和Smalltalk的许多强大的特性,Groovy 代码能够与 Java 代码很好地结合,也能用于扩展现有代码。由于其运行在 JVM 上的特性,Groovy也可以使用其他非Java语言编写的库。
执行原理使用Java反射API以提供Java语句和表达式 的实时解释执行;可以透明地访问任何Java对象和API。动态地加载一个脚本并执行它的行为。GroovyClassLoader是一个定制的类装载器,负责解释加载Java类中用到的Groovy类
直接访问私有方法可以可以
泛型不支持支持
评价专注,小而强大,小强沉睡的巨人
脚本量除了目标脚本外面要套一层类的外壳
语言友好性纯java语言纯java语言
后遗症没有Groovy每执行一次脚本,都会生成一个脚本对应的class对象存放metaspace,
但可以通过每次new GroovyClassLoader或者调用GroovyClassLoader.clearCache()去化解
性能非常快GroovyShell执行groovy语言,静态编译情况下速度还可以,
GroovyClassLoader 要相对Beanshell要慢一些
IDE对引擎的支持更友好,高亮,语法智能插入
社区不大活跃,目前在谋划beanshell3 

其中脚本量这块,为了做比较,脚本实现同样的功能, 举个栗子:

BeanShell使用:

script.bsh脚本

import io.gamioo.script.ScriptManager;

for(int i=0;i<10;i++){
    String content="hello world";
    ScriptManager.getInstance().log(content);
}

beanshell执行脚本:

public void init() throws ServiceException {
        logger.info("开始初始化Java Script引擎.");
        // 让所有的非public方法和字段可供调用
        try {
            Capabilities.setAccessibility(true);
        } catch (Unavailable e) {
            throw new ServiceException(e);
        }
        logger.info("成功初始化Java Script引擎.");
    }


    public String execScriptByBeanshell(String script) {
        try {
            Object output = interpreter.eval(script);
            return output == null ? "OK" : output.toString();
        } catch (TargetError e) {
            Throwable able = e.getTarget();
            logger.error(e.getMessage(), e);
            return able.toString();
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            return e.getMessage();
        }
    }

Groovy 使用:

script.groovy脚本:

package io.gamioo.script

public class GroovyScriptExecutor2 implements GroovyScript {

    @Override
    public String execute() {
        for(int i=0;i<10;i++){
            String content="hello world";
            ScriptManager.getInstance().log("Hello ketty");
        }

        return "OK";
    }
}

groovy执行脚本:


/**
 * Groovy脚本接口.

 */
public interface GroovyScript {

    /**
     * 执行逻辑.
     *
     * @return 执行结果
     */
    public String execute();
}
  
  /**
     * 执行一段Groovy脚本.
     *
     * @param script Groovy脚本
     * @return 执行结果
     */
    public String executeByGroovy(String script) {
        try (GroovyClassLoader loader = new GroovyClassLoader()) {
            //	loader.clearCache();
            return ((GroovyScript) loader.parseClass(script).newInstance()).execute();
        } catch (Exception e) {
            logger.error("groovy script execute exception.{}", e);
            return ExceptionUtils.toString(e);
        }
    }

测试类:

@DisplayName("脚本测试")
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class ScriptManagerTest {
    private static final Logger logger = LogManager.getLogger(ScriptManagerTest.class);
    private  static ScriptManager scriptManager;

    @BeforeAll
    public  static void beforeAll() throws Exception {
        scriptManager=ScriptManager.getInstance();
        scriptManager.init();

    }

    @Test
    @DisplayName("BeanShell脚本测试")
    public void testBeanShell() throws Exception {

        File file= FileUtils.getFile("script.bsh");
        String content=FileUtils.readFileToString(file);
        scriptManager.execScriptByBeanshell(content);

    }

    @Test
    @DisplayName("Groovy脚本测试")
    public void testGroovyClassLoader() throws Exception {
        File file=FileUtils.getFile("script.groovy");
        String content=FileUtils.readFileToString(file);
        scriptManager.executeByGroovy(content);

    }
}

 

后台脚本系统UI设计

参考:

java groovy集成_Groovy与Java集成常见的坑

Groovy or Beanshell 性能比较

 

流子 CSDN认证博客专家 游戏程序员
关注游戏服务器架构及优化,监控预警,智能运维,数据统计分析等,对IO,MOBA,FPS,全球同服方面很感兴趣,希望能和兴趣相投的人一起搞点事。
https://github.com/jiangguilong2000/gamioo
已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 技术黑板 设计师:CSDN官方博客 返回首页
实付 19.90元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值