package com.huangzj.base.cmd;

import com.huangzj.cmd.gen.CmdRpcEnvelope;

/**
 * 解析CmdRpcEnvelope、查表、执行，三步并一行，Netty handler 里少写点重复代码。
 */
public final class CmdRpcDispatch {

    private CmdRpcDispatch() {
    }

    /**
     * 从原始字节起跳，适合 TCP 一帧读完再分发。
     */
    public static CmdRpcEnvelope dispatch(byte[] raw, GameCommandLookup lookup, CommandContext ctx) throws Exception {
        CmdRpcEnvelope in = CmdRpcEnvelope.parseFrom(raw);
        return dispatchEnvelope(in, lookup, ctx);
    }

    /**
     * 已经 parse 过CmdRpcEnvelope时用，避免重复解析；上下文里的 cross_ret 必须在这之前就算好。
     */
    public static CmdRpcEnvelope dispatchEnvelope(CmdRpcEnvelope in, GameCommandLookup lookup, CommandContext ctx) throws Exception {
        // lookup 按「来源已过滤后的表」解析，故同一 service/method 在区服/跨服可绑定不同实现类
        GameCommand cmd = lookup.resolve(in.getServiceId(), in.getMethodId());
        // 异常若直接抛出，由上层 Netty handler 记录并关连接；此处不吞异常
        return cmd.execute(ctx, in);
    }
}
