From 9b301eba25482e5d970d1a747be5a561f637c57f Mon Sep 17 00:00:00 2001
From: 18401019693 <https://gitee.com/xxkp/NEWPDLIVE.git>
Date: Tue, 12 Sep 2023 17:14:17 +0800
Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=9C=A8=E7=9B=B4=E6=92=AD?=
 =?UTF-8?q?=E9=97=B4=E5=86=85=E8=B7=B3=E8=BD=AC=E8=87=AA=E5=B7=B1=E7=9A=84?=
 =?UTF-8?q?=E7=9B=B4=E6=92=AD=E9=97=B4=E9=97=AE=E9=A2=98?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 common/build.gradle                           |   14 +-
 .../yunbao/common/sud/BaseGameViewModel.java  |  432 +++++
 .../common/sud/QuickStartGameViewModel.java   |  216 +++
 .../yunbao/common/sud/QuickStartUtils.java    |   30 +
 .../common/sud/decorator/SudFSMMGCache.java   |  151 ++
 .../sud/decorator/SudFSMMGDecorator.java      | 1009 +++++++++++
 .../sud/decorator/SudFSMMGListener.java       |  901 ++++++++++
 .../sud/decorator/SudFSTAPPDecorator.java     |  446 +++++
 .../common/sud/model/GameConfigModel.java     |  256 +++
 .../common/sud/model/GameViewInfoModel.java   |   44 +
 .../common/sud/state/MGStateResponse.java     |   18 +
 .../common/sud/state/SudMGPAPPState.java      | 1001 +++++++++++
 .../common/sud/state/SudMGPMGState.java       | 1509 +++++++++++++++++
 .../common/utils/ISudFSMStateHandleUtils.java |   26 +
 .../com/yunbao/common/utils/SudJsonUtils.java |   43 +
 config.gradle                                 |    4 +-
 16 files changed, 6094 insertions(+), 6 deletions(-)
 create mode 100644 common/src/main/java/com/yunbao/common/sud/BaseGameViewModel.java
 create mode 100644 common/src/main/java/com/yunbao/common/sud/QuickStartGameViewModel.java
 create mode 100644 common/src/main/java/com/yunbao/common/sud/QuickStartUtils.java
 create mode 100644 common/src/main/java/com/yunbao/common/sud/decorator/SudFSMMGCache.java
 create mode 100644 common/src/main/java/com/yunbao/common/sud/decorator/SudFSMMGDecorator.java
 create mode 100644 common/src/main/java/com/yunbao/common/sud/decorator/SudFSMMGListener.java
 create mode 100644 common/src/main/java/com/yunbao/common/sud/decorator/SudFSTAPPDecorator.java
 create mode 100644 common/src/main/java/com/yunbao/common/sud/model/GameConfigModel.java
 create mode 100644 common/src/main/java/com/yunbao/common/sud/model/GameViewInfoModel.java
 create mode 100644 common/src/main/java/com/yunbao/common/sud/state/MGStateResponse.java
 create mode 100644 common/src/main/java/com/yunbao/common/sud/state/SudMGPAPPState.java
 create mode 100644 common/src/main/java/com/yunbao/common/sud/state/SudMGPMGState.java
 create mode 100644 common/src/main/java/com/yunbao/common/utils/ISudFSMStateHandleUtils.java
 create mode 100644 common/src/main/java/com/yunbao/common/utils/SudJsonUtils.java

diff --git a/common/build.gradle b/common/build.gradle
index 40486453e..56dbc58bf 100644
--- a/common/build.gradle
+++ b/common/build.gradle
@@ -179,7 +179,7 @@ dependencies {
     implementation 'io.reactivex.rxjava2:rxandroid:2.1.1'
     api 'com.jakewharton.rxbinding3:rxbinding:3.1.0'
     //loading样式库
-    api  'com.wang.avi:library:2.1.3'
+    api 'com.wang.avi:library:2.1.3'
     api 'com.google.firebase:firebase-messaging:23.0.6'
     api 'com.google.firebase:firebase-analytics:21.1.0'
 //    api 'com.huawei.hms:push:4.0.2.300'
@@ -197,7 +197,13 @@ dependencies {
     //自定义圆角图片
     api 'com.makeramen:roundedimageview:2.3.0'
     // 友盟统计SDK
-    api  'com.umeng.umsdk:common:9.6.3'// 必选
-    api  'com.umeng.umsdk:asms:1.8.0'// 必选
-    api 'com.umeng.umsdk:uyumao:1.1.2' //高级运营分析功能依赖库,使用卸载分析、开启反作弊能力请务必集成,以免影响高级功能使用。common需搭配v9.6.3及以上版本,asms需搭配v1.7.0及以上版本。需更新隐私声明。
+    api 'com.umeng.umsdk:common:9.6.3'// 必选
+    api 'com.umeng.umsdk:asms:1.8.0'// 必选
+    api 'com.umeng.umsdk:uyumao:1.1.2'
+    //高级运营分析功能依赖库,使用卸载分析、开启反作弊能力请务必集成,以免影响高级功能使用。common需搭配v9.6.3及以上版本,asms需搭配v1.7.0及以上版本。需更新隐私声明。
+    // 标准版本SudMGP SDK
+    api 'tech.sud.mgp:SudMGP:1.3.3.1158'
+
+    // 多语言语音识别扩展库(可选)
+    api 'tech.sud.mgp:SudASR:1.3.3.1158'
 }
diff --git a/common/src/main/java/com/yunbao/common/sud/BaseGameViewModel.java b/common/src/main/java/com/yunbao/common/sud/BaseGameViewModel.java
new file mode 100644
index 000000000..2f2933601
--- /dev/null
+++ b/common/src/main/java/com/yunbao/common/sud/BaseGameViewModel.java
@@ -0,0 +1,432 @@
+package com.yunbao.common.sud;
+
+import android.app.Activity;
+import android.os.Handler;
+import android.os.Looper;
+import android.text.TextUtils;
+import android.view.View;
+import android.view.ViewTreeObserver;
+import android.widget.Toast;
+
+
+import com.yunbao.common.sud.decorator.SudFSMMGCache;
+import com.yunbao.common.sud.decorator.SudFSMMGDecorator;
+import com.yunbao.common.sud.decorator.SudFSMMGListener;
+import com.yunbao.common.sud.decorator.SudFSTAPPDecorator;
+import com.yunbao.common.sud.model.GameConfigModel;
+import com.yunbao.common.sud.model.GameViewInfoModel;
+import com.yunbao.common.sud.state.MGStateResponse;
+import com.yunbao.common.utils.SudJsonUtils;
+
+import tech.sud.mgp.core.ISudFSMStateHandle;
+import tech.sud.mgp.core.ISudFSTAPP;
+import tech.sud.mgp.core.ISudListenerInitSDK;
+import tech.sud.mgp.core.SudMGP;
+
+/**
+ * 游戏业务逻辑抽象类
+ * 1.定自义ViewModel继承此类,实现对应方法。(注意:onAddGameView()与onRemoveGameView()与页面有交互)
+ * 2.外部调用switchGame()方法启动游戏
+ * 3.页面销毁时调用onDestroy()
+ */
+public abstract class BaseGameViewModel implements SudFSMMGListener {
+
+    private String gameRoomId; // 游戏房间id
+    private long playingGameId; // 当前使用的游戏id
+    public final SudFSTAPPDecorator sudFSTAPPDecorator = new SudFSTAPPDecorator(); // app调用sdk的封装类
+    private final SudFSMMGDecorator sudFSMMGDecorator = new SudFSMMGDecorator(); // 用于处理游戏SDK部分回调业务
+
+    private boolean isRunning = true; // 业务是否还在运行
+    public View gameView; // 游戏View
+    public GameConfigModel gameConfigModel = new GameConfigModel(); // 游戏配置
+    protected final Handler handler = new Handler(Looper.getMainLooper());
+
+    /**
+     * 外部调用切换游戏,传不同的gameId即可加载不同的游戏
+     * gameId传0 等同于关闭游戏
+     *
+     * @param activity   游戏所在页面,用作于生命周期判断
+     * @param gameRoomId 游戏房间id,房间隔离,同一房间才能一起游戏
+     * @param gameId     游戏id,传入不同的游戏id,即可加载不同的游戏,传0等同于关闭游戏
+     */
+    public void switchGame(Activity activity, String gameRoomId, long gameId) {
+        if (TextUtils.isEmpty(gameRoomId)) {
+            Toast.makeText(activity, "gameRoomId can not be empty", Toast.LENGTH_LONG).show();
+            return;
+        }
+        if (!isRunning) {
+            return;
+        }
+        if (playingGameId == gameId && gameRoomId.equals(this.gameRoomId)) {
+            return;
+        }
+        destroyMG();
+        this.gameRoomId = gameRoomId;
+        playingGameId = gameId;
+        login(activity, gameId);
+    }
+
+    /**
+     * 第1步,获取短期令牌code,用于换取游戏Server访问APP Server的长期ssToken
+     * 接入方客户端 调用 接入方服务端 login 获取 短期令牌code
+     * 参考文档时序图:sud-mgp-doc(https://docs.sud.tech/zh-CN/app/Client/StartUp-Android.html)
+     *
+     * @param activity 游戏所在页面
+     * @param gameId   游戏id
+     */
+    private void login(Activity activity, long gameId) {
+        if (activity.isDestroyed() || gameId <= 0) {
+            return;
+        }
+        // 请求登录code
+        getCode(activity, getUserId(), getAppId(), new GameGetCodeListener() {
+            @Override
+            public void onSuccess(String code) {
+                if (!isRunning || gameId != playingGameId) {
+                    return;
+                }
+                initSdk(activity, gameId, code);
+            }
+
+            @Override
+            public void onFailed() {
+                delayLoadGame(activity, gameId);
+            }
+        });
+    }
+
+    /**
+     * 第2步,初始化SudMGP sdk
+     *
+     * @param activity 游戏所在页面
+     * @param gameId   游戏id
+     * @param code     令牌
+     */
+    private void initSdk(Activity activity, long gameId, String code) {
+        String appId = getAppId();
+        String appKey = getAppKey();
+        // 初始化sdk
+        SudMGP.initSDK(activity, appId, appKey, isTestEnv(), new ISudListenerInitSDK() {
+            @Override
+            public void onSuccess() {
+                loadGame(activity, code, gameId);
+            }
+
+            @Override
+            public void onFailure(int errCode, String errMsg) {
+                // TODO: 2022/6/13 下面toast可以根据业务需要决定是否保留
+                if (isTestEnv()) {
+                    Toast.makeText(activity, "initSDK onFailure:" + errMsg + "(" + errCode + ")", Toast.LENGTH_LONG).show();
+                }
+
+                delayLoadGame(activity, gameId);
+            }
+        });
+    }
+
+    /**
+     * 第3步,加载游戏
+     * APP和游戏的相互调用
+     * ISudFSTAPP:APP调用游戏的接口
+     * ISudFSMMG:游戏调APP的响应回调
+     *
+     * @param activity 游戏所在页面
+     * @param code     登录令牌
+     * @param gameId   游戏id
+     */
+    private void loadGame(Activity activity, String code, long gameId) {
+        if (activity.isDestroyed() || !isRunning || gameId != playingGameId) {
+            return;
+        }
+
+        // 给装饰类设置回调
+        sudFSMMGDecorator.setSudFSMMGListener(this);
+
+        // 调用游戏sdk加载游戏
+        ISudFSTAPP iSudFSTAPP = SudMGP.loadMG(activity, getUserId(), gameRoomId, code, gameId, getLanguageCode(), sudFSMMGDecorator);
+
+        // 如果返回空,则代表参数问题或者非主线程
+        if (iSudFSTAPP == null) {
+            Toast.makeText(activity, "loadMG params error", Toast.LENGTH_LONG).show();
+            delayLoadGame(activity, gameId);
+            return;
+        }
+
+        // APP调用游戏接口的装饰类设置
+        sudFSTAPPDecorator.setISudFSTAPP(iSudFSTAPP);
+
+        // 获取游戏视图,将其抛回Activity进行展示
+        // Activity调用:gameContainer.addView(view, FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT);
+        gameView = iSudFSTAPP.getGameView();
+        onAddGameView(gameView);
+    }
+
+    /**
+     * 游戏加载失败的时候,延迟一会再重新加载
+     *
+     * @param activity 游戏所在页面
+     * @param gameId   游戏id
+     */
+    private void delayLoadGame(Activity activity, long gameId) {
+        handler.postDelayed(new Runnable() {
+            @Override
+            public void run() {
+                login(activity, gameId);
+            }
+        }, 5000);
+    }
+
+    // region 生命周期相关
+
+    /** 页面销毁的时候调用 */
+    public void onDestroy() {
+        isRunning = false;
+        destroyMG();
+    }
+    // endregion 生命周期相关
+
+
+    /** 销毁游戏 */
+    private void destroyMG() {
+        if (playingGameId > 0) {
+            sudFSTAPPDecorator.destroyMG();
+            sudFSMMGDecorator.destroyMG();
+            playingGameId = 0;
+            gameView = null;
+            onRemoveGameView();
+        }
+    }
+
+    /** 获取当前游戏房id */
+    public String getGameRoomId() {
+        return gameRoomId;
+    }
+
+    // region 子类需要实现的方法
+
+    /**
+     * 向接入方服务器获取code
+     */
+    protected abstract void getCode(Activity activity, String userId, String appId, GameGetCodeListener listener);
+
+    /**
+     * 设置当前用户id(接入方定义)
+     *
+     * @return 返回用户id
+     */
+    protected abstract String getUserId();
+
+    /**
+     * 设置游戏所用的appId
+     *
+     * @return 返回游戏服务appId
+     */
+    protected abstract String getAppId();
+
+    /**
+     * 设置游戏所用的appKey
+     *
+     * @return 返回游戏服务appKey
+     */
+    protected abstract String getAppKey();
+
+    /**
+     * 设置游戏的语言代码
+     * 参考文档:https://docs.sud.tech/zh-CN/app/Client/Languages/
+     *
+     * @return 返回语言代码
+     */
+    protected abstract String getLanguageCode();
+
+    /**
+     * 设置游戏的安全操作区域
+     *
+     * @param gameViewInfoModel 游戏视图大小
+     */
+    protected abstract void getGameRect(GameViewInfoModel gameViewInfoModel);
+
+    /**
+     * true 加载游戏时为测试环境
+     * false 加载游戏时为生产环境
+     */
+    protected abstract boolean isTestEnv();
+
+    /**
+     * 将游戏View添加到页面中
+     *
+     * @param gameView
+     */
+    protected abstract void onAddGameView(View gameView);
+
+    /**
+     * 将页面中的游戏View移除
+     */
+    protected abstract void onRemoveGameView();
+
+    // endregion 子类需要实现的方法
+
+    // region 游戏侧回调
+
+    /**
+     * 游戏日志
+     * 最低版本:v1.1.30.xx
+     */
+    @Override
+    public void onGameLog(String str) {
+        SudFSMMGListener.super.onGameLog(str);
+    }
+
+    /**
+     * 游戏开始
+     * 最低版本:v1.1.30.xx
+     */
+    @Override
+    public void onGameStarted() {
+    }
+
+    /**
+     * 游戏销毁
+     * 最低版本:v1.1.30.xx
+     */
+    @Override
+    public void onGameDestroyed() {
+    }
+
+    /**
+     * Code过期,需要实现
+     * APP接入方需要调用handle.success或handle.fail
+     *
+     * @param dataJson {"code":"value"}
+     */
+    @Override
+    public void onExpireCode(ISudFSMStateHandle handle, String dataJson) {
+        processOnExpireCode(sudFSTAPPDecorator, handle);
+    }
+
+    /**
+     * 获取游戏View信息,需要实现
+     * APP接入方需要调用handle.success或handle.fail
+     *
+     * @param handle   handle
+     * @param dataJson {}
+     */
+    @Override
+    public void onGetGameViewInfo(ISudFSMStateHandle handle, String dataJson) {
+        processOnGetGameViewInfo(gameView, handle);
+    }
+
+    /**
+     * 获取游戏Config,需要实现
+     * APP接入方需要调用handle.success或handle.fail
+     *
+     * @param handle   handle
+     * @param dataJson {}
+     *                 最低版本:v1.1.30.xx
+     */
+    @Override
+    public void onGetGameCfg(ISudFSMStateHandle handle, String dataJson) {
+        processOnGetGameCfg(handle, dataJson);
+    }
+    // endregion 游戏侧回调
+
+
+    /** 处理code过期 */
+    public void processOnExpireCode(SudFSTAPPDecorator sudFSTAPPDecorator, ISudFSMStateHandle handle) {
+        // code过期,刷新code
+        getCode(null, getUserId(), getAppId(), new GameGetCodeListener() {
+            @Override
+            public void onSuccess(String code) {
+                if (!isRunning) return;
+                MGStateResponse mgStateResponse = new MGStateResponse();
+                mgStateResponse.ret_code = MGStateResponse.SUCCESS;
+                sudFSTAPPDecorator.updateCode(code, null);
+                handle.success(SudJsonUtils.toJson(mgStateResponse));
+            }
+
+            @Override
+            public void onFailed() {
+                MGStateResponse mgStateResponse = new MGStateResponse();
+                mgStateResponse.ret_code = -1;
+                handle.failure(SudJsonUtils.toJson(mgStateResponse));
+            }
+        });
+    }
+
+    /**
+     * 处理游戏视图信息(游戏安全区)
+     * 文档:https://docs.sud.tech/zh-CN/app/Client/API/ISudFSMMG/onGetGameViewInfo.html
+     */
+    public void processOnGetGameViewInfo(View gameView, ISudFSMStateHandle handle) {
+        //拿到游戏View的宽高
+        int gameViewWidth = gameView.getMeasuredWidth();
+        int gameViewHeight = gameView.getMeasuredHeight();
+        if (gameViewWidth > 0 && gameViewHeight > 0) {
+            notifyGameViewInfo(handle, gameViewWidth, gameViewHeight);
+            return;
+        }
+
+        //如果游戏View未加载完成,则监听加载完成时回调
+        gameView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
+            @Override
+            public void onGlobalLayout() {
+                gameView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
+                int width = gameView.getMeasuredWidth();
+                int height = gameView.getMeasuredHeight();
+                notifyGameViewInfo(handle, width, height);
+            }
+        });
+    }
+
+    /** 通知游戏,游戏视图信息 */
+    private void notifyGameViewInfo(ISudFSMStateHandle handle, int gameViewWidth, int gameViewHeight) {
+        GameViewInfoModel gameViewInfoModel = new GameViewInfoModel();
+        gameViewInfoModel.ret_code = 0;
+        // 游戏View大小
+        gameViewInfoModel.view_size.width = gameViewWidth;
+        gameViewInfoModel.view_size.height = gameViewHeight;
+
+        // 游戏安全操作区域
+        getGameRect(gameViewInfoModel);
+
+        // 给游戏侧进行返回
+        String json = SudJsonUtils.toJson(gameViewInfoModel);
+        // 如果设置安全区有疑问,可将下面的日志打印出来,分析json数据
+        // 正确的格式为:{"ret_code":0,"view_game_rect":{"bottom":156,"left":0,"right":0,"top":196},"view_size":{"height":1920,"width":1080}}
+        // 如果发生debug版本游戏正常,release版本游戏不正常,请检查是否混淆了GameViewInfoModel类,导致json序列化类的成员发生了变化
+        // Log.d("SudBaseGameViewModel", "notifyGameViewInfo:" + json);
+        handle.success(json);
+    }
+
+    public void onPause() {
+        // playMG和pauseMG要配对
+        sudFSTAPPDecorator.pauseMG();
+    }
+
+    public void onResume() {
+        // playMG和pauseMG要配对
+        sudFSTAPPDecorator.playMG();
+    }
+
+    /**
+     * 处理游戏配置
+     * 文档:https://docs.sud.tech/zh-CN/app/Client/API/ISudFSMMG/onGetGameCfg.html
+     */
+    public void processOnGetGameCfg(ISudFSMStateHandle handle, String dataJson) {
+        handle.success(SudJsonUtils.toJson(gameConfigModel));
+    }
+
+    /** 游戏login(getCode)监听 */
+    public interface GameGetCodeListener {
+        /** 成功 */
+        void onSuccess(String code);
+
+        /** 失败 */
+        void onFailed();
+    }
+
+    /** 获取游戏状态缓存 */
+    public SudFSMMGCache getSudFSMMGCache() {
+        return sudFSMMGDecorator.getSudFSMMGCache();
+    }
+
+}
diff --git a/common/src/main/java/com/yunbao/common/sud/QuickStartGameViewModel.java b/common/src/main/java/com/yunbao/common/sud/QuickStartGameViewModel.java
new file mode 100644
index 000000000..db360ecde
--- /dev/null
+++ b/common/src/main/java/com/yunbao/common/sud/QuickStartGameViewModel.java
@@ -0,0 +1,216 @@
+package com.yunbao.common.sud;
+
+import android.app.Activity;
+import android.view.View;
+
+import androidx.lifecycle.MutableLiveData;
+
+import com.yunbao.common.sud.model.GameConfigModel;
+import com.yunbao.common.sud.model.GameViewInfoModel;
+import com.yunbao.common.sud.state.MGStateResponse;
+import com.yunbao.common.sud.state.SudMGPMGState;
+
+import org.json.JSONObject;
+
+import java.io.IOException;
+import java.util.Objects;
+
+import okhttp3.Call;
+import okhttp3.Callback;
+import okhttp3.MediaType;
+import okhttp3.OkHttpClient;
+import okhttp3.Request;
+import okhttp3.RequestBody;
+import okhttp3.Response;
+
+import tech.sud.mgp.core.ISudFSMMG;
+import tech.sud.mgp.core.ISudFSMStateHandle;
+
+/**
+ * 游戏业务逻辑
+ * 1.自定义ViewModel继承此类,实现对应方法。(注意:onAddGameView()与onRemoveGameView()与页面有交互)
+ * 2.外部调用switchGame(activity,gameRoomId,gameId)方法启动游戏,参数定义可查看方法注释。
+ * 3.页面销毁时调用onDestroy()
+ */
+public class QuickStartGameViewModel extends BaseGameViewModel {
+
+    /** Sud平台申请的appId */
+    public static String SudMGP_APP_ID = "1701178631292395522";
+    /** Sud平台申请的appKey */
+    public static String SudMGP_APP_KEY = "E3Eokfq58ZklwR8fM7iKWYGzarbIOkyh";
+    /** true 加载游戏时为测试环境 false 加载游戏时为生产环境 */
+    public static final boolean GAME_IS_TEST_ENV = true;
+
+    /** 使用的UserId。这里随机生成作演示,开发者将其修改为业务使用的唯一userId */
+    public static String userId = QuickStartUtils.genUserID();
+
+    /** 游戏自定义安全操作区域 */
+    public GameViewInfoModel.GameViewRectModel gameViewRectModel;
+
+    /** 游戏的语言代码 */
+    public String languageCode = "zh-CN";
+
+    public final MutableLiveData<View> gameViewLiveData = new MutableLiveData<>(); // 游戏View回调
+
+    /** 向接入方服务器获取code */
+    @Override
+    protected void getCode(Activity activity, String userId, String appId, GameGetCodeListener listener) {
+        // TODO: 2022/6/10 注意,这里是演示使用OkHttpClient请求hello-sud服务
+        // TODO: 2022/6/10 开发者在与后端联调时需将其改成自己的网络请求方式向自己的服务器获取code
+//        OkHttpClient client = new OkHttpClient();
+//        String req;
+//        try {
+//            JSONObject reqJsonObj = new JSONObject();
+//            reqJsonObj.put("user_id", userId);
+//            req = reqJsonObj.toString();
+//        } catch (Exception e) {
+//            e.printStackTrace();
+//            req = "";
+//        }
+//
+//        RequestBody body = RequestBody.create(req, MediaType.get("application/json; charset=utf-8"));
+//        Request request = new Request.Builder()
+//                .url("https://mgp-hello.sudden.ltd/login/v3")
+//                .post(body)
+//                .build();
+//        client.newCall(request).enqueue(new Callback() {
+//            @Override
+//            public void onFailure(Call call, IOException e) {
+//                handler.post(new Runnable() {
+//                    @Override
+//                    public void run() {
+//                        listener.onFailed();
+//                    }
+//                });
+//            }
+//
+//            @Override
+//            public void onResponse(Call call, Response response) {
+//                try {
+//                    String dataJson = Objects.requireNonNull(response.body()).string();
+//                    JSONObject jsonObject = new JSONObject(dataJson);
+//                    int ret_code = jsonObject.getInt("ret_code");
+//                    JSONObject dataObject = jsonObject.getJSONObject("data");
+//                    String code = dataObject.getString("code");
+//                    handler.post(new Runnable() {
+//                        @Override
+//                        public void run() {
+//                            if (ret_code == MGStateResponse.SUCCESS) {
+//                                listener.onSuccess(code);
+//                            } else {
+//                                listener.onFailed();
+//                            }
+//                        }
+//                    });
+//                } catch (Exception e) {
+//                    e.printStackTrace();
+//                    handler.post(new Runnable() {
+//                        @Override
+//                        public void run() {
+//                            listener.onFailed();
+//                        }
+//                    });
+//                }
+//            }
+//        });
+    }
+
+    /** 设置当前用户id(接入方定义) */
+    @Override
+    protected String getUserId() {
+        return userId;
+    }
+
+    /** 设置Sud平台申请的appId */
+    @Override
+    protected String getAppId() {
+        return SudMGP_APP_ID;
+    }
+
+    /** 设置Sud平台申请的appKey */
+    @Override
+    protected String getAppKey() {
+        return SudMGP_APP_KEY;
+    }
+
+    /** 设置游戏的语言代码 */
+    @Override
+    protected String getLanguageCode() {
+        return languageCode;
+    }
+
+    /**
+     * 设置游戏的安全操作区域,{@link ISudFSMMG}.onGetGameViewInfo()的实现。
+     * 参考文档:https://docs.sud.tech/zh-CN/app/Client/API/ISudFSMMG/onGetGameViewInfo.html
+     *
+     * @param gameViewInfoModel 游戏视图模型
+     */
+    @Override
+    protected void getGameRect(GameViewInfoModel gameViewInfoModel) {
+        // 相对于view_size(左、上、右、下)边框偏移(单位像素)
+        // 开发者可自定义gameViewRectModel来控制安全区域
+        if (gameViewRectModel != null) {
+            gameViewInfoModel.view_game_rect = gameViewRectModel;
+        }
+    }
+
+    /**
+     * 获取游戏配置对象,{@link ISudFSMMG}.onGetGameCfg()的实现。
+     * 参考文档:https://docs.sud.tech/zh-CN/app/Client/API/ISudFSMMG/onGetGameCfg.html
+     * 开发者拿到此对象之后,可修改自己需要的配置
+     * 注意:在加载游戏之前配置才有效
+     *
+     * @return 游戏配置对象
+     */
+    public GameConfigModel getGameConfigModel() {
+        return gameConfigModel;
+    }
+
+    /**
+     * true 加载游戏时为测试环境
+     * false 加载游戏时为生产环境
+     */
+    @Override
+    protected boolean isTestEnv() {
+        return GAME_IS_TEST_ENV;
+    }
+
+    /** 将游戏View添加到页面中 */
+    @Override
+    protected void onAddGameView(View gameView) {
+        gameViewLiveData.setValue(gameView);
+    }
+
+    /** 将页面中的游戏View移除 */
+    @Override
+    protected void onRemoveGameView() {
+        gameViewLiveData.setValue(null);
+    }
+
+    // ************ 上面是基础能力以及必要配置,下面讲解状态交互
+    // ************ 主要有:1.App向游戏发送状态;2.游戏向App回调状态
+
+    /**
+     * 1.App向游戏发送状态
+     * 这里演示的是发送:1. 加入状态;
+     * 开发者可自由定义方法,能发送的状态都封装在{@link SudFSTAPPDecorator}
+     * 参考文档:https://docs.sud.tech/zh-CN/app/Client/APPFST/
+     * 注意:
+     * 1,App向游戏发送状态,因为需要走网络,所以向游戏发送状态之后,不能马上销毁游戏或者finish Activity,否则状态无法发送成功。
+     * 2,要保证状态能到达,可以发送之后,delay 500ms再销毁游戏或者finish Activity。
+     */
+    public void notifyAPPCommonSelfIn(boolean isIn, int seatIndex, boolean isSeatRandom, int teamId) {
+        sudFSTAPPDecorator.notifyAPPCommonSelfIn(isIn, seatIndex, isSeatRandom, teamId);
+    }
+
+    /**
+     * 2.游戏向App回调状态
+     * 这里演示的是接收游戏回调状态:10. 游戏状态 mg_common_game_state
+     * 游戏回调的每个状态都对应着一个方法,方法定义在:{@link SudFSMMGListener}
+     */
+    @Override
+    public void onGameMGCommonGameState(ISudFSMStateHandle handle, SudMGPMGState.MGCommonGameState model) {
+        super.onGameMGCommonGameState(handle, model);
+    }
+
+}
diff --git a/common/src/main/java/com/yunbao/common/sud/QuickStartUtils.java b/common/src/main/java/com/yunbao/common/sud/QuickStartUtils.java
new file mode 100644
index 000000000..1df24fba6
--- /dev/null
+++ b/common/src/main/java/com/yunbao/common/sud/QuickStartUtils.java
@@ -0,0 +1,30 @@
+package com.yunbao.common.sud;
+
+import java.math.BigInteger;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.UUID;
+
+public class QuickStartUtils {
+
+    /** 随机生成一个userId,用于演示 */
+    public static String genUserID() {
+        return md5Hex8(UUID.randomUUID().toString());
+    }
+
+    public static String md5Hex8(String plainText) {
+        byte[] secretBytes;
+        try {
+            secretBytes = MessageDigest.getInstance("md5").digest(plainText.getBytes());
+        } catch (NoSuchAlgorithmException e) {
+            return plainText;
+        }
+        String md5code = new BigInteger(1, secretBytes).toString(16);
+        for (int i = 0; i < 32 - md5code.length(); i++) {
+            md5code = String.format("0%s", md5code);
+        }
+
+        return md5code.substring(8, 16);
+    }
+
+}
diff --git a/common/src/main/java/com/yunbao/common/sud/decorator/SudFSMMGCache.java b/common/src/main/java/com/yunbao/common/sud/decorator/SudFSMMGCache.java
new file mode 100644
index 000000000..0415ebed4
--- /dev/null
+++ b/common/src/main/java/com/yunbao/common/sud/decorator/SudFSMMGCache.java
@@ -0,0 +1,151 @@
+/*
+ * Copyright © Sud.Tech
+ * https://sud.tech
+ */
+
+package com.yunbao.common.sud.decorator;
+
+import com.yunbao.common.sud.state.SudMGPMGState;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Objects;
+
+
+/**
+ * 游戏回调数据缓存
+ */
+public class SudFSMMGCache {
+
+    private String captainUserId; // 记录当前队长的用户id
+    private SudMGPMGState.MGCommonGameState mgCommonGameStateModel; // 全局游戏状态
+    private boolean isHitBomb = false; // 是否数字炸弹
+    private final HashSet<String> playerInSet = new HashSet<>(); // 记录已经加入了游戏的玩家
+    private final HashSet<String> playerReadySet = new HashSet<>(); // 记录已经准备好的游戏玩家
+    private final HashMap<String, SudMGPMGState.MGCommonPlayerPlaying> playerPlayingMap = new HashMap<>(); // 记录玩家的游戏状态
+
+    // 队长状态 处理
+    public void onPlayerMGCommonPlayerCaptain(String userId, SudMGPMGState.MGCommonPlayerCaptain model) {
+        if (model != null) {
+            if (model.isCaptain) {
+                captainUserId = userId;
+            } else {
+                if (Objects.equals(captainUserId, userId)) {
+                    captainUserId = null;
+                }
+            }
+        }
+    }
+
+    // 游戏状态 处理
+    public void onGameMGCommonGameState(SudMGPMGState.MGCommonGameState model) {
+        mgCommonGameStateModel = model;
+    }
+
+    // 玩家加入状态处理
+    public void onPlayerMGCommonPlayerIn(String userId, SudMGPMGState.MGCommonPlayerIn model) {
+        if (model != null) {
+            if (model.isIn) {
+                playerInSet.add(userId);
+            } else {
+                playerInSet.remove(userId);
+                playerReadySet.remove(userId);
+            }
+        }
+    }
+
+    // 玩家准备状态
+    public void onPlayerMGCommonPlayerReady(String userId, SudMGPMGState.MGCommonPlayerReady model) {
+        if (model != null) {
+            if (model.isReady) {
+                playerReadySet.add(userId);
+            } else {
+                playerReadySet.remove(userId);
+            }
+        }
+    }
+
+    // 玩家游戏状态
+    public void onPlayerMGCommonPlayerPlaying(String userId, SudMGPMGState.MGCommonPlayerPlaying model) {
+        if (model != null) {
+            playerPlayingMap.put(userId, model);
+        }
+    }
+
+    // 关键词状态
+    public void onGameMGCommonKeyWordToHit(SudMGPMGState.MGCommonKeyWordToHit model) {
+        if (model != null) {
+            isHitBomb = model.wordType.equals("number");
+        }
+    }
+
+    // 返回该玩家是否正在游戏中
+    public boolean playerIsPlaying(String userId) {
+        SudMGPMGState.MGCommonPlayerPlaying mgCommonPlayerPlaying = playerPlayingMap.get(userId);
+        if (mgCommonPlayerPlaying != null) {
+            return mgCommonPlayerPlaying.isPlaying;
+        }
+        return false;
+    }
+
+    // 返回该玩家是否已准备
+    public boolean playerIsReady(String userId) {
+        return playerReadySet.contains(userId);
+    }
+
+    // 返回该玩家是否已加入了游戏
+    public boolean playerIsIn(String userId) {
+        return playerInSet.contains(userId);
+    }
+
+    // 获取当前游戏中的人数
+    public int getPlayerInNumber() {
+        return playerInSet.size();
+    }
+
+    // 是否数字炸弹
+    public boolean isHitBomb() {
+        return isHitBomb;
+    }
+
+    // 销毁游戏
+    public void destroyMG() {
+        captainUserId = null;
+        mgCommonGameStateModel = null;
+        isHitBomb = false;
+        playerInSet.clear();
+        playerReadySet.clear();
+        playerPlayingMap.clear();
+    }
+
+    /** 获取队长userId */
+    public String getCaptainUserId() {
+        return captainUserId;
+    }
+
+    /** 获取当前已加入游戏的玩家集合 */
+    public HashSet<String> getPlayerInSet() {
+        return new HashSet<>(playerInSet);
+    }
+
+    /** 获取当前已准备的玩家集合 */
+    public HashSet<String> getPlayerReadySet() {
+        return new HashSet<>(playerReadySet);
+    }
+
+    /** 获取玩家游戏状态集合 */
+    public HashMap<String, SudMGPMGState.MGCommonPlayerPlaying> getPlayerPlayingMap() {
+        return new HashMap<>(playerPlayingMap);
+    }
+
+    /**
+     * 返回当前游戏的状态,数值参数{@link SudMGPMGState.MGCommonGameState}
+     */
+    public int getGameState() {
+        if (mgCommonGameStateModel != null) {
+            return mgCommonGameStateModel.gameState;
+        }
+        return SudMGPMGState.MGCommonGameState.UNKNOW;
+    }
+
+}
diff --git a/common/src/main/java/com/yunbao/common/sud/decorator/SudFSMMGDecorator.java b/common/src/main/java/com/yunbao/common/sud/decorator/SudFSMMGDecorator.java
new file mode 100644
index 000000000..fc213354a
--- /dev/null
+++ b/common/src/main/java/com/yunbao/common/sud/decorator/SudFSMMGDecorator.java
@@ -0,0 +1,1009 @@
+/*
+ * Copyright © Sud.Tech
+ * https://sud.tech
+ */
+
+package com.yunbao.common.sud.decorator;
+
+
+import com.yunbao.common.sud.state.SudMGPMGState;
+import com.yunbao.common.utils.ISudFSMStateHandleUtils;
+import com.yunbao.common.utils.SudJsonUtils;
+
+import tech.sud.mgp.core.ISudFSMMG;
+import tech.sud.mgp.core.ISudFSMStateHandle;
+
+/**
+ * ISudFSMMG 游戏调APP回调装饰类
+ * 参考文档:https://docs.sud.tech/zh-CN/app/Client/API/ISudFSMMG.html
+ */
+public class SudFSMMGDecorator implements ISudFSMMG {
+
+    // 回调
+    private SudFSMMGListener sudFSMMGListener;
+
+    // 数据状态封装
+    private final SudFSMMGCache sudFSMMGCache = new SudFSMMGCache();
+
+    /**
+     * 设置回调
+     *
+     * @param listener 监听器
+     */
+    public void setSudFSMMGListener(SudFSMMGListener listener) {
+        sudFSMMGListener = listener;
+    }
+
+    /**
+     * 游戏日志
+     * 最低版本:v1.1.30.xx
+     */
+    @Override
+    public void onGameLog(String dataJson) {
+        SudFSMMGListener listener = sudFSMMGListener;
+        if (listener != null) {
+            listener.onGameLog(dataJson);
+        }
+    }
+
+    /**
+     * 游戏加载进度
+     *
+     * @param stage    阶段:start=1,loading=2,end=3
+     * @param retCode  错误码:0成功
+     * @param progress 进度:[0, 100]
+     */
+    @Override
+    public void onGameLoadingProgress(int stage, int retCode, int progress) {
+        SudFSMMGListener listener = sudFSMMGListener;
+        if (listener != null) {
+            listener.onGameLoadingProgress(stage, retCode, progress);
+        }
+    }
+
+    /**
+     * 游戏开始
+     * 最低版本:v1.1.30.xx
+     */
+    @Override
+    public void onGameStarted() {
+        SudFSMMGListener listener = sudFSMMGListener;
+        if (listener != null) {
+            listener.onGameStarted();
+        }
+    }
+
+    /**
+     * 游戏销毁
+     * 最低版本:v1.1.30.xx
+     */
+    @Override
+    public void onGameDestroyed() {
+        SudFSMMGListener listener = sudFSMMGListener;
+        if (listener != null) {
+            listener.onGameDestroyed();
+        }
+    }
+
+    /**
+     * Code过期,需要实现
+     * APP接入方需要调用handle.success或handle.fail
+     *
+     * @param dataJson {"code":"value"}
+     */
+    @Override
+    public void onExpireCode(ISudFSMStateHandle handle, String dataJson) {
+        SudFSMMGListener listener = sudFSMMGListener;
+        if (listener != null) {
+            listener.onExpireCode(handle, dataJson);
+        }
+    }
+
+    /**
+     * 获取游戏View信息,需要实现
+     * APP接入方需要调用handle.success或handle.fail
+     *
+     * @param handle   操作
+     * @param dataJson {}
+     */
+    @Override
+    public void onGetGameViewInfo(ISudFSMStateHandle handle, String dataJson) {
+        SudFSMMGListener listener = sudFSMMGListener;
+        if (listener != null) {
+            listener.onGetGameViewInfo(handle, dataJson);
+        }
+    }
+
+    /**
+     * 获取游戏Config,需要实现
+     * APP接入方需要调用handle.success或handle.fail
+     *
+     * @param handle   操作
+     * @param dataJson {}
+     *                 最低版本:v1.1.30.xx
+     */
+    @Override
+    public void onGetGameCfg(ISudFSMStateHandle handle, String dataJson) {
+        SudFSMMGListener listener = sudFSMMGListener;
+        if (listener != null) {
+            listener.onGetGameCfg(handle, dataJson);
+        }
+    }
+
+    /**
+     * 游戏状态变化
+     * APP接入方需要调用handle.success或handle.fail
+     *
+     * @param handle   操作
+     * @param state    状态命令
+     * @param dataJson 状态值
+     */
+    @Override
+    public void onGameStateChange(ISudFSMStateHandle handle, String state, String dataJson) {
+        SudFSMMGListener listener = sudFSMMGListener;
+        if (listener != null && listener.onGameStateChange(handle, state, dataJson)) {
+            return;
+        }
+        switch (state) {
+            case SudMGPMGState.MG_COMMON_PUBLIC_MESSAGE: // 1. 公屏消息
+                SudMGPMGState.MGCommonPublicMessage mgCommonPublicMessage = SudJsonUtils.fromJson(dataJson, SudMGPMGState.MGCommonPublicMessage.class);
+                if (listener == null) {
+                    ISudFSMStateHandleUtils.handleSuccess(handle);
+                } else {
+                    listener.onGameMGCommonPublicMessage(handle, mgCommonPublicMessage);
+                }
+                break;
+            case SudMGPMGState.MG_COMMON_KEY_WORD_TO_HIT: // 2. 关键词状态
+                SudMGPMGState.MGCommonKeyWordToHit mgCommonKeyWordToHit = SudJsonUtils.fromJson(dataJson, SudMGPMGState.MGCommonKeyWordToHit.class);
+                sudFSMMGCache.onGameMGCommonKeyWordToHit(mgCommonKeyWordToHit);
+                if (listener == null) {
+                    ISudFSMStateHandleUtils.handleSuccess(handle);
+                } else {
+                    listener.onGameMGCommonKeyWordToHit(handle, mgCommonKeyWordToHit);
+                }
+                break;
+            case SudMGPMGState.MG_COMMON_GAME_SETTLE: // 3. 游戏结算状态
+                SudMGPMGState.MGCommonGameSettle mgCommonGameSettle = SudJsonUtils.fromJson(dataJson, SudMGPMGState.MGCommonGameSettle.class);
+                if (listener == null) {
+                    ISudFSMStateHandleUtils.handleSuccess(handle);
+                } else {
+                    listener.onGameMGCommonGameSettle(handle, mgCommonGameSettle);
+                }
+                break;
+            case SudMGPMGState.MG_COMMON_SELF_CLICK_JOIN_BTN: // 4. 加入游戏按钮点击状态
+                SudMGPMGState.MGCommonSelfClickJoinBtn mgCommonSelfClickJoinBtn = SudJsonUtils.fromJson(dataJson, SudMGPMGState.MGCommonSelfClickJoinBtn.class);
+                if (listener == null) {
+                    ISudFSMStateHandleUtils.handleSuccess(handle);
+                } else {
+                    listener.onGameMGCommonSelfClickJoinBtn(handle, mgCommonSelfClickJoinBtn);
+                }
+                break;
+            case SudMGPMGState.MG_COMMON_SELF_CLICK_CANCEL_JOIN_BTN: // 5. 取消加入(退出)游戏按钮点击状态
+                SudMGPMGState.MGCommonSelfClickCancelJoinBtn selfClickCancelJoinBtn = SudJsonUtils.fromJson(dataJson, SudMGPMGState.MGCommonSelfClickCancelJoinBtn.class);
+                if (listener == null) {
+                    ISudFSMStateHandleUtils.handleSuccess(handle);
+                } else {
+                    listener.onGameMGCommonSelfClickCancelJoinBtn(handle, selfClickCancelJoinBtn);
+                }
+                break;
+            case SudMGPMGState.MG_COMMON_SELF_CLICK_READY_BTN: // 6. 准备按钮点击状态
+                SudMGPMGState.MGCommonSelfClickReadyBtn mgCommonSelfClickReadyBtn = SudJsonUtils.fromJson(dataJson, SudMGPMGState.MGCommonSelfClickReadyBtn.class);
+                if (listener == null) {
+                    ISudFSMStateHandleUtils.handleSuccess(handle);
+                } else {
+                    listener.onGameMGCommonSelfClickReadyBtn(handle, mgCommonSelfClickReadyBtn);
+                }
+                break;
+            case SudMGPMGState.MG_COMMON_SELF_CLICK_CANCEL_READY_BTN: // 7. 取消准备按钮点击状态
+                SudMGPMGState.MGCommonSelfClickCancelReadyBtn mgCommonSelfClickCancelReadyBtn = SudJsonUtils.fromJson(dataJson, SudMGPMGState.MGCommonSelfClickCancelReadyBtn.class);
+                if (listener == null) {
+                    ISudFSMStateHandleUtils.handleSuccess(handle);
+                } else {
+                    listener.onGameMGCommonSelfClickCancelReadyBtn(handle, mgCommonSelfClickCancelReadyBtn);
+                }
+                break;
+            case SudMGPMGState.MG_COMMON_SELF_CLICK_START_BTN: // 8. 开始游戏按钮点击状态
+                SudMGPMGState.MGCommonSelfClickStartBtn mgCommonSelfClickStartBtn = SudJsonUtils.fromJson(dataJson, SudMGPMGState.MGCommonSelfClickStartBtn.class);
+                if (listener == null) {
+                    ISudFSMStateHandleUtils.handleSuccess(handle);
+                } else {
+                    listener.onGameMGCommonSelfClickStartBtn(handle, mgCommonSelfClickStartBtn);
+                }
+                break;
+            case SudMGPMGState.MG_COMMON_SELF_CLICK_SHARE_BTN: // 9. 分享按钮点击状态
+                SudMGPMGState.MGCommonSelfClickShareBtn mgCommonSelfClickShareBtn = SudJsonUtils.fromJson(dataJson, SudMGPMGState.MGCommonSelfClickShareBtn.class);
+                if (listener == null) {
+                    ISudFSMStateHandleUtils.handleSuccess(handle);
+                } else {
+                    listener.onGameMGCommonSelfClickShareBtn(handle, mgCommonSelfClickShareBtn);
+                }
+                break;
+            case SudMGPMGState.MG_COMMON_GAME_STATE: // 10. 游戏状态
+                SudMGPMGState.MGCommonGameState mgCommonGameState = SudJsonUtils.fromJson(dataJson, SudMGPMGState.MGCommonGameState.class);
+                sudFSMMGCache.onGameMGCommonGameState(mgCommonGameState);
+                if (listener == null) {
+                    ISudFSMStateHandleUtils.handleSuccess(handle);
+                } else {
+                    listener.onGameMGCommonGameState(handle, mgCommonGameState);
+                }
+                break;
+            case SudMGPMGState.MG_COMMON_SELF_CLICK_GAME_SETTLE_CLOSE_BTN: // 11. 结算界面关闭按钮点击状态(2021-12-27新增)
+                SudMGPMGState.MGCommonSelfClickGameSettleCloseBtn mgCommonSelfClickGameSettleCloseBtn = SudJsonUtils.fromJson(dataJson, SudMGPMGState.MGCommonSelfClickGameSettleCloseBtn.class);
+                if (listener == null) {
+                    ISudFSMStateHandleUtils.handleSuccess(handle);
+                } else {
+                    listener.onGameMGCommonSelfClickGameSettleCloseBtn(handle, mgCommonSelfClickGameSettleCloseBtn);
+                }
+                break;
+            case SudMGPMGState.MG_COMMON_SELF_CLICK_GAME_SETTLE_AGAIN_BTN: // 12. 结算界面再来一局按钮点击状态(2021-12-27新增)
+                SudMGPMGState.MGCommonSelfClickGameSettleAgainBtn mgCommonSelfClickGameSettleAgainBtn = SudJsonUtils.fromJson(dataJson, SudMGPMGState.MGCommonSelfClickGameSettleAgainBtn.class);
+                if (listener == null) {
+                    ISudFSMStateHandleUtils.handleSuccess(handle);
+                } else {
+                    listener.onGameMGCommonSelfClickGameSettleAgainBtn(handle, mgCommonSelfClickGameSettleAgainBtn);
+                }
+                break;
+            case SudMGPMGState.MG_COMMON_GAME_SOUND_LIST: // 13. 游戏上报游戏中的声音列表(2021-12-30新增,现在只支持碰碰我最强)
+                SudMGPMGState.MGCommonGameSoundList mgCommonGameSoundList = SudJsonUtils.fromJson(dataJson, SudMGPMGState.MGCommonGameSoundList.class);
+                if (listener == null) {
+                    ISudFSMStateHandleUtils.handleSuccess(handle);
+                } else {
+                    listener.onGameMGCommonGameSoundList(handle, mgCommonGameSoundList);
+                }
+                break;
+            case SudMGPMGState.MG_COMMON_GAME_SOUND: // 14. 游通知app层播放声音(2021-12-30新增,现在只支持碰碰我最强)
+                SudMGPMGState.MGCommonGameSound mgCommonGameSound = SudJsonUtils.fromJson(dataJson, SudMGPMGState.MGCommonGameSound.class);
+                if (listener == null) {
+                    ISudFSMStateHandleUtils.handleSuccess(handle);
+                } else {
+                    listener.onGameMGCommonGameSound(handle, mgCommonGameSound);
+                }
+                break;
+            case SudMGPMGState.MG_COMMON_GAME_BG_MUSIC_STATE: // 15. 游戏通知app层播放背景音乐状态(2022-01-07新增,现在只支持碰碰我最强)
+                SudMGPMGState.MGCommonGameBgMusicState mgCommonGameBgMusicState = SudJsonUtils.fromJson(dataJson, SudMGPMGState.MGCommonGameBgMusicState.class);
+                if (listener == null) {
+                    ISudFSMStateHandleUtils.handleSuccess(handle);
+                } else {
+                    listener.onGameMGCommonGameBgMusicState(handle, mgCommonGameBgMusicState);
+                }
+                break;
+            case SudMGPMGState.MG_COMMON_GAME_SOUND_STATE: // 16. 游戏通知app层播放音效的状态(2022-01-07新增,现在只支持碰碰我最强)
+                SudMGPMGState.MGCommonGameSoundState mgCommonGameSoundState = SudJsonUtils.fromJson(dataJson, SudMGPMGState.MGCommonGameSoundState.class);
+                if (listener == null) {
+                    ISudFSMStateHandleUtils.handleSuccess(handle);
+                } else {
+                    listener.onGameMGCommonGameSoundState(handle, mgCommonGameSoundState);
+                }
+                break;
+            case SudMGPMGState.MG_COMMON_GAME_ASR: // 17. ASR状态(开启和关闭语音识别状态,v1.1.45.xx 版本新增)
+                SudMGPMGState.MGCommonGameASR mgCommonGameASR = SudJsonUtils.fromJson(dataJson, SudMGPMGState.MGCommonGameASR.class);
+                if (listener == null) {
+                    ISudFSMStateHandleUtils.handleSuccess(handle);
+                } else {
+                    listener.onGameMGCommonGameASR(handle, mgCommonGameASR);
+                }
+                break;
+            case SudMGPMGState.MG_COMMON_SELF_MICROPHONE: // 18. 麦克风状态(2022-02-08新增)
+                SudMGPMGState.MGCommonSelfMicrophone mgCommonSelfMicrophone = SudJsonUtils.fromJson(dataJson, SudMGPMGState.MGCommonSelfMicrophone.class);
+                if (listener == null) {
+                    ISudFSMStateHandleUtils.handleSuccess(handle);
+                } else {
+                    listener.onGameMGCommonSelfMicrophone(handle, mgCommonSelfMicrophone);
+                }
+                break;
+            case SudMGPMGState.MG_COMMON_SELF_HEADPHONE: // 19. 耳机(听筒,扬声器)状态(2022-02-08新增)
+                SudMGPMGState.MGCommonSelfHeadphone mgCommonSelfHeadphone = SudJsonUtils.fromJson(dataJson, SudMGPMGState.MGCommonSelfHeadphone.class);
+                if (listener == null) {
+                    ISudFSMStateHandleUtils.handleSuccess(handle);
+                } else {
+                    listener.onGameMGCommonSelfHeadphone(handle, mgCommonSelfHeadphone);
+                }
+                break;
+            case SudMGPMGState.MG_COMMON_APP_COMMON_SELF_X_RESP: // 20. App通用状态操作结果错误码(2022-05-10新增)
+                SudMGPMGState.MGCommonAPPCommonSelfXResp mgCommonAPPCommonSelfXResp = SudJsonUtils.fromJson(dataJson, SudMGPMGState.MGCommonAPPCommonSelfXResp.class);
+                if (listener == null) {
+                    ISudFSMStateHandleUtils.handleSuccess(handle);
+                } else {
+                    listener.onGameMGCommonAPPCommonSelfXResp(handle, mgCommonAPPCommonSelfXResp);
+                }
+                break;
+            case SudMGPMGState.MG_COMMON_GAME_ADD_AI_PLAYERS: // 21. 游戏通知app层添加陪玩机器人是否成功(2022-05-17新增)
+                SudMGPMGState.MGCommonGameAddAIPlayers mgCommonGameAddAIPlayers = SudJsonUtils.fromJson(dataJson, SudMGPMGState.MGCommonGameAddAIPlayers.class);
+                if (listener == null) {
+                    ISudFSMStateHandleUtils.handleSuccess(handle);
+                } else {
+                    listener.onGameMGCommonGameAddAIPlayers(handle, mgCommonGameAddAIPlayers);
+                }
+                break;
+            case SudMGPMGState.MG_COMMON_GAME_NETWORK_STATE: // 22. 游戏通知app层添当前网络连接状态(2022-06-21新增)
+                SudMGPMGState.MGCommonGameNetworkState mgCommonGameNetworkState = SudJsonUtils.fromJson(dataJson, SudMGPMGState.MGCommonGameNetworkState.class);
+                if (listener == null) {
+                    ISudFSMStateHandleUtils.handleSuccess(handle);
+                } else {
+                    listener.onGameMGCommonGameNetworkState(handle, mgCommonGameNetworkState);
+                }
+                break;
+            case SudMGPMGState.MG_COMMON_GAME_GET_SCORE: // 23. 游戏通知app获取积分
+                SudMGPMGState.MGCommonGameGetScore mgCommonGameScore = SudJsonUtils.fromJson(dataJson, SudMGPMGState.MGCommonGameGetScore.class);
+                if (listener == null) {
+                    ISudFSMStateHandleUtils.handleSuccess(handle);
+                } else {
+                    listener.onGameMGCommonGameGetScore(handle, mgCommonGameScore);
+                }
+                break;
+            case SudMGPMGState.MG_COMMON_GAME_SET_SCORE: // 24. 游戏通知app带入积分
+                SudMGPMGState.MGCommonGameSetScore mgCommonGameSetScore = SudJsonUtils.fromJson(dataJson, SudMGPMGState.MGCommonGameSetScore.class);
+                if (listener == null) {
+                    ISudFSMStateHandleUtils.handleSuccess(handle);
+                } else {
+                    listener.onGameMGCommonGameSetScore(handle, mgCommonGameSetScore);
+                }
+                break;
+            case SudMGPMGState.MG_COMMON_GAME_CREATE_ORDER: // 25. 创建订单
+                SudMGPMGState.MGCommonGameCreateOrder mgCommonGameCreateOrder = SudJsonUtils.fromJson(dataJson, SudMGPMGState.MGCommonGameCreateOrder.class);
+                if (listener == null) {
+                    ISudFSMStateHandleUtils.handleSuccess(handle);
+                } else {
+                    listener.onGameMGCommonGameCreateOrder(handle, mgCommonGameCreateOrder);
+                }
+                break;
+            case SudMGPMGState.MG_COMMON_PLAYER_ROLE_ID: // 26. 游戏通知app玩家角色(仅对狼人杀有效)
+                SudMGPMGState.MGCommonPlayerRoleId mgCommonPlayerRoleId = SudJsonUtils.fromJson(dataJson, SudMGPMGState.MGCommonPlayerRoleId.class);
+                if (listener == null) {
+                    ISudFSMStateHandleUtils.handleSuccess(handle);
+                } else {
+                    listener.onGameMGCommonPlayerRoleId(handle, mgCommonPlayerRoleId);
+                }
+                break;
+            case SudMGPMGState.MG_COMMON_SELF_CLICK_POOP: // 27. 游戏通知app玩家被扔便便(你画我猜,你说我猜,友尽闯关有效)
+                SudMGPMGState.MGCommonSelfClickPoop mgCommonSelfClickPoop = SudJsonUtils.fromJson(dataJson, SudMGPMGState.MGCommonSelfClickPoop.class);
+                if (listener == null) {
+                    ISudFSMStateHandleUtils.handleSuccess(handle);
+                } else {
+                    listener.onGameMGCommonSelfClickPoop(handle, mgCommonSelfClickPoop);
+                }
+                break;
+            case SudMGPMGState.MG_COMMON_SELF_CLICK_GOOD: // 28. 游戏通知app玩家被点赞(你画我猜,你说我猜,友尽闯关有效)
+                SudMGPMGState.MGCommonSelfClickGood mgCommonSelfClickGood = SudJsonUtils.fromJson(dataJson, SudMGPMGState.MGCommonSelfClickGood.class);
+                if (listener == null) {
+                    ISudFSMStateHandleUtils.handleSuccess(handle);
+                } else {
+                    listener.onGameMGCommonSelfClickGood(handle, mgCommonSelfClickGood);
+                }
+                break;
+            case SudMGPMGState.MG_COMMON_GAME_FPS: // 29. 游戏通知app游戏FPS(仅对碰碰,多米诺骨牌,飞镖达人生效)
+                SudMGPMGState.MGCommonGameFps mgCommonGameFps = SudJsonUtils.fromJson(dataJson, SudMGPMGState.MGCommonGameFps.class);
+                if (listener == null) {
+                    ISudFSMStateHandleUtils.handleSuccess(handle);
+                } else {
+                    listener.onGameMGCommonGameFps(handle, mgCommonGameFps);
+                }
+                break;
+            case SudMGPMGState.MG_COMMON_ALERT: // 30. 游戏通知app游戏弹框
+                SudMGPMGState.MGCommonAlert mgCommonAlert = SudJsonUtils.fromJson(dataJson, SudMGPMGState.MGCommonAlert.class);
+                if (listener == null) {
+                    ISudFSMStateHandleUtils.handleSuccess(handle);
+                } else {
+                    listener.onGameMGCommonAlert(handle, mgCommonAlert);
+                }
+                break;
+            case SudMGPMGState.MG_COMMON_WORST_TEAMMATE: // 31. 游戏通知app最坑队友(只支持友尽闯关)
+                SudMGPMGState.MGCommonWorstTeammate mgCommonWorstTeammate = SudJsonUtils.fromJson(dataJson, SudMGPMGState.MGCommonWorstTeammate.class);
+                if (listener == null) {
+                    ISudFSMStateHandleUtils.handleSuccess(handle);
+                } else {
+                    listener.onGameMGCommonWorstTeammate(handle, mgCommonWorstTeammate);
+                }
+                break;
+            case SudMGPMGState.MG_COMMON_GAME_OVER_TIP: // 32. 游戏通知app因玩家逃跑导致游戏结束(只支持友尽闯关)
+                SudMGPMGState.MGCommonGameOverTip mgCommonGameOverTip = SudJsonUtils.fromJson(dataJson, SudMGPMGState.MGCommonGameOverTip.class);
+                if (listener == null) {
+                    ISudFSMStateHandleUtils.handleSuccess(handle);
+                } else {
+                    listener.onGameMGCommonGameOverTip(handle, mgCommonGameOverTip);
+                }
+                break;
+            case SudMGPMGState.MG_COMMON_GAME_PLAYER_COLOR: // 33. 游戏通知app玩家颜色(只支持友尽闯关)
+                SudMGPMGState.MGCommonGamePlayerColor mgCommonGamePlayerColor = SudJsonUtils.fromJson(dataJson, SudMGPMGState.MGCommonGamePlayerColor.class);
+                if (listener == null) {
+                    ISudFSMStateHandleUtils.handleSuccess(handle);
+                } else {
+                    listener.onGameMGCommonGamePlayerColor(handle, mgCommonGamePlayerColor);
+                }
+                break;
+            case SudMGPMGState.MG_COMMON_GAME_PLAYER_ICON_POSITION: // 34. 游戏通知app玩家头像的坐标(只支持ludo)
+                SudMGPMGState.MGCommonGamePlayerIconPosition mgCommonGamePlayerIconPosition = SudJsonUtils.fromJson(dataJson, SudMGPMGState.MGCommonGamePlayerIconPosition.class);
+                if (listener == null) {
+                    ISudFSMStateHandleUtils.handleSuccess(handle);
+                } else {
+                    listener.onGameMGCommonGamePlayerIconPosition(handle, mgCommonGamePlayerIconPosition);
+                }
+                break;
+            case SudMGPMGState.MG_COMMON_SELF_CLICK_EXIT_GAME_BTN: // 35. 游戏通知app退出游戏(只支持teenpattipro 与 德州pro)
+                SudMGPMGState.MGCommonSelfClickExitGameBtn mgCommonSelfClickExitGameBtn = SudJsonUtils.fromJson(dataJson, SudMGPMGState.MGCommonSelfClickExitGameBtn.class);
+                if (listener == null) {
+                    ISudFSMStateHandleUtils.handleSuccess(handle);
+                } else {
+                    listener.onGameMGCommonSelfClickExitGameBtn(handle, mgCommonSelfClickExitGameBtn);
+                }
+                break;
+            case SudMGPMGState.MG_COMMON_GAME_IS_APP_CHIP: // 36. 游戏通知app是否要开启带入积分(只支持teenpattipro 与 德州pro)
+                SudMGPMGState.MGCommonGameIsAppChip mgCommonGameIsAppChip = SudJsonUtils.fromJson(dataJson, SudMGPMGState.MGCommonGameIsAppChip.class);
+                if (listener == null) {
+                    ISudFSMStateHandleUtils.handleSuccess(handle);
+                } else {
+                    listener.onGameMGCommonGameIsAppChip(handle, mgCommonGameIsAppChip);
+                }
+                break;
+            case SudMGPMGState.MG_COMMON_GAME_RULE: // 37. 游戏通知app当前游戏的设置信息(只支持德州pro,teenpatti pro)
+                SudMGPMGState.MGCommonGameRule mgCommonGameRule = SudJsonUtils.fromJson(dataJson, SudMGPMGState.MGCommonGameRule.class);
+                if (listener == null) {
+                    ISudFSMStateHandleUtils.handleSuccess(handle);
+                } else {
+                    listener.onGameMGCommonGameRule(handle, mgCommonGameRule);
+                }
+                break;
+            case SudMGPMGState.MG_COMMON_GAME_SETTINGS: // 38. 游戏通知app进行玩法设置(只支持德州pro,teenpatti pro)
+                SudMGPMGState.MGCommonGameSettings mgCommonGameSettings = SudJsonUtils.fromJson(dataJson, SudMGPMGState.MGCommonGameSettings.class);
+                if (listener == null) {
+                    ISudFSMStateHandleUtils.handleSuccess(handle);
+                } else {
+                    listener.onGameMGCommonGameSettings(handle, mgCommonGameSettings);
+                }
+                break;
+            case SudMGPMGState.MG_COMMON_GAME_MONEY_NOT_ENOUGH: // 39. 游戏通知app钱币不足(只支持德州pro,teenpatti pro)
+                SudMGPMGState.MGCommonGameMoneyNotEnough mgCommonGameMoneyNotEnough = SudJsonUtils.fromJson(dataJson, SudMGPMGState.MGCommonGameMoneyNotEnough.class);
+                if (listener == null) {
+                    ISudFSMStateHandleUtils.handleSuccess(handle);
+                } else {
+                    listener.onGameMGCommonGameMoneyNotEnough(handle, mgCommonGameMoneyNotEnough);
+                }
+                break;
+            case SudMGPMGState.MG_COMMON_GAME_UI_CUSTOM_CONFIG: // 40. 游戏通知app下发定制ui配置表(只支持ludo)
+                SudMGPMGState.MGCommonGameUiCustomConfig mgCommonGameUiCustomConfig = SudJsonUtils.fromJson(dataJson, SudMGPMGState.MGCommonGameUiCustomConfig.class);
+                if (listener == null) {
+                    ISudFSMStateHandleUtils.handleSuccess(handle);
+                } else {
+                    listener.onGameMGCommonGameUiCustomConfig(handle, mgCommonGameUiCustomConfig);
+                }
+                break;
+            case SudMGPMGState.MG_COMMON_SET_CLICK_RECT: // 41. 设置app提供给游戏可点击区域(赛车)
+                SudMGPMGState.MGCommonSetClickRect mgCommonSetClickRect = SudJsonUtils.fromJson(dataJson, SudMGPMGState.MGCommonSetClickRect.class);
+                if (listener == null) {
+                    ISudFSMStateHandleUtils.handleSuccess(handle);
+                } else {
+                    listener.onGameMGCommonSetClickRect(handle, mgCommonSetClickRect);
+                }
+                break;
+            case SudMGPMGState.MG_COMMON_USERS_INFO: // 42. 通知app提供对应uids列表玩家的数据(赛车)
+                SudMGPMGState.MGCommonUsersInfo mgCommonUsersInfo = SudJsonUtils.fromJson(dataJson, SudMGPMGState.MGCommonUsersInfo.class);
+                if (listener == null) {
+                    ISudFSMStateHandleUtils.handleSuccess(handle);
+                } else {
+                    listener.onGameMGCommonUsersInfo(handle, mgCommonUsersInfo);
+                }
+                break;
+            case SudMGPMGState.MG_COMMON_GAME_PREPARE_FINISH: // 43. 通知app游戏前期准备完成(赛车)
+                SudMGPMGState.MGCommonGamePrepareFinish mgCommonGamePrepareFinish = SudJsonUtils.fromJson(dataJson, SudMGPMGState.MGCommonGamePrepareFinish.class);
+                if (listener == null) {
+                    ISudFSMStateHandleUtils.handleSuccess(handle);
+                } else {
+                    listener.onGameMGCommonGamePrepareFinish(handle, mgCommonGamePrepareFinish);
+                }
+                break;
+            case SudMGPMGState.MG_COMMON_SHOW_GAME_SCENE: // 44. 通知app游戏主界面已显示(赛车)
+                SudMGPMGState.MGCommonShowGameScene mgCommonShowGameScene = SudJsonUtils.fromJson(dataJson, SudMGPMGState.MGCommonShowGameScene.class);
+                if (listener == null) {
+                    ISudFSMStateHandleUtils.handleSuccess(handle);
+                } else {
+                    listener.onGameMGCommonShowGameScene(handle, mgCommonShowGameScene);
+                }
+                break;
+            case SudMGPMGState.MG_COMMON_HIDE_GAME_SCENE: // 45. 通知app游戏主界面已隐藏(赛车)
+                SudMGPMGState.MGCommonHideGameScene mgCommonHideGameScene = SudJsonUtils.fromJson(dataJson, SudMGPMGState.MGCommonHideGameScene.class);
+                if (listener == null) {
+                    ISudFSMStateHandleUtils.handleSuccess(handle);
+                } else {
+                    listener.onGameMGCommonHideGameScene(handle, mgCommonHideGameScene);
+                }
+                break;
+            case SudMGPMGState.MG_COMMON_GAME_DISCO_ACTION: // 1. 元宇宙砂砂舞指令回调
+                SudMGPMGState.MGCommonGameDiscoAction mgCommonGameDiscoAction = SudJsonUtils.fromJson(dataJson, SudMGPMGState.MGCommonGameDiscoAction.class);
+                if (listener == null) {
+                    ISudFSMStateHandleUtils.handleSuccess(handle);
+                } else {
+                    listener.onGameMGCommonGameDiscoAction(handle, mgCommonGameDiscoAction);
+                }
+                break;
+            case SudMGPMGState.MG_COMMON_GAME_DISCO_ACTION_END: // 2. 元宇宙砂砂舞指令动作结束通知
+                SudMGPMGState.MGCommonGameDiscoActionEnd mgCommonGameDiscoActionEnd = SudJsonUtils.fromJson(dataJson, SudMGPMGState.MGCommonGameDiscoActionEnd.class);
+                if (listener == null) {
+                    ISudFSMStateHandleUtils.handleSuccess(handle);
+                } else {
+                    listener.onGameMGCommonGameDiscoActionEnd(handle, mgCommonGameDiscoActionEnd);
+                }
+                break;
+            case SudMGPMGState.MG_CUSTOM_ROCKET_CONFIG: // 1. 礼物配置文件(火箭)
+                SudMGPMGState.MGCustomRocketConfig mgCustomRocketConfig = SudJsonUtils.fromJson(dataJson, SudMGPMGState.MGCustomRocketConfig.class);
+                if (listener == null) {
+                    ISudFSMStateHandleUtils.handleSuccess(handle);
+                } else {
+                    listener.onGameMGCustomRocketConfig(handle, mgCustomRocketConfig);
+                }
+                break;
+            case SudMGPMGState.MG_CUSTOM_ROCKET_MODEL_LIST: // 2. 拥有模型列表(火箭)
+                SudMGPMGState.MGCustomRocketModelList mgCustomRocketModelList = SudJsonUtils.fromJson(dataJson, SudMGPMGState.MGCustomRocketModelList.class);
+                if (listener == null) {
+                    ISudFSMStateHandleUtils.handleSuccess(handle);
+                } else {
+                    listener.onGameMGCustomRocketModelList(handle, mgCustomRocketModelList);
+                }
+                break;
+            case SudMGPMGState.MG_CUSTOM_ROCKET_COMPONENT_LIST: // 3. 拥有组件列表(火箭)
+                SudMGPMGState.MGCustomRocketComponentList mgCustomRocketComponentList = SudJsonUtils.fromJson(dataJson, SudMGPMGState.MGCustomRocketComponentList.class);
+                if (listener == null) {
+                    ISudFSMStateHandleUtils.handleSuccess(handle);
+                } else {
+                    listener.onGameMGCustomRocketComponentList(handle, mgCustomRocketComponentList);
+                }
+                break;
+            case SudMGPMGState.MG_CUSTOM_ROCKET_USER_INFO: // 4. 获取用户信息(火箭)
+                SudMGPMGState.MGCustomRocketUserInfo mgCustomRocketUserInfo = SudJsonUtils.fromJson(dataJson, SudMGPMGState.MGCustomRocketUserInfo.class);
+                if (listener == null) {
+                    ISudFSMStateHandleUtils.handleSuccess(handle);
+                } else {
+                    listener.onGameMGCustomRocketUserInfo(handle, mgCustomRocketUserInfo);
+                }
+                break;
+            case SudMGPMGState.MG_CUSTOM_ROCKET_ORDER_RECORD_LIST: // 5. 订单记录列表(火箭)
+                SudMGPMGState.MGCustomRocketOrderRecordList mgCustomRocketOrderRecordList = SudJsonUtils.fromJson(dataJson, SudMGPMGState.MGCustomRocketOrderRecordList.class);
+                if (listener == null) {
+                    ISudFSMStateHandleUtils.handleSuccess(handle);
+                } else {
+                    listener.onGameMGCustomRocketOrderRecordList(handle, mgCustomRocketOrderRecordList);
+                }
+                break;
+            case SudMGPMGState.MG_CUSTOM_ROCKET_ROOM_RECORD_LIST: // 6. 展馆内列表(火箭)
+                SudMGPMGState.MGCustomRocketRoomRecordList mgCustomRocketRoomRecordList = SudJsonUtils.fromJson(dataJson, SudMGPMGState.MGCustomRocketRoomRecordList.class);
+                if (listener == null) {
+                    ISudFSMStateHandleUtils.handleSuccess(handle);
+                } else {
+                    listener.onGameMGCustomRocketRoomRecordList(handle, mgCustomRocketRoomRecordList);
+                }
+                break;
+            case SudMGPMGState.MG_CUSTOM_ROCKET_USER_RECORD_LIST: // 7. 展馆内玩家送出记录(火箭)
+                SudMGPMGState.MGCustomRocketUserRecordList mgCustomRocketUserRecordList = SudJsonUtils.fromJson(dataJson, SudMGPMGState.MGCustomRocketUserRecordList.class);
+                if (listener == null) {
+                    ISudFSMStateHandleUtils.handleSuccess(handle);
+                } else {
+                    listener.onGameMGCustomRocketUserRecordList(handle, mgCustomRocketUserRecordList);
+                }
+                break;
+            case SudMGPMGState.MG_CUSTOM_ROCKET_SET_DEFAULT_MODEL: // 8. 设置默认模型(火箭)
+                SudMGPMGState.MGCustomRocketSetDefaultModel mgCustomRocketSetDefaultSeat = SudJsonUtils.fromJson(dataJson, SudMGPMGState.MGCustomRocketSetDefaultModel.class);
+                if (listener == null) {
+                    ISudFSMStateHandleUtils.handleSuccess(handle);
+                } else {
+                    listener.onGameMGCustomRocketSetDefaultModel(handle, mgCustomRocketSetDefaultSeat);
+                }
+                break;
+            case SudMGPMGState.MG_CUSTOM_ROCKET_DYNAMIC_FIRE_PRICE: // 9. 动态计算一键发送价格(火箭)
+                SudMGPMGState.MGCustomRocketDynamicFirePrice mgCustomRocketDynamicFirePrice = SudJsonUtils.fromJson(dataJson, SudMGPMGState.MGCustomRocketDynamicFirePrice.class);
+                if (listener == null) {
+                    ISudFSMStateHandleUtils.handleSuccess(handle);
+                } else {
+                    listener.onGameMGCustomRocketDynamicFirePrice(handle, mgCustomRocketDynamicFirePrice);
+                }
+                break;
+            case SudMGPMGState.MG_CUSTOM_ROCKET_FIRE_MODEL: // 10. 一键发送(火箭)
+                SudMGPMGState.MGCustomRocketFireModel mGCustomRocketFireModel = SudJsonUtils.fromJson(dataJson, SudMGPMGState.MGCustomRocketFireModel.class);
+                if (listener == null) {
+                    ISudFSMStateHandleUtils.handleSuccess(handle);
+                } else {
+                    listener.onGameMGCustomRocketFireModel(handle, mGCustomRocketFireModel);
+                }
+                break;
+            case SudMGPMGState.MG_CUSTOM_ROCKET_CREATE_MODEL: // 11. 新组装模型(火箭)
+                SudMGPMGState.MGCustomRocketCreateModel mgCustomRocketCreateModel = SudJsonUtils.fromJson(dataJson, SudMGPMGState.MGCustomRocketCreateModel.class);
+                if (listener == null) {
+                    ISudFSMStateHandleUtils.handleSuccess(handle);
+                } else {
+                    listener.onGameMGCustomRocketCreateModel(handle, mgCustomRocketCreateModel);
+                }
+                break;
+            case SudMGPMGState.MG_CUSTOM_ROCKET_REPLACE_COMPONENT: // 12. 模型更换组件(火箭)
+                SudMGPMGState.MGCustomRocketReplaceComponent mgCustomRocketReplaceComponent = SudJsonUtils.fromJson(dataJson, SudMGPMGState.MGCustomRocketReplaceComponent.class);
+                if (listener == null) {
+                    ISudFSMStateHandleUtils.handleSuccess(handle);
+                } else {
+                    listener.onGameMGCustomRocketReplaceComponent(handle, mgCustomRocketReplaceComponent);
+                }
+                break;
+            case SudMGPMGState.MG_CUSTOM_ROCKET_BUY_COMPONENT: // 13. 购买组件(火箭)
+                SudMGPMGState.MGCustomRocketBuyComponent mgCustomRocketBuyComponent = SudJsonUtils.fromJson(dataJson, SudMGPMGState.MGCustomRocketBuyComponent.class);
+                if (listener == null) {
+                    ISudFSMStateHandleUtils.handleSuccess(handle);
+                } else {
+                    listener.onGameMGCustomRocketBuyComponent(handle, mgCustomRocketBuyComponent);
+                }
+                break;
+            case SudMGPMGState.MG_CUSTOM_ROCKET_PLAY_EFFECT_START: // 14. 播放效果开始(火箭)
+                SudMGPMGState.MGCustomRocketPlayEffectStart mgCustomRocketPlayEffectStart = SudJsonUtils.fromJson(dataJson, SudMGPMGState.MGCustomRocketPlayEffectStart.class);
+                if (listener == null) {
+                    ISudFSMStateHandleUtils.handleSuccess(handle);
+                } else {
+                    listener.onGameMGCustomRocketPlayEffectStart(handle, mgCustomRocketPlayEffectStart);
+                }
+                break;
+            case SudMGPMGState.MG_CUSTOM_ROCKET_PLAY_EFFECT_FINISH: // 15. 播放效果完成(火箭)
+                SudMGPMGState.MGCustomRocketPlayEffectFinish mgCustomRocketPlayEffectFinish = SudJsonUtils.fromJson(dataJson, SudMGPMGState.MGCustomRocketPlayEffectFinish.class);
+                if (listener == null) {
+                    ISudFSMStateHandleUtils.handleSuccess(handle);
+                } else {
+                    listener.onGameMGCustomRocketPlayEffectFinish(handle, mgCustomRocketPlayEffectFinish);
+                }
+                break;
+            case SudMGPMGState.MG_CUSTOM_ROCKET_VERIFY_SIGN: // 16. 验证签名合规(火箭)
+                SudMGPMGState.MGCustomRocketVerifySign mgCustomRocketVerifySign = SudJsonUtils.fromJson(dataJson, SudMGPMGState.MGCustomRocketVerifySign.class);
+                if (listener == null) {
+                    ISudFSMStateHandleUtils.handleSuccess(handle);
+                } else {
+                    listener.onGameMGCustomRocketVerifySign(handle, mgCustomRocketVerifySign);
+                }
+                break;
+            case SudMGPMGState.MG_CUSTOM_ROCKET_UPLOAD_MODEL_ICON: // 17. 上传icon(火箭)
+                SudMGPMGState.MGCustomRocketUploadModelIcon mgCustomRocketUploadModelIcon = SudJsonUtils.fromJson(dataJson, SudMGPMGState.MGCustomRocketUploadModelIcon.class);
+                if (listener == null) {
+                    ISudFSMStateHandleUtils.handleSuccess(handle);
+                } else {
+                    listener.onGameMGCustomRocketUploadModelIcon(handle, mgCustomRocketUploadModelIcon);
+                }
+                break;
+            case SudMGPMGState.MG_CUSTOM_ROCKET_PREPARE_FINISH: // 18. 前期准备完成(火箭)
+                SudMGPMGState.MGCustomRocketPrepareFinish mgCustomRocketPrepareFinish = SudJsonUtils.fromJson(dataJson, SudMGPMGState.MGCustomRocketPrepareFinish.class);
+                if (listener == null) {
+                    ISudFSMStateHandleUtils.handleSuccess(handle);
+                } else {
+                    listener.onGameMGCustomRocketPrepareFinish(handle, mgCustomRocketPrepareFinish);
+                }
+                break;
+            case SudMGPMGState.MG_CUSTOM_ROCKET_SHOW_GAME_SCENE: // 19. 火箭主界面已显示(火箭)
+                SudMGPMGState.MGCustomRocketShowGameScene mgCustomRocketShowGameScene = SudJsonUtils.fromJson(dataJson, SudMGPMGState.MGCustomRocketShowGameScene.class);
+                if (listener == null) {
+                    ISudFSMStateHandleUtils.handleSuccess(handle);
+                } else {
+                    listener.onGameMGCustomRocketShowGameScene(handle, mgCustomRocketShowGameScene);
+                }
+                break;
+            case SudMGPMGState.MG_CUSTOM_ROCKET_HIDE_GAME_SCENE: // 20. 火箭主界面已隐藏(火箭)
+                SudMGPMGState.MGCustomRocketHideGameScene mgCustomRocketHideGameScene = SudJsonUtils.fromJson(dataJson, SudMGPMGState.MGCustomRocketHideGameScene.class);
+                if (listener == null) {
+                    ISudFSMStateHandleUtils.handleSuccess(handle);
+                } else {
+                    listener.onGameMGCustomRocketHideGameScene(handle, mgCustomRocketHideGameScene);
+                }
+                break;
+            case SudMGPMGState.MG_CUSTOM_ROCKET_CLICK_LOCK_COMPONENT: // 21. 点击锁住组件(火箭)
+                SudMGPMGState.MGCustomRocketClickLockComponent mgCustomRocketClickLockComponent = SudJsonUtils.fromJson(dataJson, SudMGPMGState.MGCustomRocketClickLockComponent.class);
+                if (listener == null) {
+                    ISudFSMStateHandleUtils.handleSuccess(handle);
+                } else {
+                    listener.onGameMGCustomRocketClickLockComponent(handle, mgCustomRocketClickLockComponent);
+                }
+                break;
+            case SudMGPMGState.MG_CUSTOM_ROCKET_FLY_CLICK: // 22. 火箭效果飞行点击(火箭)
+                SudMGPMGState.MGCustomRocketFlyClick mgCustomRocketFlyClick = SudJsonUtils.fromJson(dataJson, SudMGPMGState.MGCustomRocketFlyClick.class);
+                if (listener == null) {
+                    ISudFSMStateHandleUtils.handleSuccess(handle);
+                } else {
+                    listener.onGameMGCustomRocketFlyClick(handle, mgCustomRocketFlyClick);
+                }
+                break;
+            case SudMGPMGState.MG_CUSTOM_ROCKET_FLY_END: // 23. 火箭效果飞行结束(火箭)
+                SudMGPMGState.MGCustomRocketFlyEnd mgCustomRocketFlyEnd = SudJsonUtils.fromJson(dataJson, SudMGPMGState.MGCustomRocketFlyEnd.class);
+                if (listener == null) {
+                    ISudFSMStateHandleUtils.handleSuccess(handle);
+                } else {
+                    listener.onGameMGCustomRocketFlyEnd(handle, mgCustomRocketFlyEnd);
+                }
+                break;
+            case SudMGPMGState.MG_CUSTOM_ROCKET_SET_CLICK_RECT: // 24. 设置点击区域(火箭)
+                SudMGPMGState.MGCustomRocketSetClickRect mgCustomRocketSetClickRect = SudJsonUtils.fromJson(dataJson, SudMGPMGState.MGCustomRocketSetClickRect.class);
+                if (listener == null) {
+                    ISudFSMStateHandleUtils.handleSuccess(handle);
+                } else {
+                    listener.onGameMGCustomRocketSetClickRect(handle, mgCustomRocketSetClickRect);
+                }
+                break;
+            case SudMGPMGState.MG_CUSTOM_ROCKET_SAVE_SIGN_COLOR: // 25. 颜色和签名自定义改到装配间的模式,保存颜色或签名 模型
+                SudMGPMGState.MGCustomRocketSaveSignColor mgCustomRocketSaveSignColor = SudJsonUtils.fromJson(dataJson, SudMGPMGState.MGCustomRocketSaveSignColor.class);
+                if (listener == null) {
+                    ISudFSMStateHandleUtils.handleSuccess(handle);
+                } else {
+                    listener.onGameMGCustomRocketSaveSignColor(handle, mgCustomRocketSaveSignColor);
+                }
+                break;
+            case SudMGPMGState.MG_BASEBALL_RANKING: // 1. 查询排行榜数据(棒球)
+                SudMGPMGState.MGBaseballRanking mgBaseballRanking = SudJsonUtils.fromJson(dataJson, SudMGPMGState.MGBaseballRanking.class);
+                if (listener == null) {
+                    ISudFSMStateHandleUtils.handleSuccess(handle);
+                } else {
+                    listener.onGameMGBaseballRanking(handle, mgBaseballRanking);
+                }
+                break;
+            case SudMGPMGState.MG_BASEBALL_MY_RANKING: // 2. 查询我的排名(棒球)
+                SudMGPMGState.MGBaseballMyRanking mgBaseballMyRanking = SudJsonUtils.fromJson(dataJson, SudMGPMGState.MGBaseballMyRanking.class);
+                if (listener == null) {
+                    ISudFSMStateHandleUtils.handleSuccess(handle);
+                } else {
+                    listener.onGameMGBaseballMyRanking(handle, mgBaseballMyRanking);
+                }
+                break;
+            case SudMGPMGState.MG_BASEBALL_RANGE_INFO: // 3. 查询当前距离我的前后玩家数据(棒球)
+                SudMGPMGState.MGBaseballRangeInfo mgBaseballRangeInfo = SudJsonUtils.fromJson(dataJson, SudMGPMGState.MGBaseballRangeInfo.class);
+                if (listener == null) {
+                    ISudFSMStateHandleUtils.handleSuccess(handle);
+                } else {
+                    listener.onGameMGBaseballRangeInfo(handle, mgBaseballRangeInfo);
+                }
+                break;
+            case SudMGPMGState.MG_BASEBALL_SET_CLICK_RECT: // 4. 设置app提供给游戏可点击区域(棒球)
+                SudMGPMGState.MGBaseballSetClickRect mgBaseballSetClickRect = SudJsonUtils.fromJson(dataJson, SudMGPMGState.MGBaseballSetClickRect.class);
+                if (listener == null) {
+                    ISudFSMStateHandleUtils.handleSuccess(handle);
+                } else {
+                    listener.onGameMGBaseballSetClickRect(handle, mgBaseballSetClickRect);
+                }
+                break;
+            case SudMGPMGState.MG_BASEBALL_PREPARE_FINISH: // 5. 前期准备完成(棒球)
+                SudMGPMGState.MGBaseballPrepareFinish mgBaseballPrepareFinish = SudJsonUtils.fromJson(dataJson, SudMGPMGState.MGBaseballPrepareFinish.class);
+                if (listener == null) {
+                    ISudFSMStateHandleUtils.handleSuccess(handle);
+                } else {
+                    listener.onGameMGBaseballPrepareFinish(handle, mgBaseballPrepareFinish);
+                }
+                break;
+            case SudMGPMGState.MG_BASEBALL_SHOW_GAME_SCENE: // 6. 主界面已显示(棒球)
+                SudMGPMGState.MGBaseballShowGameScene mgBaseballShowGameScene = SudJsonUtils.fromJson(dataJson, SudMGPMGState.MGBaseballShowGameScene.class);
+                if (listener == null) {
+                    ISudFSMStateHandleUtils.handleSuccess(handle);
+                } else {
+                    listener.onGameMGBaseballShowGameScene(handle, mgBaseballShowGameScene);
+                }
+                break;
+            case SudMGPMGState.MG_BASEBALL_HIDE_GAME_SCENE: // 7. 主界面已隐藏(棒球)
+                SudMGPMGState.MGBaseballHideGameScene mgBaseballHideGameScene = SudJsonUtils.fromJson(dataJson, SudMGPMGState.MGBaseballHideGameScene.class);
+                if (listener == null) {
+                    ISudFSMStateHandleUtils.handleSuccess(handle);
+                } else {
+                    listener.onGameMGBaseballHideGameScene(handle, mgBaseballHideGameScene);
+                }
+                break;
+            case SudMGPMGState.MG_BASEBALL_TEXT_CONFIG: // 8. 获取文本配置数据(棒球)
+                SudMGPMGState.MGBaseballTextConfig mgBaseballTextConfig = SudJsonUtils.fromJson(dataJson, SudMGPMGState.MGBaseballTextConfig.class);
+                if (listener == null) {
+                    ISudFSMStateHandleUtils.handleSuccess(handle);
+                } else {
+                    listener.onGameMGBaseballTextConfig(handle, mgBaseballTextConfig);
+                }
+                break;
+            default:
+                ISudFSMStateHandleUtils.handleSuccess(handle);
+                break;
+        }
+    }
+
+    /**
+     * 游戏玩家状态变化
+     * APP接入方需要调用handle.success或handle.fail
+     *
+     * @param handle   操作
+     * @param userId   用户id
+     * @param state    状态命令
+     * @param dataJson 状态值
+     */
+    @Override
+    public void onPlayerStateChange(ISudFSMStateHandle handle, String userId, String state, String dataJson) {
+        SudFSMMGListener listener = sudFSMMGListener;
+        if (listener != null && listener.onPlayerStateChange(handle, userId, state, dataJson)) {
+            return;
+        }
+        switch (state) {
+            case SudMGPMGState.MG_COMMON_PLAYER_IN: // 1.加入状态(已修改)
+                SudMGPMGState.MGCommonPlayerIn mgCommonPlayerIn = SudJsonUtils.fromJson(dataJson, SudMGPMGState.MGCommonPlayerIn.class);
+                sudFSMMGCache.onPlayerMGCommonPlayerIn(userId, mgCommonPlayerIn);
+                if (listener == null) {
+                    ISudFSMStateHandleUtils.handleSuccess(handle);
+                } else {
+                    listener.onPlayerMGCommonPlayerIn(handle, userId, mgCommonPlayerIn);
+                }
+                break;
+            case SudMGPMGState.MG_COMMON_PLAYER_READY: // 2.准备状态(已修改)
+                SudMGPMGState.MGCommonPlayerReady mgCommonPlayerReady = SudJsonUtils.fromJson(dataJson, SudMGPMGState.MGCommonPlayerReady.class);
+                sudFSMMGCache.onPlayerMGCommonPlayerReady(userId, mgCommonPlayerReady);
+                if (listener == null) {
+                    ISudFSMStateHandleUtils.handleSuccess(handle);
+                } else {
+                    listener.onPlayerMGCommonPlayerReady(handle, userId, mgCommonPlayerReady);
+                }
+                break;
+            case SudMGPMGState.MG_COMMON_PLAYER_CAPTAIN: // 3.队长状态(已修改)
+                SudMGPMGState.MGCommonPlayerCaptain mgCommonPlayerCaptain = SudJsonUtils.fromJson(dataJson, SudMGPMGState.MGCommonPlayerCaptain.class);
+                sudFSMMGCache.onPlayerMGCommonPlayerCaptain(userId, mgCommonPlayerCaptain);
+                if (listener == null) {
+                    ISudFSMStateHandleUtils.handleSuccess(handle);
+                } else {
+                    listener.onPlayerMGCommonPlayerCaptain(handle, userId, mgCommonPlayerCaptain);
+                }
+                break;
+            case SudMGPMGState.MG_COMMON_PLAYER_PLAYING: // 4.游戏状态(已修改)
+                SudMGPMGState.MGCommonPlayerPlaying mgCommonPlayerPlaying = SudJsonUtils.fromJson(dataJson, SudMGPMGState.MGCommonPlayerPlaying.class);
+                sudFSMMGCache.onPlayerMGCommonPlayerPlaying(userId, mgCommonPlayerPlaying);
+                if (listener == null) {
+                    ISudFSMStateHandleUtils.handleSuccess(handle);
+                } else {
+                    listener.onPlayerMGCommonPlayerPlaying(handle, userId, mgCommonPlayerPlaying);
+                }
+                break;
+            case SudMGPMGState.MG_COMMON_PLAYER_ONLINE: // 5.玩家在线状态
+                SudMGPMGState.MGCommonPlayerOnline mgCommonPlayerOnline = SudJsonUtils.fromJson(dataJson, SudMGPMGState.MGCommonPlayerOnline.class);
+                if (listener == null) {
+                    ISudFSMStateHandleUtils.handleSuccess(handle);
+                } else {
+                    listener.onPlayerMGCommonPlayerOnline(handle, userId, mgCommonPlayerOnline);
+                }
+                break;
+            case SudMGPMGState.MG_COMMON_PLAYER_CHANGE_SEAT: // 6.玩家换游戏位状态
+                SudMGPMGState.MGCommonPlayerChangeSeat mgCommonPlayerChangeSeat = SudJsonUtils.fromJson(dataJson, SudMGPMGState.MGCommonPlayerChangeSeat.class);
+                if (listener == null) {
+                    ISudFSMStateHandleUtils.handleSuccess(handle);
+                } else {
+                    listener.onPlayerMGCommonPlayerChangeSeat(handle, userId, mgCommonPlayerChangeSeat);
+                }
+                break;
+            case SudMGPMGState.MG_COMMON_SELF_CLICK_GAME_PLAYER_ICON: // 7. 游戏通知app点击玩家头像
+                SudMGPMGState.MGCommonSelfClickGamePlayerIcon mgCommonSelfClickGamePlayerIcon = SudJsonUtils.fromJson(dataJson, SudMGPMGState.MGCommonSelfClickGamePlayerIcon.class);
+                if (listener == null) {
+                    ISudFSMStateHandleUtils.handleSuccess(handle);
+                } else {
+                    listener.onPlayerMGCommonSelfClickGamePlayerIcon(handle, userId, mgCommonSelfClickGamePlayerIcon);
+                }
+                break;
+            case SudMGPMGState.MG_COMMON_SELF_DIE_STATUS: // 8. 游戏通知app玩家死亡状态(2022-04-24新增)
+                SudMGPMGState.MGCommonSelfDieStatus mgCommonSelfDieStatus = SudJsonUtils.fromJson(dataJson, SudMGPMGState.MGCommonSelfDieStatus.class);
+                if (listener == null) {
+                    ISudFSMStateHandleUtils.handleSuccess(handle);
+                } else {
+                    listener.onPlayerMGCommonSelfDieStatus(handle, userId, mgCommonSelfDieStatus);
+                }
+                break;
+            case SudMGPMGState.MG_COMMON_SELF_TURN_STATUS: // 9. 游戏通知app轮到玩家出手状态(2022-04-24新增)
+                SudMGPMGState.MGCommonSelfTurnStatus mgCommonSelfTurnStatus = SudJsonUtils.fromJson(dataJson, SudMGPMGState.MGCommonSelfTurnStatus.class);
+                if (listener == null) {
+                    ISudFSMStateHandleUtils.handleSuccess(handle);
+                } else {
+                    listener.onPlayerMGCommonSelfTurnStatus(handle, userId, mgCommonSelfTurnStatus);
+                }
+                break;
+            case SudMGPMGState.MG_COMMON_SELF_SELECT_STATUS: // 10. 游戏通知app玩家选择状态(2022-04-24新增)
+                SudMGPMGState.MGCommonSelfSelectStatus mgCommonSelfSelectStatus = SudJsonUtils.fromJson(dataJson, SudMGPMGState.MGCommonSelfSelectStatus.class);
+                if (listener == null) {
+                    ISudFSMStateHandleUtils.handleSuccess(handle);
+                } else {
+                    listener.onPlayerMGCommonSelfSelectStatus(handle, userId, mgCommonSelfSelectStatus);
+                }
+                break;
+            case SudMGPMGState.MG_COMMON_GAME_COUNTDOWN_TIME: // 11. 游戏通知app层当前游戏剩余时间(2022-05-23新增,目前UMO生效)
+                SudMGPMGState.MGCommonGameCountdownTime mgCommonGameCountdownTime = SudJsonUtils.fromJson(dataJson, SudMGPMGState.MGCommonGameCountdownTime.class);
+                if (listener == null) {
+                    ISudFSMStateHandleUtils.handleSuccess(handle);
+                } else {
+                    listener.onPlayerMGCommonGameCountdownTime(handle, userId, mgCommonGameCountdownTime);
+                }
+                break;
+            case SudMGPMGState.MG_COMMON_SELF_OB_STATUS: // 12. 游戏通知app层当前玩家死亡后变成ob视角(2022-08-23新增,目前狼人杀生效)
+                SudMGPMGState.MGCommonSelfObStatus mgCommonSelfObStatus = SudJsonUtils.fromJson(dataJson, SudMGPMGState.MGCommonSelfObStatus.class);
+                if (listener == null) {
+                    ISudFSMStateHandleUtils.handleSuccess(handle);
+                } else {
+                    listener.onPlayerMGCommonSelfObStatus(handle, userId, mgCommonSelfObStatus);
+                }
+                break;
+            case SudMGPMGState.MG_DG_SELECTING: // 1. 选词中状态(已修改)
+                SudMGPMGState.MGDGSelecting mgdgSelecting = SudJsonUtils.fromJson(dataJson, SudMGPMGState.MGDGSelecting.class);
+                if (listener == null) {
+                    ISudFSMStateHandleUtils.handleSuccess(handle);
+                } else {
+                    listener.onPlayerMGDGSelecting(handle, userId, mgdgSelecting);
+                }
+                break;
+            case SudMGPMGState.MG_DG_PAINTING: // 2. 作画中状态(已修改)
+                SudMGPMGState.MGDGPainting mgdgPainting = SudJsonUtils.fromJson(dataJson, SudMGPMGState.MGDGPainting.class);
+                if (listener == null) {
+                    ISudFSMStateHandleUtils.handleSuccess(handle);
+                } else {
+                    listener.onPlayerMGDGPainting(handle, userId, mgdgPainting);
+                }
+                break;
+            case SudMGPMGState.MG_DG_ERRORANSWER: // 3. 显示错误答案状态(已修改)
+                SudMGPMGState.MGDGErroranswer mgdgErroranswer = SudJsonUtils.fromJson(dataJson, SudMGPMGState.MGDGErroranswer.class);
+                if (listener == null) {
+                    ISudFSMStateHandleUtils.handleSuccess(handle);
+                } else {
+                    listener.onPlayerMGDGErroranswer(handle, userId, mgdgErroranswer);
+                }
+                break;
+            case SudMGPMGState.MG_DG_TOTALSCORE: // 4. 显示总积分状态(已修改)
+                SudMGPMGState.MGDGTotalscore mgdgTotalscore = SudJsonUtils.fromJson(dataJson, SudMGPMGState.MGDGTotalscore.class);
+                if (listener == null) {
+                    ISudFSMStateHandleUtils.handleSuccess(handle);
+                } else {
+                    listener.onPlayerMGDGTotalscore(handle, userId, mgdgTotalscore);
+                }
+                break;
+            case SudMGPMGState.MG_DG_SCORE: // 5. 本次获得积分状态(已修改)
+                SudMGPMGState.MGDGScore mgdgScore = SudJsonUtils.fromJson(dataJson, SudMGPMGState.MGDGScore.class);
+                if (listener == null) {
+                    ISudFSMStateHandleUtils.handleSuccess(handle);
+                } else {
+                    listener.onPlayerMGDGScore(handle, userId, mgdgScore);
+                }
+                break;
+            default:
+                ISudFSMStateHandleUtils.handleSuccess(handle);
+                break;
+        }
+    }
+
+    /**
+     * 获取队长userId
+     */
+    public String getCaptainUserId() {
+        return sudFSMMGCache.getCaptainUserId();
+    }
+
+    // 返回该玩家是否正在游戏中
+    public boolean playerIsPlaying(String userId) {
+        return sudFSMMGCache.playerIsPlaying(userId);
+    }
+
+    // 返回该玩家是否已准备
+    public boolean playerIsReady(String userId) {
+        return sudFSMMGCache.playerIsReady(userId);
+    }
+
+    // 返回该玩家是否已加入了游戏
+    public boolean playerIsIn(String userId) {
+        return sudFSMMGCache.playerIsIn(userId);
+    }
+
+    // 获取当前游戏中的人数
+    public int getPlayerInNumber() {
+        return sudFSMMGCache.getPlayerInNumber();
+    }
+
+    // 是否数字炸弹
+    public boolean isHitBomb() {
+        return sudFSMMGCache.isHitBomb();
+    }
+
+    // 销毁游戏
+    public void destroyMG() {
+        sudFSMMGCache.destroyMG();
+    }
+
+    /**
+     * 返回当前游戏的状态,数值参数{@link SudMGPMGState.MGCommonGameState}
+     */
+    public int getGameState() {
+        return sudFSMMGCache.getGameState();
+    }
+
+    /**
+     * 获取缓存的状态
+     */
+    public SudFSMMGCache getSudFSMMGCache() {
+        return sudFSMMGCache;
+    }
+
+}
diff --git a/common/src/main/java/com/yunbao/common/sud/decorator/SudFSMMGListener.java b/common/src/main/java/com/yunbao/common/sud/decorator/SudFSMMGListener.java
new file mode 100644
index 000000000..8b6da8ba1
--- /dev/null
+++ b/common/src/main/java/com/yunbao/common/sud/decorator/SudFSMMGListener.java
@@ -0,0 +1,901 @@
+/*
+ * Copyright © Sud.Tech
+ * https://sud.tech
+ */
+
+package com.yunbao.common.sud.decorator;
+
+import com.yunbao.common.sud.state.SudMGPMGState;
+import com.yunbao.common.utils.ISudFSMStateHandleUtils;
+
+import tech.sud.mgp.core.ISudFSMStateHandle;
+
+/**
+ * {@link SudFSMMGDecorator} 回调定义
+ */
+public interface SudFSMMGListener {
+
+    /**
+     * 游戏日志
+     * 最低版本:v1.1.30.xx
+     */
+    default void onGameLog(String str) {
+    }
+
+    /**
+     * 游戏加载进度
+     *
+     * @param stage    阶段:start=1,loading=2,end=3
+     * @param retCode  错误码:0成功
+     * @param progress 进度:[0, 100]
+     */
+    default void onGameLoadingProgress(int stage, int retCode, int progress) {
+    }
+
+    /**
+     * 游戏开始,需要实现
+     * 最低版本:v1.1.30.xx
+     */
+    void onGameStarted();
+
+    /**
+     * 游戏销毁,需要实现
+     * 最低版本:v1.1.30.xx
+     */
+    void onGameDestroyed();
+
+    /**
+     * Code过期,需要实现
+     * APP接入方需要调用handle.success或handle.fail
+     *
+     * @param dataJson {"code":"value"}
+     */
+    void onExpireCode(ISudFSMStateHandle handle, String dataJson);
+
+    /**
+     * 获取游戏View信息,需要实现
+     * APP接入方需要调用handle.success或handle.fail
+     *
+     * @param handle
+     * @param dataJson {}
+     */
+    void onGetGameViewInfo(ISudFSMStateHandle handle, String dataJson);
+
+    /**
+     * 获取游戏Config,需要实现
+     * APP接入方需要调用handle.success或handle.fail
+     *
+     * @param handle
+     * @param dataJson {}
+     *                 最低版本:v1.1.30.xx
+     */
+    void onGetGameCfg(ISudFSMStateHandle handle, String dataJson);
+
+    // region 游戏回调APP 通用状态
+    // 参考文档:https://github.com/SudTechnology/sud-mgp-doc/blob/main/Client/MG%20FSM/%E9%80%9A%E7%94%A8%E7%8A%B6%E6%80%81-%E7%8E%A9%E5%AE%B6.md
+
+    /**
+     * 1.游戏公屏消息
+     * mg_common_public_message
+     */
+    default void onGameMGCommonPublicMessage(ISudFSMStateHandle handle, SudMGPMGState.MGCommonPublicMessage model) {
+        ISudFSMStateHandleUtils.handleSuccess(handle);
+    }
+
+    /**
+     * 2. 关键词状态
+     * mg_common_key_word_to_hit
+     */
+    default void onGameMGCommonKeyWordToHit(ISudFSMStateHandle handle, SudMGPMGState.MGCommonKeyWordToHit model) {
+        ISudFSMStateHandleUtils.handleSuccess(handle);
+    }
+
+    /**
+     * 3. 游戏结算状态
+     * mg_common_game_settle
+     */
+    default void onGameMGCommonGameSettle(ISudFSMStateHandle handle, SudMGPMGState.MGCommonGameSettle model) {
+        ISudFSMStateHandleUtils.handleSuccess(handle);
+    }
+
+    /**
+     * 4. 加入游戏按钮点击状态
+     * mg_common_self_click_join_btn
+     */
+    default void onGameMGCommonSelfClickJoinBtn(ISudFSMStateHandle handle, SudMGPMGState.MGCommonSelfClickJoinBtn model) {
+        ISudFSMStateHandleUtils.handleSuccess(handle);
+    }
+
+    /**
+     * 5. 取消加入(退出)游戏按钮点击状态
+     * mg_common_self_click_cancel_join_btn
+     */
+    default void onGameMGCommonSelfClickCancelJoinBtn(ISudFSMStateHandle handle, SudMGPMGState.MGCommonSelfClickCancelJoinBtn model) {
+        ISudFSMStateHandleUtils.handleSuccess(handle);
+    }
+
+    /**
+     * 6. 准备按钮点击状态
+     * mg_common_self_click_ready_btn
+     */
+    default void onGameMGCommonSelfClickReadyBtn(ISudFSMStateHandle handle, SudMGPMGState.MGCommonSelfClickReadyBtn model) {
+        ISudFSMStateHandleUtils.handleSuccess(handle);
+    }
+
+    /**
+     * 7. 取消准备按钮点击状态
+     * mg_common_self_click_cancel_ready_btn
+     */
+    default void onGameMGCommonSelfClickCancelReadyBtn(ISudFSMStateHandle handle, SudMGPMGState.MGCommonSelfClickCancelReadyBtn model) {
+        ISudFSMStateHandleUtils.handleSuccess(handle);
+    }
+
+    /**
+     * 8. 开始游戏按钮点击状态
+     * mg_common_self_click_start_btn
+     */
+    default void onGameMGCommonSelfClickStartBtn(ISudFSMStateHandle handle, SudMGPMGState.MGCommonSelfClickStartBtn model) {
+        ISudFSMStateHandleUtils.handleSuccess(handle);
+    }
+
+    /**
+     * 9. 分享按钮点击状态
+     * mg_common_self_click_share_btn
+     */
+    default void onGameMGCommonSelfClickShareBtn(ISudFSMStateHandle handle, SudMGPMGState.MGCommonSelfClickShareBtn model) {
+        ISudFSMStateHandleUtils.handleSuccess(handle);
+    }
+
+    /**
+     * 10. 游戏状态
+     * mg_common_game_state
+     */
+    default void onGameMGCommonGameState(ISudFSMStateHandle handle, SudMGPMGState.MGCommonGameState model) {
+        ISudFSMStateHandleUtils.handleSuccess(handle);
+    }
+
+    /**
+     * 11. 结算界面关闭按钮点击状态(2021-12-27新增)
+     * mg_common_self_click_game_settle_close_btn
+     */
+    default void onGameMGCommonSelfClickGameSettleCloseBtn(ISudFSMStateHandle handle, SudMGPMGState.MGCommonSelfClickGameSettleCloseBtn model) {
+        ISudFSMStateHandleUtils.handleSuccess(handle);
+    }
+
+    /**
+     * 12. 结算界面再来一局按钮点击状态(2021-12-27新增)
+     * mg_common_self_click_game_settle_again_btn
+     */
+    default void onGameMGCommonSelfClickGameSettleAgainBtn(ISudFSMStateHandle handle, SudMGPMGState.MGCommonSelfClickGameSettleAgainBtn model) {
+        ISudFSMStateHandleUtils.handleSuccess(handle);
+    }
+
+    /**
+     * 13. 游戏上报游戏中的声音列表(2021-12-30新增,现在只支持碰碰我最强)
+     * mg_common_game_sound_list
+     */
+    default void onGameMGCommonGameSoundList(ISudFSMStateHandle handle, SudMGPMGState.MGCommonGameSoundList model) {
+        ISudFSMStateHandleUtils.handleSuccess(handle);
+    }
+
+    /**
+     * 14. 游通知app层播放声音(2021-12-30新增,现在只支持碰碰我最强)
+     * mg_common_game_sound
+     */
+    default void onGameMGCommonGameSound(ISudFSMStateHandle handle, SudMGPMGState.MGCommonGameSound model) {
+        ISudFSMStateHandleUtils.handleSuccess(handle);
+    }
+
+    /**
+     * 15. 游戏通知app层播放背景音乐状态(2022-01-07新增,现在只支持碰碰我最强)
+     * mg_common_game_bg_music_state
+     */
+    default void onGameMGCommonGameBgMusicState(ISudFSMStateHandle handle, SudMGPMGState.MGCommonGameBgMusicState model) {
+        ISudFSMStateHandleUtils.handleSuccess(handle);
+    }
+
+    /**
+     * 16. 游戏通知app层播放音效的状态(2022-01-07新增,现在只支持碰碰我最强)
+     * mg_common_game_sound_state
+     */
+    default void onGameMGCommonGameSoundState(ISudFSMStateHandle handle, SudMGPMGState.MGCommonGameSoundState model) {
+        ISudFSMStateHandleUtils.handleSuccess(handle);
+    }
+
+    /**
+     * 17. ASR状态(开启和关闭语音识别状态,v1.1.45.xx 版本新增)
+     * mg_common_game_asr
+     */
+    default void onGameMGCommonGameASR(ISudFSMStateHandle handle, SudMGPMGState.MGCommonGameASR model) {
+        ISudFSMStateHandleUtils.handleSuccess(handle);
+    }
+
+    /**
+     * 18. 麦克风状态(2022-02-08新增)
+     * mg_common_self_microphone
+     */
+    default void onGameMGCommonSelfMicrophone(ISudFSMStateHandle handle, SudMGPMGState.MGCommonSelfMicrophone model) {
+        ISudFSMStateHandleUtils.handleSuccess(handle);
+    }
+
+    /**
+     * 19. 耳机(听筒,扬声器)状态(2022-02-08新增)
+     * mg_common_self_headphone
+     */
+    default void onGameMGCommonSelfHeadphone(ISudFSMStateHandle handle, SudMGPMGState.MGCommonSelfHeadphone model) {
+        ISudFSMStateHandleUtils.handleSuccess(handle);
+    }
+
+    /**
+     * 20. App通用状态操作结果错误码(2022-05-10新增)
+     * mg_common_app_common_self_x_resp
+     */
+    default void onGameMGCommonAPPCommonSelfXResp(ISudFSMStateHandle handle, SudMGPMGState.MGCommonAPPCommonSelfXResp model) {
+        ISudFSMStateHandleUtils.handleSuccess(handle);
+    }
+
+    /**
+     * 21. 游戏通知app层添加陪玩机器人是否成功(2022-05-17新增)
+     * mg_common_game_add_ai_players
+     */
+    default void onGameMGCommonGameAddAIPlayers(ISudFSMStateHandle handle, SudMGPMGState.MGCommonGameAddAIPlayers model) {
+        ISudFSMStateHandleUtils.handleSuccess(handle);
+    }
+
+    /**
+     * 22. 游戏通知app层添当前网络连接状态(2022-06-21新增)
+     * mg_common_game_network_state
+     */
+    default void onGameMGCommonGameNetworkState(ISudFSMStateHandle handle, SudMGPMGState.MGCommonGameNetworkState model) {
+        ISudFSMStateHandleUtils.handleSuccess(handle);
+    }
+
+    /**
+     * 23. 游戏通知app获取积分
+     * mg_common_game_score
+     */
+    default void onGameMGCommonGameGetScore(ISudFSMStateHandle handle, SudMGPMGState.MGCommonGameGetScore model) {
+        ISudFSMStateHandleUtils.handleSuccess(handle);
+    }
+
+    /**
+     * 24. 游戏通知app带入积分
+     * mg_common_game_set_score
+     */
+    default void onGameMGCommonGameSetScore(ISudFSMStateHandle handle, SudMGPMGState.MGCommonGameSetScore model) {
+        ISudFSMStateHandleUtils.handleSuccess(handle);
+    }
+
+    /**
+     * 25. 创建订单
+     * mg_common_game_create_order
+     */
+    default void onGameMGCommonGameCreateOrder(ISudFSMStateHandle handle, SudMGPMGState.MGCommonGameCreateOrder model) {
+        ISudFSMStateHandleUtils.handleSuccess(handle);
+    }
+
+    /**
+     * 26. 游戏通知app玩家角色(仅对狼人杀有效)
+     * mg_common_player_role_id
+     */
+    default void onGameMGCommonPlayerRoleId(ISudFSMStateHandle handle, SudMGPMGState.MGCommonPlayerRoleId model) {
+        ISudFSMStateHandleUtils.handleSuccess(handle);
+    }
+
+    /**
+     * 27. 游戏通知app玩家被扔便便(你画我猜,你说我猜,友尽闯关有效)
+     * mg_common_self_click_poop
+     */
+    default void onGameMGCommonSelfClickPoop(ISudFSMStateHandle handle, SudMGPMGState.MGCommonSelfClickPoop model) {
+        ISudFSMStateHandleUtils.handleSuccess(handle);
+    }
+
+    /**
+     * 28. 游戏通知app玩家被点赞(你画我猜,你说我猜,友尽闯关有效)
+     * mg_common_self_click_good
+     */
+    default void onGameMGCommonSelfClickGood(ISudFSMStateHandle handle, SudMGPMGState.MGCommonSelfClickGood model) {
+        ISudFSMStateHandleUtils.handleSuccess(handle);
+    }
+
+    /**
+     * 29. 游戏通知app游戏FPS(仅对碰碰,多米诺骨牌,飞镖达人生效)
+     * mg_common_game_fps
+     */
+    default void onGameMGCommonGameFps(ISudFSMStateHandle handle, SudMGPMGState.MGCommonGameFps model) {
+        ISudFSMStateHandleUtils.handleSuccess(handle);
+    }
+
+    /**
+     * 30. 游戏通知app游戏弹框
+     * mg_common_alert
+     */
+    default void onGameMGCommonAlert(ISudFSMStateHandle handle, SudMGPMGState.MGCommonAlert model) {
+        ISudFSMStateHandleUtils.handleSuccess(handle);
+    }
+
+    /**
+     * 31. 游戏通知app最坑队友(只支持友尽闯关)
+     * mg_common_worst_teammate
+     */
+    default void onGameMGCommonWorstTeammate(ISudFSMStateHandle handle, SudMGPMGState.MGCommonWorstTeammate model) {
+        ISudFSMStateHandleUtils.handleSuccess(handle);
+    }
+
+    /**
+     * 32. 游戏通知app因玩家逃跑导致游戏结束(只支持友尽闯关)
+     * mg_common_game_over_tip
+     */
+    default void onGameMGCommonGameOverTip(ISudFSMStateHandle handle, SudMGPMGState.MGCommonGameOverTip model) {
+        ISudFSMStateHandleUtils.handleSuccess(handle);
+    }
+
+    /**
+     * 33. 游戏通知app玩家颜色(只支持友尽闯关)
+     * mg_common_game_player_color
+     */
+    default void onGameMGCommonGamePlayerColor(ISudFSMStateHandle handle, SudMGPMGState.MGCommonGamePlayerColor model) {
+        ISudFSMStateHandleUtils.handleSuccess(handle);
+    }
+
+    /**
+     * 34. 游戏通知app玩家头像的坐标(只支持ludo)
+     * mg_common_game_player_icon_position
+     */
+    default void onGameMGCommonGamePlayerIconPosition(ISudFSMStateHandle handle, SudMGPMGState.MGCommonGamePlayerIconPosition model) {
+        ISudFSMStateHandleUtils.handleSuccess(handle);
+    }
+
+    /**
+     * 35. 游戏通知app退出游戏(只支持teenpattipro 与 德州pro)
+     * mg_common_self_click_exit_game_btn
+     */
+    default void onGameMGCommonSelfClickExitGameBtn(ISudFSMStateHandle handle, SudMGPMGState.MGCommonSelfClickExitGameBtn model) {
+        ISudFSMStateHandleUtils.handleSuccess(handle);
+    }
+
+    /**
+     * 36. 游戏通知app是否要开启带入积分(只支持teenpattipro 与 德州pro)
+     * mg_common_game_is_app_chip
+     */
+    default void onGameMGCommonGameIsAppChip(ISudFSMStateHandle handle, SudMGPMGState.MGCommonGameIsAppChip model) {
+        ISudFSMStateHandleUtils.handleSuccess(handle);
+    }
+
+    /**
+     * 37. 游戏通知app当前游戏的设置信息(只支持德州pro,teenpatti pro)
+     * mg_common_game_rule
+     */
+    default void onGameMGCommonGameRule(ISudFSMStateHandle handle, SudMGPMGState.MGCommonGameRule model) {
+        ISudFSMStateHandleUtils.handleSuccess(handle);
+    }
+
+    /**
+     * 38. 游戏通知app进行玩法设置(只支持德州pro,teenpatti pro)
+     * mg_common_game_settings
+     */
+    default void onGameMGCommonGameSettings(ISudFSMStateHandle handle, SudMGPMGState.MGCommonGameSettings model) {
+        ISudFSMStateHandleUtils.handleSuccess(handle);
+    }
+
+    /**
+     * 39. 游戏通知app钱币不足(只支持德州pro,teenpatti pro)
+     * mg_common_game_money_not_enough
+     */
+    default void onGameMGCommonGameMoneyNotEnough(ISudFSMStateHandle handle, SudMGPMGState.MGCommonGameMoneyNotEnough model) {
+        ISudFSMStateHandleUtils.handleSuccess(handle);
+    }
+
+    /**
+     * 40. 游戏通知app下发定制ui配置表(只支持ludo)
+     * mg_common_game_ui_custom_config
+     */
+    default void onGameMGCommonGameUiCustomConfig(ISudFSMStateHandle handle, SudMGPMGState.MGCommonGameUiCustomConfig model) {
+        ISudFSMStateHandleUtils.handleSuccess(handle);
+    }
+
+    /**
+     * 41. 设置app提供给游戏可点击区域(赛车)
+     * mg_common_set_click_rect
+     */
+    default void onGameMGCommonSetClickRect(ISudFSMStateHandle handle, SudMGPMGState.MGCommonSetClickRect model) {
+        ISudFSMStateHandleUtils.handleSuccess(handle);
+    }
+
+    /**
+     * 42. 通知app提供对应uids列表玩家的数据(赛车)
+     * mg_common_users_info
+     */
+    default void onGameMGCommonUsersInfo(ISudFSMStateHandle handle, SudMGPMGState.MGCommonUsersInfo model) {
+        ISudFSMStateHandleUtils.handleSuccess(handle);
+    }
+
+    /**
+     * 43. 通知app游戏前期准备完成(赛车)
+     * mg_common_game_prepare_finish
+     */
+    default void onGameMGCommonGamePrepareFinish(ISudFSMStateHandle handle, SudMGPMGState.MGCommonGamePrepareFinish model) {
+        ISudFSMStateHandleUtils.handleSuccess(handle);
+    }
+
+    /**
+     * 44. 通知app游戏主界面已显示(赛车)
+     * mg_common_show_game_scene
+     */
+    default void onGameMGCommonShowGameScene(ISudFSMStateHandle handle, SudMGPMGState.MGCommonShowGameScene model) {
+        ISudFSMStateHandleUtils.handleSuccess(handle);
+    }
+
+    /**
+     * 45. 通知app游戏主界面已隐藏(赛车)
+     * mg_common_hide_game_scene
+     */
+    default void onGameMGCommonHideGameScene(ISudFSMStateHandle handle, SudMGPMGState.MGCommonHideGameScene model) {
+        ISudFSMStateHandleUtils.handleSuccess(handle);
+    }
+    // endregion 游戏回调APP 通用状态
+
+    // region 游戏回调APP 玩家状态
+
+    /**
+     * 1.加入状态(已修改)
+     * mg_common_player_in
+     */
+    default void onPlayerMGCommonPlayerIn(ISudFSMStateHandle handle, String userId, SudMGPMGState.MGCommonPlayerIn model) {
+        ISudFSMStateHandleUtils.handleSuccess(handle);
+    }
+
+    /**
+     * 2.准备状态(已修改)
+     * mg_common_player_ready
+     */
+    default void onPlayerMGCommonPlayerReady(ISudFSMStateHandle handle, String userId, SudMGPMGState.MGCommonPlayerReady model) {
+        ISudFSMStateHandleUtils.handleSuccess(handle);
+    }
+
+    /**
+     * 3.队长状态(已修改)
+     * mg_common_player_captain
+     */
+    default void onPlayerMGCommonPlayerCaptain(ISudFSMStateHandle handle, String userId, SudMGPMGState.MGCommonPlayerCaptain model) {
+        ISudFSMStateHandleUtils.handleSuccess(handle);
+    }
+
+    /**
+     * 4.游戏状态(已修改)
+     * mg_common_player_playing
+     */
+    default void onPlayerMGCommonPlayerPlaying(ISudFSMStateHandle handle, String userId, SudMGPMGState.MGCommonPlayerPlaying model) {
+        ISudFSMStateHandleUtils.handleSuccess(handle);
+    }
+
+    /**
+     * 5.玩家在线状态
+     * mg_common_player_online
+     */
+    default void onPlayerMGCommonPlayerOnline(ISudFSMStateHandle handle, String userId, SudMGPMGState.MGCommonPlayerOnline model) {
+        ISudFSMStateHandleUtils.handleSuccess(handle);
+    }
+
+    /**
+     * 6.玩家换游戏位状态
+     * mg_common_player_change_seat
+     */
+    default void onPlayerMGCommonPlayerChangeSeat(ISudFSMStateHandle handle, String userId, SudMGPMGState.MGCommonPlayerChangeSeat model) {
+        ISudFSMStateHandleUtils.handleSuccess(handle);
+    }
+
+    /**
+     * 7. 游戏通知app点击玩家头像
+     * mg_common_self_click_game_player_icon
+     */
+    default void onPlayerMGCommonSelfClickGamePlayerIcon(ISudFSMStateHandle handle, String userId, SudMGPMGState.MGCommonSelfClickGamePlayerIcon model) {
+        ISudFSMStateHandleUtils.handleSuccess(handle);
+    }
+
+    /**
+     * 8. 游戏通知app玩家死亡状态(2022-04-24新增)
+     * mg_common_self_die_status
+     */
+    default void onPlayerMGCommonSelfDieStatus(ISudFSMStateHandle handle, String userId, SudMGPMGState.MGCommonSelfDieStatus model) {
+        ISudFSMStateHandleUtils.handleSuccess(handle);
+    }
+
+    /**
+     * 9. 游戏通知app轮到玩家出手状态(2022-04-24新增)
+     * mg_common_self_turn_status
+     */
+    default void onPlayerMGCommonSelfTurnStatus(ISudFSMStateHandle handle, String userId, SudMGPMGState.MGCommonSelfTurnStatus model) {
+        ISudFSMStateHandleUtils.handleSuccess(handle);
+    }
+
+    /**
+     * 10. 游戏通知app玩家选择状态(2022-04-24新增)
+     * mg_common_self_select_status
+     */
+    default void onPlayerMGCommonSelfSelectStatus(ISudFSMStateHandle handle, String userId, SudMGPMGState.MGCommonSelfSelectStatus model) {
+        ISudFSMStateHandleUtils.handleSuccess(handle);
+    }
+
+    /**
+     * 11. 游戏通知app层当前游戏剩余时间(2022-05-23新增,目前UMO生效)
+     * mg_common_game_countdown_time
+     */
+    default void onPlayerMGCommonGameCountdownTime(ISudFSMStateHandle handle, String userId, SudMGPMGState.MGCommonGameCountdownTime model) {
+        ISudFSMStateHandleUtils.handleSuccess(handle);
+    }
+
+    /**
+     * 12. 游戏通知app层当前玩家死亡后变成ob视角(2022-08-23新增,目前狼人杀生效)
+     * mg_common_self_ob_status
+     */
+    default void onPlayerMGCommonSelfObStatus(ISudFSMStateHandle handle, String userId, SudMGPMGState.MGCommonSelfObStatus model) {
+        ISudFSMStateHandleUtils.handleSuccess(handle);
+    }
+
+    // endregion 游戏回调APP 玩家状态
+
+    // region 游戏回调APP 玩家状态 你画我猜
+    // 参考文档:https://github.com/SudTechnology/sud-mgp-doc/blob/main/Client/MG%20FSM/%E4%BD%A0%E7%94%BB%E6%88%91%E7%8C%9C.md
+
+    /**
+     * 1. 选词中状态(已修改)
+     * mg_dg_selecting
+     */
+    default void onPlayerMGDGSelecting(ISudFSMStateHandle handle, String userId, SudMGPMGState.MGDGSelecting model) {
+        ISudFSMStateHandleUtils.handleSuccess(handle);
+    }
+
+    /**
+     * 2. 作画中状态(已修改)
+     * mg_dg_painting
+     */
+    default void onPlayerMGDGPainting(ISudFSMStateHandle handle, String userId, SudMGPMGState.MGDGPainting model) {
+        ISudFSMStateHandleUtils.handleSuccess(handle);
+    }
+
+    /**
+     * 3. 显示错误答案状态(已修改)
+     * mg_dg_erroranswer
+     */
+    default void onPlayerMGDGErroranswer(ISudFSMStateHandle handle, String userId, SudMGPMGState.MGDGErroranswer model) {
+        ISudFSMStateHandleUtils.handleSuccess(handle);
+    }
+
+    /**
+     * 4. 显示总积分状态(已修改)
+     * mg_dg_totalscore
+     */
+    default void onPlayerMGDGTotalscore(ISudFSMStateHandle handle, String userId, SudMGPMGState.MGDGTotalscore model) {
+        ISudFSMStateHandleUtils.handleSuccess(handle);
+    }
+
+    /**
+     * 5. 本次获得积分状态(已修改)
+     * mg_dg_score
+     */
+    default void onPlayerMGDGScore(ISudFSMStateHandle handle, String userId, SudMGPMGState.MGDGScore model) {
+        ISudFSMStateHandleUtils.handleSuccess(handle);
+    }
+
+    // endregion 游戏回调APP 玩家状态 你画我猜
+
+    // region 游戏回调APP 通用状态 元宇宙砂砂舞
+
+    /**
+     * 1. 元宇宙砂砂舞指令回调
+     * mg_common_game_disco_action
+     */
+    default void onGameMGCommonGameDiscoAction(ISudFSMStateHandle handle, SudMGPMGState.MGCommonGameDiscoAction model) {
+        ISudFSMStateHandleUtils.handleSuccess(handle);
+    }
+
+    /**
+     * 2. 元宇宙砂砂舞指令动作结束通知
+     * mg_common_game_disco_action_end
+     */
+    default void onGameMGCommonGameDiscoActionEnd(ISudFSMStateHandle handle, SudMGPMGState.MGCommonGameDiscoActionEnd model) {
+        ISudFSMStateHandleUtils.handleSuccess(handle);
+    }
+    // endregion 游戏回调APP 通用状态 元宇宙砂砂舞
+
+    // region 游戏回调APP 通用状态 定制火箭
+
+    /**
+     * 1. 礼物配置文件(火箭)
+     * mg_custom_rocket_config
+     */
+    default void onGameMGCustomRocketConfig(ISudFSMStateHandle handle, SudMGPMGState.MGCustomRocketConfig model) {
+        ISudFSMStateHandleUtils.handleSuccess(handle);
+    }
+
+    /**
+     * 2. 拥有模型列表(火箭)
+     * mg_custom_rocket_model_list
+     */
+    default void onGameMGCustomRocketModelList(ISudFSMStateHandle handle, SudMGPMGState.MGCustomRocketModelList model) {
+        ISudFSMStateHandleUtils.handleSuccess(handle);
+    }
+
+    /**
+     * 3. 拥有组件列表(火箭)
+     * mg_custom_rocket_component_list
+     */
+    default void onGameMGCustomRocketComponentList(ISudFSMStateHandle handle, SudMGPMGState.MGCustomRocketComponentList model) {
+        ISudFSMStateHandleUtils.handleSuccess(handle);
+    }
+
+    /**
+     * 4. 获取用户信息(火箭)
+     * mg_custom_rocket_user_info
+     */
+    default void onGameMGCustomRocketUserInfo(ISudFSMStateHandle handle, SudMGPMGState.MGCustomRocketUserInfo model) {
+        ISudFSMStateHandleUtils.handleSuccess(handle);
+    }
+
+    /**
+     * 5. 订单记录列表(火箭)
+     * mg_custom_rocket_order_record_list
+     */
+    default void onGameMGCustomRocketOrderRecordList(ISudFSMStateHandle handle, SudMGPMGState.MGCustomRocketOrderRecordList model) {
+        ISudFSMStateHandleUtils.handleSuccess(handle);
+    }
+
+    /**
+     * 6. 展馆内列表(火箭)
+     * mg_custom_rocket_room_record_list
+     */
+    default void onGameMGCustomRocketRoomRecordList(ISudFSMStateHandle handle, SudMGPMGState.MGCustomRocketRoomRecordList model) {
+        ISudFSMStateHandleUtils.handleSuccess(handle);
+    }
+
+    /**
+     * 7. 展馆内玩家送出记录(火箭)
+     * mg_custom_rocket_user_record_list
+     */
+    default void onGameMGCustomRocketUserRecordList(ISudFSMStateHandle handle, SudMGPMGState.MGCustomRocketUserRecordList model) {
+        ISudFSMStateHandleUtils.handleSuccess(handle);
+    }
+
+    /**
+     * 8. 设置默认模型(火箭)
+     * mg_custom_rocket_set_default_model
+     */
+    default void onGameMGCustomRocketSetDefaultModel(ISudFSMStateHandle handle, SudMGPMGState.MGCustomRocketSetDefaultModel model) {
+        ISudFSMStateHandleUtils.handleSuccess(handle);
+    }
+
+    /**
+     * 9. 动态计算一键发送价格(火箭)
+     * mg_custom_rocket_dynamic_fire_price
+     */
+    default void onGameMGCustomRocketDynamicFirePrice(ISudFSMStateHandle handle, SudMGPMGState.MGCustomRocketDynamicFirePrice model) {
+        ISudFSMStateHandleUtils.handleSuccess(handle);
+    }
+
+    /**
+     * 10. 一键发送(火箭)
+     * mg_custom_rocket_fire_model
+     */
+    default void onGameMGCustomRocketFireModel(ISudFSMStateHandle handle, SudMGPMGState.MGCustomRocketFireModel model) {
+        ISudFSMStateHandleUtils.handleSuccess(handle);
+    }
+
+    /**
+     * 11. 新组装模型(火箭)
+     * mg_custom_rocket_create_model
+     */
+    default void onGameMGCustomRocketCreateModel(ISudFSMStateHandle handle, SudMGPMGState.MGCustomRocketCreateModel model) {
+        ISudFSMStateHandleUtils.handleSuccess(handle);
+    }
+
+    /**
+     * 12. 模型更换组件(火箭)
+     * mg_custom_rocket_replace_component
+     */
+    default void onGameMGCustomRocketReplaceComponent(ISudFSMStateHandle handle, SudMGPMGState.MGCustomRocketReplaceComponent model) {
+        ISudFSMStateHandleUtils.handleSuccess(handle);
+    }
+
+    /**
+     * 13. 购买组件(火箭)
+     * mg_custom_rocket_buy_component
+     */
+    default void onGameMGCustomRocketBuyComponent(ISudFSMStateHandle handle, SudMGPMGState.MGCustomRocketBuyComponent model) {
+        ISudFSMStateHandleUtils.handleSuccess(handle);
+    }
+
+    /**
+     * 14. 播放效果开始(火箭)
+     * mg_custom_rocket_play_effect_start
+     */
+    default void onGameMGCustomRocketPlayEffectStart(ISudFSMStateHandle handle, SudMGPMGState.MGCustomRocketPlayEffectStart model) {
+        ISudFSMStateHandleUtils.handleSuccess(handle);
+    }
+
+    /**
+     * 15. 播放效果完成(火箭)
+     * mg_custom_rocket_play_effect_finish
+     */
+    default void onGameMGCustomRocketPlayEffectFinish(ISudFSMStateHandle handle, SudMGPMGState.MGCustomRocketPlayEffectFinish model) {
+        ISudFSMStateHandleUtils.handleSuccess(handle);
+    }
+
+    /**
+     * 16. 验证签名合规(火箭)
+     * mg_custom_rocket_verify_sign
+     */
+    default void onGameMGCustomRocketVerifySign(ISudFSMStateHandle handle, SudMGPMGState.MGCustomRocketVerifySign model) {
+        ISudFSMStateHandleUtils.handleSuccess(handle);
+    }
+
+    /**
+     * 17. 上传icon(火箭)
+     * mg_custom_rocket_upload_model_icon
+     */
+    default void onGameMGCustomRocketUploadModelIcon(ISudFSMStateHandle handle, SudMGPMGState.MGCustomRocketUploadModelIcon model) {
+        ISudFSMStateHandleUtils.handleSuccess(handle);
+    }
+
+    /**
+     * 18. 前期准备完成(火箭)
+     * mg_custom_rocket_prepare_finish
+     */
+    default void onGameMGCustomRocketPrepareFinish(ISudFSMStateHandle handle, SudMGPMGState.MGCustomRocketPrepareFinish model) {
+        ISudFSMStateHandleUtils.handleSuccess(handle);
+    }
+
+    /**
+     * 19. 火箭主界面已显示(火箭)
+     * mg_custom_rocket_show_game_scene
+     */
+    default void onGameMGCustomRocketShowGameScene(ISudFSMStateHandle handle, SudMGPMGState.MGCustomRocketShowGameScene model) {
+        ISudFSMStateHandleUtils.handleSuccess(handle);
+    }
+
+    /**
+     * 20. 火箭主界面已隐藏(火箭)
+     * mg_custom_rocket_hide_game_scene
+     */
+    default void onGameMGCustomRocketHideGameScene(ISudFSMStateHandle handle, SudMGPMGState.MGCustomRocketHideGameScene model) {
+        ISudFSMStateHandleUtils.handleSuccess(handle);
+    }
+
+    /**
+     * 21. 点击锁住组件(火箭)
+     * mg_custom_rocket_click_lock_component
+     */
+    default void onGameMGCustomRocketClickLockComponent(ISudFSMStateHandle handle, SudMGPMGState.MGCustomRocketClickLockComponent model) {
+        ISudFSMStateHandleUtils.handleSuccess(handle);
+    }
+
+    /**
+     * 22. 火箭效果飞行点击(火箭)
+     * mg_custom_rocket_fly_click
+     */
+    default void onGameMGCustomRocketFlyClick(ISudFSMStateHandle handle, SudMGPMGState.MGCustomRocketFlyClick model) {
+        ISudFSMStateHandleUtils.handleSuccess(handle);
+    }
+
+    /**
+     * 23. 火箭效果飞行结束(火箭)
+     * mg_custom_rocket_fly_end
+     */
+    default void onGameMGCustomRocketFlyEnd(ISudFSMStateHandle handle, SudMGPMGState.MGCustomRocketFlyEnd model) {
+        ISudFSMStateHandleUtils.handleSuccess(handle);
+    }
+
+    /**
+     * 24. 设置点击区域(火箭)
+     * mg_custom_rocket_set_click_rect
+     */
+    default void onGameMGCustomRocketSetClickRect(ISudFSMStateHandle handle, SudMGPMGState.MGCustomRocketSetClickRect model) {
+        ISudFSMStateHandleUtils.handleSuccess(handle);
+    }
+
+    /**
+     * 25. 颜色和签名自定义改到装配间的模式,保存颜色或签名
+     * mg_custom_rocket_save_sign_color
+     */
+    default void onGameMGCustomRocketSaveSignColor(ISudFSMStateHandle handle, SudMGPMGState.MGCustomRocketSaveSignColor model) {
+        ISudFSMStateHandleUtils.handleSuccess(handle);
+    }
+    // endregion 游戏回调APP 通用状态 定制火箭
+
+    // region 游戏回调APP 通用状态 棒球
+
+    /**
+     * 1. 查询排行榜数据(棒球)
+     * mg_baseball_ranking
+     */
+    default void onGameMGBaseballRanking(ISudFSMStateHandle handle, SudMGPMGState.MGBaseballRanking model) {
+        ISudFSMStateHandleUtils.handleSuccess(handle);
+    }
+
+    /**
+     * 2. 查询我的排名(棒球)
+     * mg_baseball_my_ranking
+     */
+    default void onGameMGBaseballMyRanking(ISudFSMStateHandle handle, SudMGPMGState.MGBaseballMyRanking model) {
+        ISudFSMStateHandleUtils.handleSuccess(handle);
+    }
+
+    /**
+     * 3. 查询当前距离我的前后玩家数据(棒球)
+     * mg_baseball_range_info
+     */
+    default void onGameMGBaseballRangeInfo(ISudFSMStateHandle handle, SudMGPMGState.MGBaseballRangeInfo model) {
+        ISudFSMStateHandleUtils.handleSuccess(handle);
+    }
+
+    /**
+     * 4. 设置app提供给游戏可点击区域(棒球)
+     * mg_baseball_set_click_rect
+     */
+    default void onGameMGBaseballSetClickRect(ISudFSMStateHandle handle, SudMGPMGState.MGBaseballSetClickRect model) {
+        ISudFSMStateHandleUtils.handleSuccess(handle);
+    }
+
+    /**
+     * 5. 前期准备完成(棒球)
+     * mg_baseball_prepare_finish
+     */
+    default void onGameMGBaseballPrepareFinish(ISudFSMStateHandle handle, SudMGPMGState.MGBaseballPrepareFinish model) {
+        ISudFSMStateHandleUtils.handleSuccess(handle);
+    }
+
+    /**
+     * 6. 主界面已显示(棒球)
+     * mg_baseball_show_game_scene
+     */
+    default void onGameMGBaseballShowGameScene(ISudFSMStateHandle handle, SudMGPMGState.MGBaseballShowGameScene model) {
+        ISudFSMStateHandleUtils.handleSuccess(handle);
+    }
+
+    /**
+     * 7. 主界面已隐藏(棒球)
+     * mg_baseball_hide_game_scene
+     */
+    default void onGameMGBaseballHideGameScene(ISudFSMStateHandle handle, SudMGPMGState.MGBaseballHideGameScene model) {
+        ISudFSMStateHandleUtils.handleSuccess(handle);
+    }
+
+    /**
+     * 8. 获取文本配置数据(棒球)
+     * mg_baseball_text_config
+     */
+    default void onGameMGBaseballTextConfig(ISudFSMStateHandle handle, SudMGPMGState.MGBaseballTextConfig model) {
+        ISudFSMStateHandleUtils.handleSuccess(handle);
+    }
+    // endregion 游戏回调APP 通用状态 棒球
+
+    /**
+     * 游戏状态变化
+     * 透传游戏向App发送的游戏通用状态消息
+     * **********使用此方法可先看下此方法的使用逻辑*************
+     *
+     * @param handle   回调操作
+     * @param state    状态命令
+     * @param dataJson 状态值
+     * @return 返回true,表示由此方法接管该状态处理,此时需注意调用:ISudFSMStateHandleUtils.handleSuccess(handle);
+     */
+    default boolean onGameStateChange(ISudFSMStateHandle handle, String state, String dataJson) {
+        return false;
+    }
+
+    /**
+     * 游戏玩家状态变化
+     * 透传游戏向App发送的玩家状态变化
+     * **********使用此方法可先看下此方法的使用逻辑*************
+     *
+     * @param handle   回调操作
+     * @param userId   用户Id
+     * @param state    状态命令
+     * @param dataJson 状态值
+     * @return 返回true,表示由此方法接管该状态处理,此时需注意调用:ISudFSMStateHandleUtils.handleSuccess(handle);
+     */
+    default boolean onPlayerStateChange(ISudFSMStateHandle handle, String userId, String state, String dataJson) {
+        return false;
+    }
+
+}
diff --git a/common/src/main/java/com/yunbao/common/sud/decorator/SudFSTAPPDecorator.java b/common/src/main/java/com/yunbao/common/sud/decorator/SudFSTAPPDecorator.java
new file mode 100644
index 000000000..b9111098c
--- /dev/null
+++ b/common/src/main/java/com/yunbao/common/sud/decorator/SudFSTAPPDecorator.java
@@ -0,0 +1,446 @@
+/*
+ * Copyright © Sud.Tech
+ * https://sud.tech
+ */
+
+package com.yunbao.common.sud.decorator;
+
+import com.yunbao.common.sud.state.SudMGPAPPState;
+import com.yunbao.common.utils.SudJsonUtils;
+
+import java.nio.ByteBuffer;
+import java.util.List;
+
+import tech.sud.mgp.core.ISudFSTAPP;
+import tech.sud.mgp.core.ISudListenerNotifyStateChange;
+
+/**
+ * ISudFSTAPP的装饰类,接近于业务
+ * 参考文档:https://docs.sud.tech/zh-CN/app/Client/API/ISudFSTAPP.html
+ * 注意:
+ * 1,向游戏侧发送状态之后,不能立即调用destroyMG()方法,也不能立即finish Activity。例如:{@link SudFSTAPPDecorator#notifyAPPCommonSelfEnd()}
+ */
+public class SudFSTAPPDecorator {
+
+    /**
+     * APP调用游戏的接口
+     */
+    private ISudFSTAPP iSudFSTAPP;
+
+    /**
+     * 设置app调用sdk的对象
+     *
+     * @param iSudFSTAPP
+     */
+    public void setISudFSTAPP(ISudFSTAPP iSudFSTAPP) {
+        this.iSudFSTAPP = iSudFSTAPP;
+    }
+
+    // region 状态通知,ISudFSTAPP.notifyStateChange
+
+    /**
+     * 发送
+     * 1. 加入状态
+     *
+     * @param isIn         true 加入游戏,false 退出游戏
+     * @param seatIndex    加入的游戏位(座位号) 默认传seatIndex = -1 随机加入,seatIndex 从0开始,不可大于座位数
+     * @param isSeatRandom 默认为ture, 带有游戏位(座位号)的时候,如果游戏位(座位号)已经被占用,是否随机分配一个空位坐下 isSeatRandom=true 随机分配空位坐下,isSeatRandom=false 不随机分配
+     * @param teamId       不支持分队的游戏:数值填1;支持分队的游戏:数值填1或2(两支队伍);
+     */
+    public void notifyAPPCommonSelfIn(boolean isIn, int seatIndex, boolean isSeatRandom, int teamId) {
+        ISudFSTAPP iSudFSTAPP = this.iSudFSTAPP;
+        if (iSudFSTAPP != null) {
+            SudMGPAPPState.APPCommonSelfIn state = new SudMGPAPPState.APPCommonSelfIn();
+            state.isIn = isIn;
+            state.seatIndex = seatIndex;
+            state.isSeatRandom = isSeatRandom;
+            state.teamId = teamId;
+            iSudFSTAPP.notifyStateChange(SudMGPAPPState.APP_COMMON_SELF_IN, SudJsonUtils.toJson(state), null);
+        }
+    }
+
+    /**
+     * 发送
+     * 2. 准备状态
+     * 用户(本人)准备/取消准备
+     *
+     * @param isReady true 准备,false 取消准备
+     */
+    public void notifyAPPCommonSelfReady(boolean isReady) {
+        ISudFSTAPP iSudFSTAPP = this.iSudFSTAPP;
+        if (iSudFSTAPP != null) {
+            SudMGPAPPState.APPCommonSelfReady state = new SudMGPAPPState.APPCommonSelfReady();
+            state.isReady = isReady;
+            iSudFSTAPP.notifyStateChange(SudMGPAPPState.APP_COMMON_SELF_READY, SudJsonUtils.toJson(state), null);
+        }
+    }
+
+    /**
+     * 发送
+     * 3. 游戏状态 模型
+     * 用户游戏状态,如果用户在游戏中,建议:
+     * a.空出屏幕中心区:
+     * 关闭全屏礼物特效;
+     * b.部分强操作类小游戏(spaceMax为true),尽量收缩原生UI,给游戏留出尽量大的操作空间:
+     * 收缩公屏;
+     * 收缩麦位;
+     * 如果不在游戏中,则恢复。
+     *
+     * @param isPlaying            true 开始游戏,false 结束游戏
+     * @param reportGameInfoExtras string类型,Https服务回调report_game_info参数,最大长度1024字节,超过则截断(2022-01-21)
+     */
+    public void notifyAPPCommonSelfPlaying(boolean isPlaying, String reportGameInfoExtras, String reportGameInfoKey) {
+        ISudFSTAPP iSudFSTAPP = this.iSudFSTAPP;
+        if (iSudFSTAPP != null) {
+            SudMGPAPPState.APPCommonSelfPlaying state = new SudMGPAPPState.APPCommonSelfPlaying();
+            state.isPlaying = isPlaying;
+            state.reportGameInfoExtras = reportGameInfoExtras;
+            state.reportGameInfoKey = reportGameInfoKey;
+            iSudFSTAPP.notifyStateChange(SudMGPAPPState.APP_COMMON_SELF_PLAYING, SudJsonUtils.toJson(state), null);
+        }
+    }
+
+    /**
+     * 发送
+     * 4. 队长状态
+     * 用户是否为队长,队长在游戏中会有开始游戏的权利。
+     * 发送此状态后,会把队长身份转移到另一名用户身上。
+     * 注意:必须是队长发送才有效果。可通过{@link SudFSMMGDecorator#getCaptainUserId()}拿到当前队长id
+     *
+     * @param curCaptainUID 必填,指定队长uid
+     */
+    public void notifyAPPCommonSelfCaptain(String curCaptainUID) {
+        ISudFSTAPP iSudFSTAPP = this.iSudFSTAPP;
+        if (iSudFSTAPP != null) {
+            SudMGPAPPState.APPCommonSelfCaptain state = new SudMGPAPPState.APPCommonSelfCaptain();
+            state.curCaptainUID = curCaptainUID;
+            iSudFSTAPP.notifyStateChange(SudMGPAPPState.APP_COMMON_SELF_CAPTAIN, SudJsonUtils.toJson(state), null);
+        }
+    }
+
+    /**
+     * 发送
+     * 5. 踢人
+     * 用户(本人,队长)踢其他玩家;
+     * 队长才能踢人;
+     *
+     * @param kickedUID 被踢用户uid
+     */
+    public void notifyAPPCommonSelfKick(String kickedUID) {
+        ISudFSTAPP iSudFSTAPP = this.iSudFSTAPP;
+        if (iSudFSTAPP != null) {
+            SudMGPAPPState.APPCommonSelfKick state = new SudMGPAPPState.APPCommonSelfKick();
+            state.kickedUID = kickedUID;
+            iSudFSTAPP.notifyStateChange(SudMGPAPPState.APP_COMMON_SELF_KICK, SudJsonUtils.toJson(state), null);
+        }
+    }
+
+    /**
+     * 发送
+     * 6. 结束游戏
+     * 用户(本人,队长)结束(本局)游戏
+     * 注意:必须是队长发送才有效果。可通过{@link SudFSMMGDecorator#getCaptainUserId()}拿到当前队长id
+     */
+    public void notifyAPPCommonSelfEnd() {
+        ISudFSTAPP iSudFSTAPP = this.iSudFSTAPP;
+        if (iSudFSTAPP != null) {
+            SudMGPAPPState.APPCommonSelfEnd state = new SudMGPAPPState.APPCommonSelfEnd();
+            // 使用iSudFSTAPP.notifyStateChange方法向游戏侧发送状态时,因为大部分状态都需要通过网络向后端发送状态指令
+            // 所以如果发送状态后,马上就销毁游戏或者Activity,那么状态指令大概率会不生效
+            // *** 如果要确保指令能到达后端,那么发送指令后不要立即destroyMG()或finish Activity,可在发送后delay一定时间(如300 or 500 ms)再销毁
+            // *** 如果不在乎指令是否能成功到达,可忽略delay
+            iSudFSTAPP.notifyStateChange(SudMGPAPPState.APP_COMMON_SELF_END, SudJsonUtils.toJson(state), null);
+        }
+    }
+
+    /**
+     * 发送
+     * 9. 麦克风状态
+     * 用户(本人)麦克风状态,建议:
+     * 进入房间后初始通知一次;
+     * 每次变更(开麦/闭麦/禁麦/解麦)通知一次;
+     *
+     * @param isOn       true 开麦,false 闭麦
+     * @param isDisabled true 被禁麦,false 未被禁麦
+     */
+    public void notifyAPPCommonSelfMicrophone(boolean isOn, boolean isDisabled) {
+        ISudFSTAPP iSudFSTAPP = this.iSudFSTAPP;
+        if (iSudFSTAPP != null) {
+            SudMGPAPPState.APPCommonSelfMicrophone state = new SudMGPAPPState.APPCommonSelfMicrophone();
+            state.isOn = isOn;
+            state.isDisabled = isDisabled;
+            iSudFSTAPP.notifyStateChange(SudMGPAPPState.APP_COMMON_SELF_MICROPHONE, SudJsonUtils.toJson(state), null);
+        }
+    }
+
+    /**
+     * 发送
+     * 10. 文字命中状态
+     * 用户(本人)聊天信息命中关键词状态,建议:
+     * 精确匹配;
+     * 首次聊天内容命中关键词之后,后续聊天内容不翻转成未命中;
+     * 直至小游戏侧关键词更新,再将状态翻转为未命中;
+     *
+     * @param isHit       true 命中,false 未命中
+     * @param keyWord     单个关键词, 兼容老版本
+     * @param text        返回转写文本
+     * @param wordType    text:文本包含匹配; number:数字等于匹配
+     * @param keyWordList 命中关键词,可以包含多个关键词
+     * @param numberList  在number模式下才有,返回转写的多个数字
+     */
+    public void notifyAPPCommonSelfTextHitState(boolean isHit, String keyWord, String text,
+                                                String wordType, List<String> keyWordList, List<Integer> numberList) {
+        ISudFSTAPP iSudFSTAPP = this.iSudFSTAPP;
+        if (iSudFSTAPP != null) {
+            SudMGPAPPState.APPCommonSelfTextHitState state = new SudMGPAPPState.APPCommonSelfTextHitState();
+            state.isHit = isHit;
+            state.keyWord = keyWord;
+            state.text = text;
+            state.wordType = wordType;
+            state.keyWordList = keyWordList;
+            state.numberList = numberList;
+            iSudFSTAPP.notifyStateChange(SudMGPAPPState.APP_COMMON_SELF_TEXT_HIT, SudJsonUtils.toJson(state), null);
+        }
+    }
+
+    /**
+     * 发送
+     * 11. 打开或关闭背景音乐(2021-12-27新增)
+     *
+     * @param isOpen true 打开背景音乐,false 关闭背景音乐
+     */
+    public void notifyAPPCommonOpenBgMusic(boolean isOpen) {
+        ISudFSTAPP iSudFSTAPP = this.iSudFSTAPP;
+        if (iSudFSTAPP != null) {
+            SudMGPAPPState.APPCommonOpenBgMusic state = new SudMGPAPPState.APPCommonOpenBgMusic();
+            state.isOpen = isOpen;
+            iSudFSTAPP.notifyStateChange(SudMGPAPPState.APP_COMMON_OPEN_BG_MUSIC, SudJsonUtils.toJson(state), null);
+        }
+    }
+
+    /**
+     * 发送
+     * 12. 打开或关闭音效(2021-12-27新增)
+     *
+     * @param isOpen true 打开音效,false 关闭音效
+     */
+    public void notifyAPPCommonOpenSound(boolean isOpen) {
+        ISudFSTAPP iSudFSTAPP = this.iSudFSTAPP;
+        if (iSudFSTAPP != null) {
+            SudMGPAPPState.APPCommonOpenSound state = new SudMGPAPPState.APPCommonOpenSound();
+            state.isOpen = isOpen;
+            iSudFSTAPP.notifyStateChange(SudMGPAPPState.APP_COMMON_OPEN_SOUND, SudJsonUtils.toJson(state), null);
+        }
+    }
+
+    /**
+     * 发送
+     * 13. 打开或关闭游戏中的振动效果(2021-12-27新增)
+     *
+     * @param isOpen 打开振动效果,false 关闭振动效果
+     */
+    public void notifyAPPCommonOpenVibrate(boolean isOpen) {
+        ISudFSTAPP iSudFSTAPP = this.iSudFSTAPP;
+        if (iSudFSTAPP != null) {
+            SudMGPAPPState.APPCommonOpenVibrate state = new SudMGPAPPState.APPCommonOpenVibrate();
+            state.isOpen = isOpen;
+            iSudFSTAPP.notifyStateChange(SudMGPAPPState.APP_COMMON_OPEN_VIBRATE, SudJsonUtils.toJson(state), null);
+        }
+    }
+
+    /**
+     * 发送
+     * 14. 设置游戏的音量大小(2021-12-31新增)
+     *
+     * @param volume 音量大小 0 到 100
+     */
+    public void notifyAPPCommonGameSoundVolume(int volume) {
+        ISudFSTAPP iSudFSTAPP = this.iSudFSTAPP;
+        if (iSudFSTAPP != null) {
+            SudMGPAPPState.APPCommonGameSoundVolume state = new SudMGPAPPState.APPCommonGameSoundVolume();
+            state.volume = volume;
+            iSudFSTAPP.notifyStateChange(SudMGPAPPState.APP_COMMON_GAME_SOUND_VOLUME, SudJsonUtils.toJson(state), null);
+        }
+    }
+
+    /**
+     * 发送
+     * 15.  设置游戏玩法选项(2022-05-10新增)
+     *
+     * @param ludo ludo游戏
+     */
+    public void notifyAPPCommonGameSettingSelectInfo(SudMGPAPPState.Ludo ludo) {
+        ISudFSTAPP iSudFSTAPP = this.iSudFSTAPP;
+        if (iSudFSTAPP != null) {
+            SudMGPAPPState.APPCommonGameSettingSelectInfo state = new SudMGPAPPState.APPCommonGameSettingSelectInfo();
+            state.ludo = ludo;
+            iSudFSTAPP.notifyStateChange(SudMGPAPPState.APP_COMMON_GAME_SETTING_SELECT_INFO, SudJsonUtils.toJson(state), null);
+        }
+    }
+
+    /**
+     * 发送
+     * 16. 设置游戏中的AI玩家(2022-05-11新增)
+     *
+     * @param aiPlayers AI玩家
+     * @param isReady   机器人加入后是否自动准备 1:自动准备,0:不自动准备 默认为1
+     */
+    public void notifyAPPCommonGameAddAIPlayers(List<SudMGPAPPState.AIPlayers> aiPlayers, int isReady) {
+        ISudFSTAPP iSudFSTAPP = this.iSudFSTAPP;
+        if (iSudFSTAPP != null) {
+            SudMGPAPPState.APPCommonGameAddAIPlayers state = new SudMGPAPPState.APPCommonGameAddAIPlayers();
+            state.aiPlayers = aiPlayers;
+            state.isReady = isReady;
+            iSudFSTAPP.notifyStateChange(SudMGPAPPState.APP_COMMON_GAME_ADD_AI_PLAYERS, SudJsonUtils.toJson(state), null);
+        }
+    }
+
+    /**
+     * 发送
+     * 17. app在收到游戏断开连接通知后,通知游戏重试连接(2022-06-21新增,暂时支持ludo)
+     */
+    public void notifyAPPCommonGameReconnect() {
+        ISudFSTAPP iSudFSTAPP = this.iSudFSTAPP;
+        if (iSudFSTAPP != null) {
+            SudMGPAPPState.APPCommonGameReconnect state = new SudMGPAPPState.APPCommonGameReconnect();
+            iSudFSTAPP.notifyStateChange(SudMGPAPPState.APP_COMMON_GAME_RECONNECT, SudJsonUtils.toJson(state), null);
+        }
+    }
+
+    /**
+     * 发送
+     * 18. app返回玩家当前积分
+     */
+    public void notifyAPPCommonGameScore(long score) {
+        ISudFSTAPP iSudFSTAPP = this.iSudFSTAPP;
+        if (iSudFSTAPP != null) {
+            SudMGPAPPState.APPCommonGameScore state = new SudMGPAPPState.APPCommonGameScore();
+            state.score = score;
+            iSudFSTAPP.notifyStateChange(SudMGPAPPState.APP_COMMON_GAME_SCORE, SudJsonUtils.toJson(state), null);
+        }
+    }
+    // endregion 状态通知,ISudFSTAPP.notifyStateChange
+
+    // region 生命周期
+    public void startMG() {
+        ISudFSTAPP iSudFSTAPP = this.iSudFSTAPP;
+        if (iSudFSTAPP != null) {
+            iSudFSTAPP.startMG();
+        }
+    }
+
+    public void pauseMG() {
+        ISudFSTAPP iSudFSTAPP = this.iSudFSTAPP;
+        if (iSudFSTAPP != null) {
+            iSudFSTAPP.pauseMG();
+        }
+    }
+
+    public void playMG() {
+        ISudFSTAPP iSudFSTAPP = this.iSudFSTAPP;
+        if (iSudFSTAPP != null) {
+            iSudFSTAPP.playMG();
+        }
+    }
+
+    public void stopMG() {
+        ISudFSTAPP iSudFSTAPP = this.iSudFSTAPP;
+        if (iSudFSTAPP != null) {
+            iSudFSTAPP.stopMG();
+        }
+    }
+
+    public void destroyMG() {
+        ISudFSTAPP iSudFSTAPP = this.iSudFSTAPP;
+        if (iSudFSTAPP != null) {
+            iSudFSTAPP.destroyMG();
+        }
+    }
+
+    // endregion 生命周期
+
+    /**
+     * 更新code
+     *
+     * @param code
+     * @param listener
+     */
+    public void updateCode(String code, ISudListenerNotifyStateChange listener) {
+        ISudFSTAPP iSudFSTAPP = this.iSudFSTAPP;
+        if (iSudFSTAPP != null) {
+            iSudFSTAPP.updateCode(code, listener);
+        }
+    }
+
+    /**
+     * 音频流数据
+     */
+    public void pushAudio(ByteBuffer buffer, int bufferLength) {
+        ISudFSTAPP iSudFSTAPP = this.iSudFSTAPP;
+        if (iSudFSTAPP != null) {
+            iSudFSTAPP.pushAudio(buffer, bufferLength);
+        }
+    }
+
+    // region 元宇宙砂砂舞
+
+    /**
+     * 发送
+     * 1. 元宇宙砂砂舞相关设置
+     * 参考文档:https://docs.sud.tech/zh-CN/app/Client/APPFST/CommonStateForDisco.html
+     *
+     * @param actionId 必传的参数,用于指定类型的序号,不同序号用于区分游戏内的不同功能,不传则会判断为无效指令,具体序号代表的功能见下表
+     * @param cooldown 持续时间,单位秒,部分功能有持续时间就需要传对应的数值,不传或传错则会按各自功能的默认值处理(见下表)
+     * @param isTop    是否置顶,针对部分功能可排队置顶(false:不置顶;true:置顶;默认为false)
+     * @param field1   额外参数1,针对部分功能有具体的意义
+     * @param field2   额外参数2,针对部分功能有具体的意义
+     */
+    public void notifyAppCommonGameDiscoAction(int actionId, Integer cooldown, Boolean isTop, String field1, String field2) {
+        ISudFSTAPP iSudFSTAPP = this.iSudFSTAPP;
+        if (iSudFSTAPP != null) {
+            SudMGPAPPState.AppCommonGameDiscoAction state = new SudMGPAPPState.AppCommonGameDiscoAction();
+            state.actionId = actionId;
+            state.cooldown = cooldown;
+            state.isTop = isTop;
+            state.field1 = field1;
+            state.field2 = field2;
+            iSudFSTAPP.notifyStateChange(SudMGPAPPState.APP_COMMON_GAME_DISCO_ACTION, SudJsonUtils.toJson(state), null);
+        }
+    }
+    // endregion 元宇宙砂砂舞
+
+    /**
+     * APP状态通知给小游戏
+     *
+     * @param state    状态标识
+     * @param dataJson 数据
+     * @param listener 回调监听
+     */
+    public void notifyStateChange(String state, String dataJson, ISudListenerNotifyStateChange listener) {
+        ISudFSTAPP iSudFSTAPP = this.iSudFSTAPP;
+        if (iSudFSTAPP != null) {
+            iSudFSTAPP.notifyStateChange(state, dataJson, listener);
+        }
+    }
+
+    /**
+     * APP状态通知给小游戏
+     *
+     * @param state    状态标识
+     * @param dataJson 数据
+     */
+    public void notifyStateChange(String state, String dataJson) {
+        notifyStateChange(state, dataJson, null);
+    }
+
+    /**
+     * APP状态通知给小游戏
+     *
+     * @param state 状态标识
+     * @param obj   数据
+     */
+    public void notifyStateChange(String state, Object obj) {
+        notifyStateChange(state, SudJsonUtils.toJson(obj), null);
+    }
+
+}
diff --git a/common/src/main/java/com/yunbao/common/sud/model/GameConfigModel.java b/common/src/main/java/com/yunbao/common/sud/model/GameConfigModel.java
new file mode 100644
index 000000000..72bcf1312
--- /dev/null
+++ b/common/src/main/java/com/yunbao/common/sud/model/GameConfigModel.java
@@ -0,0 +1,256 @@
+/*
+ * Copyright © Sud.Tech
+ * https://sud.tech
+ */
+
+package com.yunbao.common.sud.model;
+
+import java.io.Serializable;
+
+/**
+ * 游戏配置模型
+ * 参考文档:https://docs.sud.tech/zh-CN/app/Client/API/ISudFSMMG/onGetGameCfg.html
+ */
+public class GameConfigModel implements Serializable {
+
+    public int gameMode = 1; // 游戏模式(每个游戏默认模式是1,不填是1)
+    public int gameCPU = 0; // 游戏CPU(值为0和1;0:CPU正常功耗,1:CPU低功耗;默认是0,CPU正常功耗)
+    public int gameSoundControl = 0; // 游戏中声音的播放是否被app层接管(值为0和1;0:游戏播放声音,1:app层播放声音,游戏中不播放任何声音;默认是0)
+    public int gameSoundVolume = 100; // 游戏中音量的大小(值为0到100;默认是100)
+    public GameUi ui = new GameUi(); // 对游戏ui界面的配置,可定制ui界面的显示与不显示
+
+    // 游戏配置中,ui部分
+    public static class GameUi implements Serializable {
+        public GameSettle gameSettle = new GameSettle(); // 结算界面
+        public GamePing ping = new GamePing(); // 界面中的ping值
+        public GameVersion version = new GameVersion(); // 界面中的版本信息值
+        public GameLevel level = new GameLevel(); // 大厅中的段位信息
+        public GameLobbySettingBtn lobby_setting_btn = new GameLobbySettingBtn(); // 大厅的设置按钮
+        public GameLobbyHelpBtn lobby_help_btn = new GameLobbyHelpBtn(); // 大厅的帮助按钮
+        public GameLobbyPlayers lobby_players = new GameLobbyPlayers(); // 大厅玩家展示位
+        public GameLobbyPlayerCaptainIcon lobby_player_captain_icon = new GameLobbyPlayerCaptainIcon(); // 大厅玩家展示位上队长标识
+        public GameLobbyPlayerKickoutIcon lobby_player_kickout_icon = new GameLobbyPlayerKickoutIcon(); // 大厅玩家展示位上踢人标识
+        public GameLobbyRule lobby_rule = new GameLobbyRule(); // 大厅的玩法规则描述文字
+        public GameLobbyGameSetting lobby_game_setting = new GameLobbyGameSetting(); // 玩法设置
+        public GameJoinBtn join_btn = new GameJoinBtn(); // 加入按钮
+        public GameCancelJoinBtn cancel_join_btn = new GameCancelJoinBtn(); // 取消加入按钮
+        public GameReadyBtn ready_btn = new GameReadyBtn(); // 准备按钮
+        public GameCancelReadyBtn cancel_ready_btn = new GameCancelReadyBtn(); // 取消准备按钮
+        public GameStartBtn start_btn = new GameStartBtn(); // 开始按钮
+        public GameShareBtn share_btn = new GameShareBtn(); // 分享
+        public GameSttingBtn game_setting_btn = new GameSttingBtn(); // 游戏场景中的设置按钮
+        public GameHelpBtn game_help_btn = new GameHelpBtn(); // 游戏场景中的帮助按钮
+        public GameSettleCloseBtn game_settle_close_btn = new GameSettleCloseBtn(); // 游戏结算界面中的关闭按钮
+        public GameSettleAgainBtn game_settle_again_btn = new GameSettleAgainBtn(); // 游戏结算界面中的再来一局按钮
+        public GameBg game_bg = new GameBg();// 是否隐藏背景图,包括大厅和战斗
+        public BlockChangeSeat block_change_seat = new BlockChangeSeat(); // 自定义阻止换座位
+        public GameSettingSelectPnl game_setting_select_pnl = new GameSettingSelectPnl(); // 大厅中的玩法选择设置面板
+        public GameManagedImage game_managed_image = new GameManagedImage(); // 游戏中的托管图标
+        public GameTableImage game_table_image = new GameTableImage(); // 游戏中牌桌背景图 (注:只对某些带牌桌类游戏有作用)
+        public GameCountdownTime game_countdown_time = new GameCountdownTime(); // 游戏中游戏倒计时显示 (注:现在只针对umo生效)
+        public GameSelectedTips game_selected_tips = new GameSelectedTips(); // 游戏中所选择的玩法提示文字 (注:现在只针对ludo生效)
+        public NFTAvatar nft_avatar = new NFTAvatar(); // 控制NFT头像的开关
+        public GameOpening game_opening = new GameOpening(); // 控制开场动画的开关
+        public GameMvp game_mvp = new GameMvp(); // 游戏结算前的mvp动画
+        public UmoIcon umo_icon = new UmoIcon(); // 游戏中动画和头像右上角的UMO图标
+        public Logo logo = new Logo(); // 大厅中的logo
+        public GamePlayers game_players = new GamePlayers(); // 游戏中的游戏位
+    }
+
+    // 结算界面
+    public static class GameSettle implements Serializable {
+        public boolean hide = false; // 是否隐藏结算界面(false: 显示; true: 隐藏,默认为 false)
+    }
+
+    // 界面中的ping值
+    public static class GamePing implements Serializable {
+        public boolean hide = false; // 是否隐藏ping值(false: 显示;true: 隐藏,默认为false)
+    }
+
+    // 界面中的版本信息值
+    public static class GameVersion implements Serializable {
+        public boolean hide = false; // 是否隐藏版本信息(false: 显示; true: 隐藏,默认为false)
+    }
+
+    // 大厅中的段位信息
+    public static class GameLevel implements Serializable {
+        public boolean hide = false; // 是否隐藏段位信息(false: 显示; true: 隐藏,默认为false)
+    }
+
+    // 大厅的设置按钮
+    public static class GameLobbySettingBtn implements Serializable {
+        public boolean hide = false; // 是否隐藏大厅的设置按钮(false: 显示; true: 隐藏,默认为false)
+    }
+
+    // 大厅的帮助按钮
+    public static class GameLobbyHelpBtn implements Serializable {
+        public boolean hide = false; // 是否隐藏大厅的帮助按钮(false: 显示; true: 隐藏,默认为false)
+    }
+
+    // 大厅玩家展示位
+    public static class GameLobbyPlayers implements Serializable {
+        public boolean custom = false; // 大厅玩家展示位头像点击加入(false: 游戏处理逻辑; true: 游戏只通知按钮点击事件,不处理;默认为false)
+        public boolean hide = false; // 是否隐藏大厅玩家展示位(false: 显示; true: 隐藏,默认为false)
+    }
+
+    // 大厅玩家展示位上队长标识
+    public static class GameLobbyPlayerCaptainIcon implements Serializable {
+        public boolean hide = false; // 是否隐藏大厅玩家展示位上队长标识(false: 显示; true: 隐藏,默认为false)
+    }
+
+    // 大厅玩家展示位上踢人标识
+    public static class GameLobbyPlayerKickoutIcon implements Serializable {
+        public boolean hide = false; // 是否隐藏大厅玩家展示位上踢人标识(false: 显示; true: 隐藏,默认为false)
+    }
+
+    // 大厅的玩法规则描述文字
+    public static class GameLobbyRule implements Serializable {
+        public boolean hide = false; // 是否隐藏大厅的玩法规则描述文字(false: 显示; true: 隐藏,默认为false)
+    }
+
+    // 玩法设置
+    public static class GameLobbyGameSetting implements Serializable {
+        public boolean hide = false; // 是否隐藏玩法设置(false: 显示; true: 隐藏,默认为false)
+    }
+
+    // 加入按钮
+    public static class GameJoinBtn implements Serializable {
+        public boolean custom = false; // 加入按钮(false: 游戏处理逻辑; true: 游戏只通知按钮点击事件,不处理;默认为false)
+        public boolean hide = false; // 是否隐藏加入按钮(false: 显示; true: 隐藏,默认为false)
+    }
+
+    // 取消加入按钮
+    public static class GameCancelJoinBtn implements Serializable {
+        public boolean custom = false; // 取消加入按钮(false: 游戏处理逻辑; true: 游戏只通知按钮点击事件,不处理;默认为false)
+        public boolean hide = false; // 是否隐藏取消加入按钮(false: 显示; true: 隐藏,默认为false)
+    }
+
+    // 准备按钮
+    public static class GameReadyBtn implements Serializable {
+        public boolean custom = false; // 准备按钮(false: 游戏处理逻辑; true: 游戏只通知按钮点击事件,不处理;默认为false)
+        public boolean hide = false; // 是否隐藏准备按钮(false: 显示; true: 隐藏,默认为false)
+    }
+
+    // 取消准备按钮
+    public static class GameCancelReadyBtn implements Serializable {
+        public boolean custom = false; // 取消准备按钮(false: 游戏处理逻辑; true: 游戏只通知按钮点击事件,不处理;默认为false)
+        public boolean hide = false; // 是否隐藏取消准备按钮(false: 显示; true: 隐藏,默认为false)
+    }
+
+    // 开始游戏按钮
+    public static class GameStartBtn implements Serializable {
+        public boolean custom = false; // 开始游戏按钮(false: 游戏处理逻辑; true: 游戏只通知按钮点击事件,不处理;默认为false)
+        public boolean hide = false; // 是否隐藏开始游戏按钮(false: 显示; true: 隐藏,默认为false)
+    }
+
+    // 分享按钮
+    public static class GameShareBtn implements Serializable {
+        public boolean custom = false; // 分享按钮(false: 游戏处理逻辑; true: 游戏只通知按钮点击事件,不处理;默认为false)
+        public boolean hide = true; // 是否隐藏分享按钮(false: 显示; true: 隐藏,默认为true)
+    }
+
+    // 游戏场景中的设置按钮
+    public static class GameSttingBtn implements Serializable {
+        public boolean hide = false; // 是否隐藏游戏场景中的设置按钮(false: 显示; true: 隐藏,默认为false)
+    }
+
+    // 游戏场景中的帮助按钮
+    public static class GameHelpBtn implements Serializable {
+        public boolean hide = false; // 是否隐藏游戏场景中的帮助按钮(false: 显示; true: 隐藏,默认为false)
+    }
+
+    // 游戏结算界面中的关闭按钮
+    public static class GameSettleCloseBtn implements Serializable {
+        public boolean custom = false; // 游戏结算界面中的关闭按钮(false: 关闭结算界面返回大厅; true: 游戏通知按钮点击事件,并关闭结算界面返回大厅;默认为false)
+    }
+
+    // 游戏结算界面中的再来一局按钮
+    public static class GameSettleAgainBtn implements Serializable {
+        // 游戏结算界面中的再来一局按钮
+        // (false: 关闭结算界面返回大厅并将玩家设置为准备状态; true: 游戏通知按钮点击事件,并关闭结算界面返回大厅(不将玩家设置为准备状态);默认为false)
+        public boolean custom = false;
+
+        // 是否隐藏结算界面中的『再来一局』按钮(false: 显示; true: 隐藏,默认为false)
+        public boolean hide = false;
+    }
+
+    // 是否隐藏背景图,包括大厅和战斗
+    // !!!这里只隐藏加载完成后的背景图,加载中背景图如需隐藏则调用:{SudMGP.getCfg().setShowLoadingGameBg(false); }
+    public static class GameBg implements Serializable {
+        //(false: 显示; true: 隐藏,默认为false)
+        public boolean hide = false;
+    }
+
+    // 自定义阻止换座位
+    public static class BlockChangeSeat implements Serializable {
+        //(false: 可以换座位; true: 不可以换座位;默认为false)
+        public boolean custom = false;
+    }
+
+    // 大厅中的玩法选择设置面板
+    public static class GameSettingSelectPnl implements Serializable {
+        // 是否隐藏大厅中的玩法选择设置面板(false: 显示; true: 隐藏,默认为false)
+        public boolean hide = false;
+    }
+
+    // 游戏中的托管图标
+    public static class GameManagedImage implements Serializable {
+        // 是否隐藏游戏中的托管图标(false: 显示; true: 隐藏,默认为false)
+        public boolean hide = false;
+    }
+
+    // 游戏中牌桌背景图 (注:只对某些带牌桌类游戏有作用)
+    public static class GameTableImage implements Serializable {
+        // 是否隐藏游戏牌桌背景图(false: 显示; true: 隐藏,默认为false)
+        public boolean hide = false;
+    }
+
+    // 游戏中游戏倒计时显示 (注:现在只针对umo生效)
+    public static class GameCountdownTime implements Serializable {
+        // 是否隐藏游戏中游戏倒计时显示(false: 显示; true: 隐藏,默认为false)
+        public boolean hide = false;
+    }
+
+    // 游戏中所选择的玩法提示文字 (注:现在只针对ludo生效)
+    public static class GameSelectedTips implements Serializable {
+        // 是否隐藏游戏中所选择的玩法提示文字显示(false: 显示; true: 隐藏,默认为false)
+        public boolean hide = false;
+    }
+
+    // 控制NFT头像的开关
+    public static class NFTAvatar implements Serializable {
+        // true隐藏 false显示
+        public boolean hide = true;
+    }
+
+    // 控制开场动画的开关
+    public static class GameOpening implements Serializable {
+        // true隐藏 false显示
+        public boolean hide = true;
+    }
+
+    // 游戏结算前的mvp动画
+    public static class GameMvp implements Serializable {
+        // true隐藏 false显示
+        public boolean hide = true;
+    }
+
+    // 游戏中动画和头像右上角的UMO图标
+    public static class UmoIcon implements Serializable {
+        // 是否隐藏游戏中动画和头像右上角的UMO图标并改为UNO(false: 不隐藏,依然显示UMO; true: 隐藏,改为显示UNO,默认为false)
+        public boolean hide = false;
+    }
+
+    // 大厅中的logo
+    public static class Logo implements Serializable {
+        // 是否隐藏大厅中的logo(false: 不隐藏; true: 隐藏,默认为false)
+        public boolean hide = false;
+    }
+
+    // 游戏中的游戏位
+    public static class GamePlayers implements Serializable {
+        // 是否隐藏游戏中的游戏位(false: 不隐藏; true: 隐藏,默认为false,暂时只支持你画我猜)
+        public boolean hide = false;
+    }
+
+}
diff --git a/common/src/main/java/com/yunbao/common/sud/model/GameViewInfoModel.java b/common/src/main/java/com/yunbao/common/sud/model/GameViewInfoModel.java
new file mode 100644
index 000000000..6436a8b1a
--- /dev/null
+++ b/common/src/main/java/com/yunbao/common/sud/model/GameViewInfoModel.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright © Sud.Tech
+ * https://sud.tech
+ */
+
+package com.yunbao.common.sud.model;
+
+/**
+ * 游戏视图
+ * 参考文档:https://docs.sud.tech/zh-CN/app/Client/API/ISudFSMMG/onGetGameViewInfo.html
+ */
+public class GameViewInfoModel {
+    // 返回码
+    public int ret_code;
+
+    // 返回消息
+    public String ret_msg;
+
+    // 游戏View的大小
+    public GameViewSizeModel view_size = new GameViewSizeModel();
+
+    // 游戏安全操作区域
+    public GameViewRectModel view_game_rect = new GameViewRectModel();
+
+    public static class GameViewSizeModel {
+        // 游戏View的宽 (单位像素)
+        public int width;
+
+        // 游戏View的高 (单位像素)
+        public int height;
+    }
+
+    public static class GameViewRectModel {
+        // 相对于view_size左边框偏移(单位像素)
+        public int left;
+        // 相对于view_size上边框偏移(单位像素)
+        public int top;
+        // 相对于view_size右边框偏移(单位像素)
+        public int right;
+        // 相对于view_size下边框偏移(单位像素)
+        public int bottom;
+    }
+
+}
diff --git a/common/src/main/java/com/yunbao/common/sud/state/MGStateResponse.java b/common/src/main/java/com/yunbao/common/sud/state/MGStateResponse.java
new file mode 100644
index 000000000..9027ba16d
--- /dev/null
+++ b/common/src/main/java/com/yunbao/common/sud/state/MGStateResponse.java
@@ -0,0 +1,18 @@
+/*
+ * Copyright © Sud.Tech
+ * https://sud.tech
+ */
+
+package com.yunbao.common.sud.state;
+
+/**
+ * mg2app,状态响应
+ */
+public class MGStateResponse {
+
+    // 返回码,成功
+    public static final int SUCCESS = 0;
+
+    public int ret_code; // 返回码
+    public String ret_msg; // 返回消息
+}
diff --git a/common/src/main/java/com/yunbao/common/sud/state/SudMGPAPPState.java b/common/src/main/java/com/yunbao/common/sud/state/SudMGPAPPState.java
new file mode 100644
index 000000000..68938c586
--- /dev/null
+++ b/common/src/main/java/com/yunbao/common/sud/state/SudMGPAPPState.java
@@ -0,0 +1,1001 @@
+/*
+ * Copyright © Sud.Tech
+ * https://sud.tech
+ */
+
+package com.yunbao.common.sud.state;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * APP to MG 的通用状态定义
+ * 参考文档:https://docs.sud.tech/zh-CN/app/Client/APPFST/
+ */
+public class SudMGPAPPState implements Serializable {
+
+    // region 通用状态
+    /**
+     * 1. 加入状态
+     * 最低版本: v1.1.30.xx
+     */
+    public static final String APP_COMMON_SELF_IN = "app_common_self_in";
+
+    /**
+     * 1. 加入状态 模型
+     * 用户(本人)加入游戏/退出游戏
+     * 正确流程:
+     * 1.isIn=true: 加入游戏=>准备游戏=>开始游戏;
+     * 2.isIn=false: 结束=>取消准备=>退出游戏;
+     */
+    public static class APPCommonSelfIn implements Serializable {
+        // rue 加入游戏,false 退出游戏
+        public boolean isIn;
+
+        // 加入的游戏位(座位号) 默认传seatIndex = -1 随机加入,seatIndex 从0开始,不可大于座位数
+        public int seatIndex;
+
+        // 默认为ture, 带有游戏位(座位号)的时候,如果游戏位(座位号)已经被占用,是否随机分配一个空位坐下 isSeatRandom=true 随机分配空位坐下,isSeatRandom=false 不随机分配
+        public boolean isSeatRandom;
+
+        // 不支持分队的游戏:数值填1;支持分队的游戏:数值填1或2(两支队伍);
+        public int teamId;
+    }
+
+    /**
+     * 2. 准备状态
+     * 最低版本: v1.1.30.xx
+     */
+    public static final String APP_COMMON_SELF_READY = "app_common_self_ready";
+
+    /**
+     * 2. 准备状态 模型
+     * 用户(本人)准备/取消准备
+     */
+    public static class APPCommonSelfReady implements Serializable {
+        // true 准备,false 取消准备
+        public boolean isReady;
+    }
+
+    /**
+     * 3. 游戏状态
+     * 最低版本: v1.1.30.xx
+     */
+    public static final String APP_COMMON_SELF_PLAYING = "app_common_self_playing";
+
+    /**
+     * 3. 游戏状态 模型
+     * 用户游戏状态,如果用户在游戏中,建议:
+     * a.空出屏幕中心区:
+     * 关闭全屏礼物特效;
+     * b.部分强操作类小游戏(spaceMax为true),尽量收缩原生UI,给游戏留出尽量大的操作空间:
+     * 收缩公屏;
+     * 收缩麦位;
+     * 如果不在游戏中,则恢复。
+     */
+    public static class APPCommonSelfPlaying implements Serializable {
+        // true 开始游戏,false 结束游戏
+        public boolean isPlaying;
+
+        // string类型,Https服务回调report_game_info参数,最大长度1024字节,超过则截断(2022-01-21)
+        public String reportGameInfoExtras;
+
+        // string类型,最大长度64字节,接入方服务端,可以根据这个字段来查询一局游戏的数据
+        public String reportGameInfoKey;
+    }
+
+    /**
+     * 4. 队长状态
+     * 最低版本: v1.1.30.xx
+     */
+    public static final String APP_COMMON_SELF_CAPTAIN = "app_common_self_captain";
+
+    /**
+     * 4. 队长状态 模型
+     * 用户是否为队长,队长在游戏中会有开始游戏的权利。
+     */
+    public static class APPCommonSelfCaptain implements Serializable {
+        // 必填,指定队长uid
+        public String curCaptainUID;
+    }
+
+    /**
+     * 5. 踢人
+     * v1.1.30.xx
+     */
+    public static final String APP_COMMON_SELF_KICK = "app_common_self_kick";
+
+    /**
+     * 5. 踢人 模型
+     * 用户(本人,队长)踢其他玩家;
+     * 队长才能踢人;
+     */
+    public static class APPCommonSelfKick implements Serializable {
+        // 被踢用户uid
+        public String kickedUID;
+    }
+
+    /**
+     * 6. 结束游戏
+     * v1.1.30.xx
+     */
+    public static final String APP_COMMON_SELF_END = "app_common_self_end";
+
+    /**
+     * 6. 结束游戏 模型
+     * 用户(本人,队长)结束(本局)游戏
+     */
+    public static class APPCommonSelfEnd implements Serializable {
+        // 当前不需要传参
+    }
+
+    /**
+     * 7. 房间状态(depreated 已废弃v1.1.30.xx)
+     */
+    public static final String APP_COMMON_SELF_ROOM = "app_common_self_room";
+
+    /**
+     * 8. 麦位状态(depreated 已废弃v1.1.30.xx)
+     */
+    public static final String APP_COMMON_SELF_SEAT = "app_common_self_seat";
+
+    /**
+     * 9. 麦克风状态
+     */
+    public static final String APP_COMMON_SELF_MICROPHONE = "app_common_self_microphone";
+
+    /**
+     * 9. 麦克风状态 模型
+     * 用户(本人)麦克风状态,建议:
+     * 进入房间后初始通知一次;
+     * 每次变更(开麦/闭麦/禁麦/解麦)通知一次;
+     */
+    public static class APPCommonSelfMicrophone implements Serializable {
+        // true 开麦,false 闭麦
+        public boolean isOn;
+
+        // true 被禁麦,false 未被禁麦
+        public boolean isDisabled;
+    }
+
+    /**
+     * 10. 文字命中状态
+     */
+    public static final String APP_COMMON_SELF_TEXT_HIT = "app_common_self_text_hit";
+
+    /**
+     * 10. 文字命中状态 模型
+     * 用户(本人)聊天信息命中关键词状态,建议:
+     * 精确匹配;
+     * 首次聊天内容命中关键词之后,后续聊天内容不翻转成未命中;
+     * 直至小游戏侧关键词更新,再将状态翻转为未命中;
+     */
+    public static class APPCommonSelfTextHitState implements Serializable {
+        // true 命中,false 未命中
+        public boolean isHit;
+
+        // 单个关键词, 兼容老版本
+        public String keyWord;
+
+        // 返回转写文本
+        public String text;
+
+        // text:文本包含匹配; number:数字等于匹配
+        public String wordType;
+
+        // 命中关键词,可以包含多个关键词
+        public List<String> keyWordList;
+
+        // 在number模式下才有,返回转写的多个数字
+        public List<Integer> numberList;
+    }
+
+    /**
+     * 11. 打开或关闭背景音乐(2021-12-27新增)
+     */
+    public static final String APP_COMMON_OPEN_BG_MUSIC = "app_common_open_bg_music";
+
+    /**
+     * 11. 打开或关闭背景音乐(2021-12-27新增) 模型
+     */
+    public static class APPCommonOpenBgMusic implements Serializable {
+        // true 打开背景音乐,false 关闭背景音乐
+        public boolean isOpen;
+    }
+
+    /**
+     * 12. 打开或关闭音效(2021-12-27新增)
+     */
+    public static final String APP_COMMON_OPEN_SOUND = "app_common_open_sound";
+
+    /**
+     * 12. 打开或关闭音效(2021-12-27新增) 模型
+     */
+    public static class APPCommonOpenSound implements Serializable {
+        // true 打开音效,false 关闭音效
+        public boolean isOpen;
+    }
+
+    /**
+     * 13. 打开或关闭游戏中的振动效果(2021-12-27新增)
+     */
+    public static final String APP_COMMON_OPEN_VIBRATE = "app_common_open_vibrate";
+
+    /**
+     * 13. 打开或关闭游戏中的振动效果(2021-12-27新增)模型
+     */
+    public static class APPCommonOpenVibrate implements Serializable {
+        // true 打开振动效果,false 关闭振动效果
+        public boolean isOpen;
+    }
+
+    /**
+     * 14. 设置游戏的音量大小(2021-12-31新增)
+     */
+    public static final String APP_COMMON_GAME_SOUND_VOLUME = "app_common_game_sound_volume";
+
+    /**
+     * 14. 设置游戏的音量大小(2021-12-31新增)模型
+     */
+    public static class APPCommonGameSoundVolume implements Serializable {
+        // 音量大小 0 到 100
+        public int volume;
+    }
+
+    /**
+     * 15.  设置游戏玩法选项(2022-05-10新增)
+     */
+    public static final String APP_COMMON_GAME_SETTING_SELECT_INFO = "app_common_game_setting_select_info";
+
+    /**
+     * 15.  设置游戏玩法选项(2022-05-10新增) 模型
+     */
+    public static class APPCommonGameSettingSelectInfo implements Serializable {
+        public Ludo ludo; // 游戏名称
+    }
+
+    public static class Ludo implements Serializable {
+        public int mode; // mode: 默认赛制,0: 快速, 1: 经典;
+        public int chessNum; // chessNum: 默认棋子数量, 2: 对应2颗棋子; 4: 对应4颗棋子;
+        public int item; // item: 默认道具, 1: 有道具, 0: 没有道具
+    }
+
+    /**
+     * 16. 设置游戏中的AI玩家(2022-05-11新增)
+     */
+    public static final String APP_COMMON_GAME_ADD_AI_PLAYERS = "app_common_game_add_ai_players";
+
+    /**
+     * 16. 设置游戏中的AI玩家(2022-05-11新增) 模型
+     */
+    public static class APPCommonGameAddAIPlayers implements Serializable {
+        public List<AIPlayers> aiPlayers; // AI玩家
+        public int isReady = 1; // 机器人加入后是否自动准备 1:自动准备,0:不自动准备 默认为1
+    }
+
+    public static class AIPlayers implements Serializable {
+        public String userId; // 玩家id
+        public String avatar; // 头像url
+        public String name; // 名字
+        public String gender; // 性别 male:男,female:女
+    }
+
+    /**
+     * 17. app在收到游戏断开连接通知后,通知游戏重试连接(2022-06-21新增,暂时支持ludo)
+     */
+    public static final String APP_COMMON_GAME_RECONNECT = "app_common_game_reconnect";
+
+    /**
+     * 17. app在收到游戏断开连接通知后,通知游戏重试连接(2022-06-21新增,暂时支持ludo) 模型
+     */
+    public static class APPCommonGameReconnect implements Serializable {
+    }
+
+    /**
+     * 18. app返回玩家当前积分
+     */
+    public static final String APP_COMMON_GAME_SCORE = "app_common_game_score";
+
+    /**
+     * 18. app返回玩家当前积分 模型
+     */
+    public static class APPCommonGameScore implements Serializable {
+        public long score; // 玩家当前积分
+    }
+
+    /**
+     * 23. app通知游戏创建订单的结果
+     */
+    public static final String APP_COMMON_GAME_CREATE_ORDER_RESULT = "app_common_game_create_order_result";
+
+    /**
+     * 23. app通知游戏创建订单的结果 模型
+     */
+    public static class APPCommonGameCreateOrderResult implements Serializable {
+        public int result; // app通知游戏创建订单的结果0:失败 1:成功
+    }
+
+    /**
+     * 24. app通知游戏设置玩法(只支持 德州pro和teenpattipro)
+     */
+    public static final String APP_COMMON_GAME_SETTINGS = "app_common_game_settings";
+
+    /**
+     * 24. app通知游戏设置玩法(只支持 德州pro和teenpattipro) 模型
+     */
+    public static class APPCommonGameSettings implements Serializable {
+        public int smallBlind; // 1    配置小盲,大盲为小盲的2倍[1,2,5,10,20,50,100,200,500,1000]
+        public int ante; // 0    前注
+        public int sBuyIn; // 100  带入值/最小带入配置[100,200,100,200,500,1000,2000,5000,100000]
+        public int bBuyIn; // 200  最大带入,无限(0)
+        public int isAutoStart; // 2    0表示关闭自动开始 [0,2,6,7,8,9]
+        public int isStraddle; // 0    0:关闭,1自由,2强制
+        public double tableDuration; // 0.05 牌桌时长配置(小时)[0.5,1,2,4,6,8]
+        public int thinkTime; // 20   思考时间(秒)[10,15,20]
+    }
+
+    /**
+     * 25. app通知返回大厅
+     */
+    public static final String APP_COMMON_GAME_BACK_LOBBY = "app_common_game_back_lobby";
+
+    /**
+     * 25. app通知返回大厅 模型
+     */
+    public static class APPCommonGameBackLobby implements Serializable {
+    }
+
+    /**
+     * 26. app通知游戏定制UI配置表 (仅支持ludo)
+     */
+    public static final String APP_COMMON_GAME_UI_CUSTOM_CONFIG = "app_common_game_ui_custom_config";
+
+    /**
+     * 26. app通知游戏定制UI配置表 (仅支持ludo) 模型
+     */
+    public static class APPCommonGameUiCustomConfig implements Serializable {
+        public String gameBoard01; // 棋盘底
+        public String gameBoard02; // 棋盘
+        public String diceBg; // 骰子白底
+        public String diceBgGold; // 黄金骰子底
+        public String dice01; // 骰子1
+        public String dice02; // 骰子2
+        public String dice03; // 骰子3
+        public String dice04; // 骰子4
+        public String dice05; // 骰子5
+        public String dice06; // 骰子6
+        public String diceCrown; // 骰子皇冠
+        public String chessYellow; // 黄色棋子
+        public String chessBlue; // 蓝色棋子
+        public String chessGreen; // 绿色棋子
+        public String chessRed; // 红色棋子
+    }
+
+    /**
+     * 27. app通知游戏玩家信息列表 (赛车)
+     */
+    public static final String APP_COMMON_USERS_INFO = "app_common_users_info";
+
+    /**
+     * 27. app通知游戏玩家信息列表 (赛车) 模型
+     */
+    public static class APPCommonUsersInfo implements Serializable {
+        public List<UserInfoModel> infos;
+
+        public static class UserInfoModel {
+            public String uid; // 玩家id
+            public String avatar; // 玩家头像url
+            public String name; // 玩家名字
+        }
+    }
+
+    /**
+     * 28. app通知游戏自定义帮助内容 (赛车)
+     */
+    public static final String APP_COMMON_CUSTOM_HELP_INFO = "app_common_custom_help_info";
+
+    /**
+     * 28. app通知游戏自定义帮助内容 (赛车) 模型
+     */
+    public static class APPCommonCustomHelpInfo implements Serializable {
+        public List<String> content;
+    }
+
+    /**
+     * 29. app主动调起主界面(赛车)
+     */
+    public static final String APP_COMMON_SHOW_GAME_SCENE = "app_common_show_game_scene";
+
+    /**
+     * 29. app主动调起主界面(赛车) 模型
+     */
+    public static class APPCommonShowGameScene implements Serializable {
+    }
+
+    /**
+     * 30. app主动隐藏主界面(赛车)
+     */
+    public static final String APP_COMMON_HIDE_GAME_SCENE = "app_common_hide_game_scene";
+
+    /**
+     * 30. app主动隐藏主界面(赛车) 模型
+     */
+    public static class APPCommonHideGameScene implements Serializable {
+    }
+    // endregion 通用状态
+
+    // region 元宇宙砂砂舞
+    /**
+     * 1. 元宇宙砂砂舞相关设置
+     * 参考文档:https://docs.sud.tech/zh-CN/app/Client/APPFST/CommonStateForDisco.html
+     */
+    public static final String APP_COMMON_GAME_DISCO_ACTION = "app_common_game_disco_action";
+
+    /**
+     * 1. 元宇宙砂砂舞相关设置 模型
+     */
+    public static class AppCommonGameDiscoAction implements Serializable {
+        public int actionId; // 必传的参数,用于指定类型的序号,不同序号用于区分游戏内的不同功能,不传则会判断为无效指令,具体序号代表的功能见下表
+        public Integer cooldown; // 持续时间,单位秒,部分功能有持续时间就需要传对应的数值,不传或传错则会按各自功能的默认值处理(见下表)
+        public Boolean isTop; // 是否置顶,针对部分功能可排队置顶(false:不置顶;true:置顶;默认为false)
+        public String field1; // 额外参数1,针对部分功能有具体的意义
+        public String field2; // 额外参数2,针对部分功能有具体的意义
+    }
+    // endregion 元宇宙砂砂舞
+
+    // region 定制火箭
+    /**
+     * 1. 礼物配置文件回调
+     */
+    public static final String APP_CUSTOM_ROCKET_CONFIG = "app_custom_rocket_config";
+
+    /**
+     * 1. 礼物配置文件回调 模型
+     */
+    public static class AppCustomRocketConfig implements Serializable {
+        public int maxSeat; // 最大机位
+        public double firePrice; // 发射的静态价格
+        public int isDynamicPrice; // 发射价格是否动态开关 0:静态 1动态
+        public String gameIntroduce; // 玩法介绍
+        public String monetaryUnit; // 货币的单位
+        public long serverTime; // 服务器时间戳,单位秒
+        public List<String> filterModel; // 过滤不显示的模块(默认是为空)
+        public List<String> filterLayer; // 过滤不显示的页面(默认是为空)
+        public List<ComponentModel> componentList; // 组件列表 1套装,2主仓,3尾翼,4头像,5签名,6颜色
+        public List<HeadModel> headList; // 组件列表
+        public List<ExtraModel> extraList; // 专属配置
+
+        public static class ComponentModel {
+            public String componentId; // 组件的ID
+            public int type; // 1套装,2主仓,3尾翼
+            public String name; // 显示名称(商城+装配间+购买记录+...)
+            public double price; // 价格
+            public int isForever; // 永久:0非永久 1永久
+            public long validTime; // 有效期:单位是秒
+            public String imageId; // 图片ID
+            public int isLock; // 锁:0不锁 1锁
+            public int isShow; // 展示:0不展示 1展示
+        }
+
+        public static class HeadModel {
+            public String componentId; // 组件的ID
+            public int type; // 4头像(商城+装配间+购买记录+...)
+            public String name; // 显示名称
+            public double price; // 价格 暂时不考虑小数
+            public int isForever; // 永久:0非永久 1永久
+            public long validTime; // 有效期:单位是秒
+            public String userId; // 用户的userId
+            public String nickname; // 昵称
+            public int sex; // 性别 0:男 1:女
+            public String url; // 头像URL
+        }
+
+        public static class ExtraModel {
+            public String componentId; // 组件的ID
+            public int type; // 5签名,6颜色
+            public String name; // 显示名称(商城+装配间+购买记录+...)
+            public double price; // 价格
+            public int isForever; // 永久:0非永久 1永久
+            public long validTime; // 有效期:单位是秒
+            public String desc; // 描述
+        }
+    }
+
+    /**
+     * 2. 拥有模型列表回调(火箭)
+     */
+    public static final String APP_CUSTOM_ROCKET_MODEL_LIST = "app_custom_rocket_model_list";
+
+    /**
+     * 2. 拥有模型列表回调(火箭) 模型
+     */
+    public static class AppCustomRocketModelList implements Serializable {
+        public String defaultModelId; // 默认模型
+        public int isScreenshot; // 截图:0不截图 1截图(app上传失败或者过期时,被动截图)
+        public List<Model> list;
+
+        public static class Model {
+            public String modelId; // 模型Id
+            public int isAvatar; // 可以换装:0不可以 1可以
+            public String serviceFlag; // 服务标识
+            public List<ComponentModel> componentList; // 列表
+
+            public static class ComponentModel {
+                public String itemId; // 唯一标识
+                public int type; // 类型
+                public String value; // 值
+                public int isForever; // 永久:0非永久 1永久
+                public long validTime; // 有效期时间戳:单位是秒
+            }
+        }
+    }
+
+    /**
+     * 3. 拥有组件列表回调(火箭)
+     */
+    public static final String APP_CUSTOM_ROCKET_COMPONENT_LIST = "app_custom_rocket_component_list";
+
+    /**
+     * 3. 拥有组件列表回调(火箭) 模型
+     */
+    public static class AppCustomRocketComponentList implements Serializable {
+        public List<ComponentModel> defaultList; // 默认组件列表
+        public List<ComponentModel> list; // 组件列表
+
+        public static class ComponentModel {
+            public String itemId; // 唯一标识
+            public int type; // 类型
+            public String value; // 值
+            public int isForever; // 永久:0非永久 1永久
+            public long validTime; // 有效期时间戳:单位是秒
+            public long date; // 购买时间:1970年1月1日开始。时间戳:单位是秒
+            public String extra; // (可选择) 字段存在显示内容,字段不存在显示时间或者永久
+        }
+    }
+
+    /**
+     * 4. 获取用户信息回调(火箭)
+     */
+    public static final String APP_CUSTOM_ROCKET_USER_INFO = "app_custom_rocket_user_info";
+
+    /**
+     * 4. 获取用户信息回调(火箭) 模型
+     */
+    public static class AppCustomRocketUserInfo implements Serializable {
+        public int resultCode; // 0: 请求成功,1:请求失败
+        public String error; // 错误描述
+        public List<CustomRocketUserInfoModel> userList; // 用户信息列表
+    }
+
+    /**
+     * 5. 订单记录列表回调
+     */
+    public static final String APP_CUSTOM_ROCKET_ORDER_RECORD_LIST = "app_custom_rocket_order_record_list";
+
+    /**
+     * 5. 订单记录列表回调 模型
+     */
+    public static class AppCustomRocketOrderRecordList implements Serializable {
+        public int pageIndex; // 第几页
+        public int pageCount; // 总页数
+        public List<ComponentModel> list; // 列表
+
+        /**
+         * 定制火箭,订单组件 模型
+         */
+        public static class ComponentModel {
+            public int type; // 类型
+            public String value; // 值
+            public int isForever; // 永久:0非永久 1永久
+            public long validTime; // 有效期时间戳:单位是秒
+            public long date; // 有效期时间戳:单位是秒
+        }
+    }
+
+    /**
+     * 6. 展馆内列表回调
+     */
+    public static final String APP_CUSTOM_ROCKET_ROOM_RECORD_LIST = "app_custom_rocket_room_record_list";
+
+    /**
+     * 6. 展馆内列表回调 模型
+     */
+    public static class AppCustomRocketRoomRecordList implements Serializable {
+        public int pageIndex; // 第几页
+        public int pageCount; // 总页数
+        public List<RoomRecordModel> list; // 列表
+
+        public static class RoomRecordModel {
+            public CustomRocketUserInfoModel fromUser; // 送礼人
+            public int number; // 火箭数量
+        }
+    }
+
+    /**
+     * 7. 展馆内玩家送出记录回调
+     */
+    public static final String APP_CUSTOM_ROCKET_USER_RECORD_LIST = "app_custom_rocket_user_record_list";
+
+    /**
+     * 7. 展馆内玩家送出记录回调 模型
+     */
+    public static class AppCustomRocketUserRecordList implements Serializable {
+        public int pageIndex; // 第几页
+        public int pageCount; // 总页数
+        public CustomRocketUserInfoModel fromUser; // 送礼人
+        public List<UserRecordModel> list; // 列表
+
+        public static class UserRecordModel {
+            public long date; // 订单时间戳: 单位是秒
+            public int number; // 个数
+            public CustomRocketUserInfoModel toUser; // 收礼人
+            public List<ComponentModel> componentList; // 列表
+
+            public static class ComponentModel {
+                public int type; // 类型
+                public String value; // 值
+                public int isForever; // 永久:0非永久 1永久
+                public long validTime; // 有效期时间戳:单位是秒
+            }
+        }
+    }
+
+    /**
+     * 8. 设置默认模型(火箭)
+     */
+    public static final String APP_CUSTOM_ROCKET_SET_DEFAULT_MODEL = "app_custom_rocket_set_default_model";
+
+    /**
+     * 8. 设置默认模型(火箭) 模型
+     */
+    public static class AppCustomRocketSetDefaultModel implements Serializable {
+        public int resultCode; // 0: 请求成功,1:请求失败
+        public String error; // 错误描述
+        public Data data; // 数据
+
+        public static class Data {
+            public String modelId; // 默认模型
+        }
+    }
+
+    /**
+     * 9. 动态计算一键发送价格回调
+     */
+    public static final String APP_CUSTOM_ROCKET_DYNAMIC_FIRE_PRICE = "app_custom_rocket_dynamic_fire_price";
+
+    /**
+     * 9. 动态计算一键发送价格回调 模型
+     */
+    public static class AppCustomRocketDynamicFirePrice implements Serializable {
+        public int resultCode; // 0: 请求成功,1:请求失败
+        public String error; // 错误描述
+        public Data data; // 数据
+
+        public static class Data {
+            public double price; // 发送的价格
+        }
+    }
+
+    /**
+     * 10. 一键发送回调
+     */
+    public static final String APP_CUSTOM_ROCKET_FIRE_MODEL = "app_custom_rocket_fire_model";
+
+    /**
+     * 10. 一键发送回调 模型
+     */
+    public static class AppCustomRocketFireModel implements Serializable {
+        public int resultCode; // 0: 请求成功,1:请求失败
+        public String error; // 错误描述
+    }
+
+    /**
+     * 11. 新组装模型 回调
+     */
+    public static final String APP_CUSTOM_ROCKET_CREATE_MODEL = "app_custom_rocket_create_model";
+
+    /**
+     * 11. 新组装模型 回调 模型
+     */
+    public static class AppCustomRocketCreateModel implements Serializable {
+        public int resultCode; // 0: 请求成功,1:请求失败
+        public String error; // 错误描述
+        public Data data;
+
+        public static class Data {
+            public String modelId; // 模型Id
+            public int isAvatar; // 可以换装:0不可以 1可以
+            public String serviceFlag; // 服务标识
+            public List<ComponentModel> componentList;
+
+            public static class ComponentModel {
+                public String itemId; // 模型Id
+            }
+        }
+    }
+
+    /**
+     * 12. 更换组件 回调
+     */
+    public static final String APP_CUSTOM_ROCKET_REPLACE_COMPONENT = "app_custom_rocket_replace_component";
+
+    /**
+     * 12. 更换组件 回调 模型
+     */
+    public static class AppCustomRocketReplaceComponent implements Serializable {
+        public int resultCode; // 0: 请求成功,1:请求失败
+        public String error; // 错误描述
+        public Data data;
+
+        public static class Data {
+            public String modelId; // 模型Id
+            public List<ComponentModel> componentList;
+
+            public static class ComponentModel {
+                public String itemId;
+            }
+        }
+    }
+
+    /**
+     * 13. 购买组件 回调
+     */
+    public static final String APP_CUSTOM_ROCKET_BUY_COMPONENT = "app_custom_rocket_buy_component";
+
+    /**
+     * 13. 购买组件 回调 模型
+     */
+    public static class AppCustomRocketBuyComponent implements Serializable {
+        public int resultCode; // 0: 请求成功,1:请求失败
+        public String error; // 错误描述
+        public Data data;
+
+        public static class Data {
+            public List<ComponentModel> componentList;
+
+            public static class ComponentModel {
+                public String itemId; // 唯一标识
+                public int type; // 类型
+                public String value; // 值
+                public int isForever; // 永久:0非永久 1永久
+                public long validTime; // 有效期时间戳:单位是秒
+                public long date; // 有效期时间戳:单位是秒
+            }
+        }
+    }
+
+    /**
+     * 14. app播放火箭发射动效(火箭)
+     */
+    public static final String APP_CUSTOM_ROCKET_PLAY_MODEL_LIST = "app_custom_rocket_play_model_list";
+
+    /**
+     * 14. app播放火箭发射动效(火箭) 模型
+     */
+    public static class AppCustomRocketPlayModelList implements Serializable {
+        public String orderId; // 订单号
+        public InteractConfigModel interactConfig; // 可选配置
+        public List<ComponentModel> componentList; // 组件列表
+
+        public static class ComponentModel {
+            public int type; // 类型
+            public String value; // 值
+        }
+
+        public static class InteractConfigModel {
+            public int interactivePlay; // 互动玩法默认状态,1是关闭,0是打开,默认打开;
+            public List<Integer> gear; // 每个档位需要点击的次数;
+            public int nicknameTips; // 昵称飘字是否显示,1是隐藏,0是显示,默认0;
+            public int uiSwitche; // 左上角UI信息是否显示,1是隐藏,0是显示,默认0;
+            public int guide; // 新手引导是否显示,1是隐藏,0是显示,默认0;
+        }
+    }
+
+    /**
+     * 15. app推送主播信息(火箭)
+     */
+    public static final String APP_CUSTOM_ROCKET_NEW_USER_INFO = "app_custom_rocket_new_user_info";
+
+    /**
+     * 15. app推送主播信息(火箭) 模型
+     */
+    public static class AppCustomRocketNewUserInfo implements Serializable {
+        public List<CustomRocketUserInfoModel> userList; // 用户信息列表
+    }
+
+    /**
+     * 16. 验证签名合规(火箭)
+     */
+    public static final String APP_CUSTOM_ROCKET_VERIFY_SIGN = "app_custom_rocket_verify_sign";
+
+    /**
+     * 16. 验证签名合规(火箭) 回调  模型
+     */
+    public static class AppCustomRocketVerifySign implements Serializable {
+        public int resultCode; // 0: 请求成功,1:请求失败
+        public String error; // 错误描述
+        public Data data;
+
+        public static class Data {
+            public String sign; // 验证的签名
+        }
+    }
+
+    /**
+     * 17. app主动调起火箭主界面(火箭)
+     */
+    public static final String APP_CUSTOM_ROCKET_SHOW_GAME_SCENE = "app_custom_rocket_show_game_scene";
+
+    /**
+     * 17. app主动调起火箭主界面(火箭) 模型
+     */
+    public static class AppCustomRocketShowGameScene implements Serializable {
+    }
+
+    /**
+     * 18. app主动隐藏火箭主界面(火箭)
+     */
+    public static final String APP_CUSTOM_ROCKET_HIDE_GAME_SCENE = "app_custom_rocket_hide_game_scene";
+
+    /**
+     * 18. app主动隐藏火箭主界面(火箭)  模型
+     */
+    public static class AppCustomRocketHideGameScene implements Serializable {
+    }
+
+    /**
+     * 19. app推送解锁组件(火箭)
+     */
+    public static final String APP_CUSTOM_ROCKET_UNLOCK_COMPONENT = "app_custom_rocket_unlock_component";
+
+    /**
+     * 19. app推送解锁组件(火箭)  模型
+     */
+    public static class AppCustomRocketUnlockComponent implements Serializable {
+        public int type; // 组件类型
+        public String componentId; // 组件ID
+    }
+
+    /**
+     * 20. app推送火箭效果飞行点击(火箭)
+     */
+    public static final String APP_CUSTOM_ROCKET_FLY_CLICK = "app_custom_rocket_fly_click";
+
+    /**
+     * 20. app推送火箭效果飞行点击(火箭)  模型
+     */
+    public static class AppCustomRocketFlyClick implements Serializable {
+    }
+
+    /**
+     * 21. app推送关闭火箭播放效果(火箭)
+     */
+    public static final String APP_CUSTOM_ROCKET_CLOSE_PLAY_EFFECT = "app_custom_rocket_close_play_effect";
+
+    /**
+     * 21. app推送关闭火箭播放效果(火箭)  模型
+     */
+    public static class AppCustomRocketClosePlayEffect implements Serializable {
+    }
+
+    /**
+     * 22. 颜色和签名自定义改到装配间的模式,保存颜色或签名回调
+     */
+    public static final String APP_CUSTOM_ROCKET_SAVE_SIGN_COLOR = "app_custom_rocket_save_sign_color";
+
+    /**
+     * 22. 颜色和签名自定义改到装配间的模式,保存颜色或签名回调 模型
+     */
+    public static final class AppCustomRocketSaveSignColor implements Serializable {
+        public int resultCode; // 0: 请求成功,1:请求失败
+        public String error; // 错误描述
+        public Data data; // 数据
+
+        public static class Data {
+            public List<ComponentModel> componentList;
+        }
+
+        public static class ComponentModel {
+            public String itemId; // 唯一标识
+            public int type; // 签名
+            public String value; // 签名的值
+            public int isForever; // 永久:0非永久 1永久
+            public long validTime; // 有效期时间戳:单位是秒
+        }
+    }
+
+    /**
+     * 定制火箭,用户信息 模型
+     */
+    public static class CustomRocketUserInfoModel {
+        public String userId;   // 用户的userId
+        public String nickname; // 昵称
+        public int sex; // 性别 0:男 1:女
+        public String url; // 头像URL
+    }
+    // endregion 定制火箭
+
+    // region 棒球
+    /**
+     * 1. 下发游戏客户端查询排行榜数据(棒球)
+     */
+    public static final String APP_BASEBALL_RANKING = "app_baseball_ranking";
+
+    /**
+     * 1. 下发游戏客户端查询排行榜数据(棒球) 模型
+     */
+    public static class AppBaseballRanking implements Serializable {
+        public List<AppBaseballPlayerInfo> data;
+    }
+
+    /**
+     * 2. 下发游戏客户端查询我的排名数据(棒球)
+     */
+    public static final String APP_BASEBALL_MY_RANKING = "app_baseball_my_ranking";
+
+    /**
+     * 2. 下发游戏客户端查询我的排名数据(棒球) 模型
+     */
+    public static class AppBaseballMyRanking implements Serializable {
+        public AppBaseballPlayerInfo data;
+    }
+
+    /**
+     * 3. 下发游戏客户端查询排在自己前后的玩家数据(棒球)
+     */
+    public static final String APP_BASEBALL_RANGE_INFO = "app_baseball_range_info";
+
+    /**
+     * 3. 下发游戏客户端查询排在自己前后的玩家数据(棒球) 模型
+     */
+    public static class AppBaseballRangeInfo implements Serializable {
+        public AppBaseballPlayerInfo before; // 前一名
+        public AppBaseballPlayerInfo after; // 后一名
+    }
+
+    /**
+     * 4. app主动调起主界面(棒球)
+     */
+    public static final String APP_BASEBALL_SHOW_GAME_SCENE = "app_baseball_show_game_scene";
+
+    /**
+     * 4. app主动调起主界面(棒球) 模型
+     */
+    public static class AppBaseballShowGameScene implements Serializable {
+    }
+
+    /**
+     * 5. app主动隐藏主界面(棒球)
+     */
+    public static final String APP_BASEBALL_HIDE_GAME_SCENE = "app_baseball_hide_game_scene";
+
+    /**
+     * 5. app主动隐藏主界面(棒球) 模型
+     */
+    public static class AppBaseballHideGameScene implements Serializable {
+    }
+
+    /**
+     * 6. app推送需要的文本数据(棒球)
+     */
+    public static final String APP_BASEBALL_TEXT_CONFIG = "app_baseball_text_config";
+
+    /**
+     * 6. app推送需要的文本数据(棒球) 模型
+     */
+    public static class AppBaseballTextConfig implements Serializable {
+        public String mode1;
+        public String mode2;
+        public String mode3;
+    }
+
+    public static class AppBaseballPlayerInfo implements Serializable {
+        public String playerId; // 玩家Id
+        public String name; // 玩家昵称
+        public String avatar; // 头像
+        public long distance; // 距离
+        public int rank; // 排名
+    }
+    // endregion 棒球
+
+}
diff --git a/common/src/main/java/com/yunbao/common/sud/state/SudMGPMGState.java b/common/src/main/java/com/yunbao/common/sud/state/SudMGPMGState.java
new file mode 100644
index 000000000..1523a5a16
--- /dev/null
+++ b/common/src/main/java/com/yunbao/common/sud/state/SudMGPMGState.java
@@ -0,0 +1,1509 @@
+/*
+ * Copyright © Sud.Tech
+ * https://sud.tech
+ */
+
+package com.yunbao.common.sud.state;
+
+import com.google.gson.annotations.SerializedName;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * MG to APP 的状态定义
+ * 参考文档:https://docs.sud.tech/zh-CN/app/Client/MGFSM/
+ */
+public class SudMGPMGState implements Serializable {
+
+    // region MG状态机-通用状态-游戏
+    // 参考文档:https://docs.sud.tech/zh-CN/app/Client/MGFSM/CommonStateGame.html
+    /**
+     * 1. 公屏消息(已修改)
+     * 最低版本: v1.1.30.xx
+     */
+    public static final String MG_COMMON_PUBLIC_MESSAGE = "mg_common_public_message";
+
+    /**
+     * 1. 公屏消息(已修改)
+     * 向公屏发送消息,字段含义如下
+     * type
+     * 0 通知
+     * 1 提醒
+     * 2 结算
+     * 3 其他
+     * msg
+     * <!-- -->内为转义字段:
+     * <!--name:用户昵称|uid:用户UID|color:建议颜色-->
+     * 其中name/uid/color均为可选字段,字段为空的情况如下:
+     * <!--name:|uid:|color:-->
+     * SDK仅会缓存最新一条。
+     */
+    public static class MGCommonPublicMessage implements Serializable {
+        // 0 通知
+        // 1 提醒
+        // 2 结算
+        // 3 其他
+        public int type;
+
+        // 消息内容
+        public List<MGCommonPublicMessageMsg> msg;
+
+        public static class MGCommonPublicMessageMsg implements Serializable {
+            // 词组类型 当phrase=1时,会返回text; 当phrase=2时,会返回user
+            public int phrase;
+            public MGCommonPublicMessageMsgText text;
+            public MGCommonPublicMessageMsgUser user;
+        }
+
+        public static class MGCommonPublicMessageMsgText implements Serializable {
+            @SerializedName(value = "default")
+            public String defaultStr; // 默认文本
+
+            @SerializedName(value = "zh-CN")
+            public String zh_CN; // 中文(简体)
+
+            @SerializedName(value = "zh-HK")
+            public String zh_HK; // 中文(香港)
+
+            @SerializedName(value = "zh-MO")
+            public String zh_MO; // 中文(澳门)
+
+            @SerializedName(value = "zh-SG")
+            public String zh_SG; // 中文(新加坡)
+
+            @SerializedName(value = "zh-TW")
+            public String zh_TW; // 中文(繁体)
+
+            @SerializedName(value = "en-US")
+            public String en_US; // 英语(美国)
+
+            @SerializedName(value = "en-GB")
+            public String en_GB; // 英语(英国)
+
+            @SerializedName(value = "ms-BN")
+            public String ms_BN; // 马来语(文莱达鲁萨兰)
+
+            @SerializedName(value = "ms-MY")
+            public String ms_MY; // 马来语(马来西亚)
+
+            @SerializedName(value = "vi-VN")
+            public String vi_VN; // 越南语
+
+            @SerializedName(value = "id-ID")
+            public String id_ID; // 印度尼西亚语
+
+            @SerializedName(value = "es-ES")
+            public String es_ES; // 西班牙语(传统)
+
+            @SerializedName(value = "ja-JP")
+            public String ja_JP; // 日语
+
+            @SerializedName(value = "ko-KR")
+            public String ko_KR; // 朝鲜语
+
+            @SerializedName(value = "th-TH")
+            public String th_TH; // 泰语
+
+            @SerializedName(value = "ar-SA")
+            public String ar_SA; // 阿拉伯语(沙特阿拉伯)
+
+            @SerializedName(value = "ur-PK")
+            public String ur_PK; // 乌都语
+
+            @SerializedName(value = "tr-TR")
+            public String tr_TR; // 土耳其语
+        }
+
+        public static class MGCommonPublicMessageMsgUser implements Serializable {
+            // 默认内容
+            public String defaultStr;
+            // 用户名称
+            public String name;
+            // 用户id
+            public String uid;
+            // 颜色值
+            public String color;
+        }
+    }
+
+    /**
+     * 2. 关键词状态
+     */
+    public static final String MG_COMMON_KEY_WORD_TO_HIT = "mg_common_key_word_to_hit";
+
+    /**
+     * 2. 关键词状态
+     */
+    public static class MGCommonKeyWordToHit implements Serializable {
+        // 必填字段;text:文本包含匹配; number:数字等于匹配(必填字段);默认:text(你画我猜、你说我猜);数字炸弹填number;
+        public String wordType;
+
+        // 单个关键词,兼容老版本。轮到自己猜词时才有值,否则为null
+        public String word;
+
+        // 关键词,每一轮都会下发,不区分角色
+        public String realWord;
+
+        // 必填字段;关键词列表,可以传送多个关键词。轮到自己猜词时才有值,否则为null
+        public List<String> wordList;
+
+        // 必填字段;关键词语言,默认:zh-CN;
+        public String wordLanguage;
+    }
+
+    /**
+     * 3. 游戏结算状态
+     */
+    public static final String MG_COMMON_GAME_SETTLE = "mg_common_game_settle";
+
+    /**
+     * 3. 游戏结算状态
+     */
+    public static class MGCommonGameSettle implements Serializable {
+        // 游戏模式默认为1
+        public int gameMode;
+
+        // 本局游戏的id
+        public String gameRoundId;
+
+        // 游戏结果玩家列表
+        public List<PlayerResult> results;
+
+        /**
+         * 游戏结果玩家定义
+         */
+        public static class PlayerResult implements Serializable {
+            public String uid; // 用户id
+            public int rank; // 排名 从 1 开始
+            public int award; // 奖励
+            public int score; // 积分
+            public int isEscaped; // 是否逃跑 1:逃跑 0:非逃跑
+            public String killerId; // 杀自己的玩家的id
+            public int isAI; // 是否是AI玩家,1为AI
+        }
+    }
+
+    /**
+     * 4. 加入游戏按钮点击状态
+     */
+    public static final String MG_COMMON_SELF_CLICK_JOIN_BTN = "mg_common_self_click_join_btn";
+
+    /**
+     * 4. 加入游戏按钮点击状态 模型
+     * 用户(本人)点击加入按钮,或者点击头像加入
+     */
+    public static class MGCommonSelfClickJoinBtn implements Serializable {
+        // 点击头像加入游戏对应的座位号,int 类型,从0开始, 如果seatIndex=-1,则是随机加入一个空位,如果seatIndex 大于座位数,则加入不成功
+        public int seatIndex;
+    }
+
+    /**
+     * 5. 取消加入(退出)游戏按钮点击状态
+     */
+    public static final String MG_COMMON_SELF_CLICK_CANCEL_JOIN_BTN = "mg_common_self_click_cancel_join_btn";
+
+    /**
+     * 5. 取消加入(退出)游戏按钮点击状态 模型
+     * 用户(本人)点击取消加入按钮
+     */
+    public static class MGCommonSelfClickCancelJoinBtn implements Serializable {
+    }
+
+    /**
+     * 6. 准备按钮点击状态
+     */
+    public static final String MG_COMMON_SELF_CLICK_READY_BTN = "mg_common_self_click_ready_btn";
+
+    /**
+     * 6. 准备按钮点击状态 模型
+     */
+    public static class MGCommonSelfClickReadyBtn implements Serializable {
+    }
+
+    /**
+     * 7. 取消准备按钮点击状态
+     */
+    public static final String MG_COMMON_SELF_CLICK_CANCEL_READY_BTN = "mg_common_self_click_cancel_ready_btn";
+
+    /**
+     * 7. 取消准备按钮点击状态 模型
+     */
+    public static class MGCommonSelfClickCancelReadyBtn implements Serializable {
+    }
+
+    /**
+     * 8. 开始游戏按钮点击状态
+     */
+    public static final String MG_COMMON_SELF_CLICK_START_BTN = "mg_common_self_click_start_btn";
+
+    /**
+     * 8. 开始游戏按钮点击状态 模型
+     */
+    public static class MGCommonSelfClickStartBtn implements Serializable {
+    }
+
+    /**
+     * 9. 分享按钮点击状态
+     */
+    public static final String MG_COMMON_SELF_CLICK_SHARE_BTN = "mg_common_self_click_share_btn";
+
+    /**
+     * 9. 分享按钮点击状态 模型
+     * 用户(本人)点击分享按钮
+     */
+    public static class MGCommonSelfClickShareBtn implements Serializable {
+    }
+
+    /**
+     * 10. 游戏状态
+     */
+    public static final String MG_COMMON_GAME_STATE = "mg_common_game_state";
+
+    /**
+     * 10. 游戏状态 模型
+     */
+    public static class MGCommonGameState implements Serializable {
+        public static final int UNKNOW = -1; // 未知
+        public static final int IDLE = 0;
+        public static final int LOADING = 1;
+        public static final int PLAYING = 2;
+
+        // gameState=0 (idle 状态,游戏未开始,空闲状态);
+        // gameState=1(loading 状态,所有玩家都准备好,队长点击了开始游戏按钮,等待加载游戏场景开始游戏,游戏即将开始提示阶段);
+        // gameState=2(playing状态,游戏进行中状态)
+        public int gameState;
+    }
+
+    /**
+     * 11. 结算界面关闭按钮点击状态(2021-12-27新增)
+     */
+    public static final String MG_COMMON_SELF_CLICK_GAME_SETTLE_CLOSE_BTN = "mg_common_self_click_game_settle_close_btn";
+
+    /**
+     * 11. 结算界面关闭按钮点击状态(2021-12-27新增) 模型
+     * 用户(本人)点击结算界面关闭按钮
+     */
+    public static class MGCommonSelfClickGameSettleCloseBtn implements Serializable {
+    }
+
+    /**
+     * 12. 结算界面再来一局按钮点击状态(2021-12-27新增)
+     */
+    public static final String MG_COMMON_SELF_CLICK_GAME_SETTLE_AGAIN_BTN = "mg_common_self_click_game_settle_again_btn";
+
+    /**
+     * 12. 结算界面再来一局按钮点击状态(2021-12-27新增)模型
+     * 用户(本人)点击结算界面再来一局按钮
+     */
+    public static class MGCommonSelfClickGameSettleAgainBtn implements Serializable {
+    }
+
+    /**
+     * 13. 游戏上报游戏中的声音列表(2021-12-30新增,现在只支持碰碰我最强)
+     */
+    public static final String MG_COMMON_GAME_SOUND_LIST = "mg_common_game_sound_list";
+
+    /**
+     * 13. 游戏上报游戏中的声音列表(2021-12-30新增,现在只支持碰碰我最强) 模型
+     * 游戏上报本游戏中所有的声音资源列表
+     */
+    public static class MGCommonGameSoundList implements Serializable {
+        // 声音资源列表
+        public List<MGCommonGameSound> list;
+
+        public static class MGCommonGameSound implements Serializable {
+            // 声音资源的名字
+            public String name;
+            // 声音资源的URL链接
+            public String url;
+            // 声音资源类型
+            public String type;
+        }
+    }
+
+    /**
+     * 14. 游通知app层播放声音(2021-12-30新增,现在只支持碰碰我最强)
+     */
+    public static final String MG_COMMON_GAME_SOUND = "mg_common_game_sound";
+
+    /**
+     * 14. 游通知app层播放声音(2021-12-30新增,现在只支持碰碰我最强) 模型
+     * 游戏通知app层播放背景音乐的开关状态
+     */
+    public static class MGCommonGameSound implements Serializable {
+        // 是否播放 isPlay==true(播放),isPlay==false(停止)
+        public boolean isPlay;
+        // 要播放的声音文件名,不带后缀
+        public String name;
+        // 声音资源类型
+        public String type;
+        // 播放次数;注:times == 0 为循环播放
+        public String times;
+        // https://www.xxxx.xx/xxx.mp3"  声音资源的url链接
+        public String url;
+    }
+
+    /**
+     * 15. 游戏通知app层播放背景音乐状态(2022-01-07新增,现在只支持碰碰我最强)
+     */
+    public static final String MG_COMMON_GAME_BG_MUSIC_STATE = "mg_common_game_bg_music_state";
+
+    /**
+     * 15. 游戏通知app层播放背景音乐状态(2022-01-07新增,现在只支持碰碰我最强) 模型
+     * 游戏通知app层播放背景音乐的开关状态
+     */
+    public static class MGCommonGameBgMusicState implements Serializable {
+        // 背景音乐的开关状态 true: 开,false: 关
+        public boolean state;
+    }
+
+    /**
+     * 16. 游戏通知app层播放音效的状态(2022-01-07新增,现在只支持碰碰我最强)
+     */
+    public static final String MG_COMMON_GAME_SOUND_STATE = "mg_common_game_sound_state";
+
+    /**
+     * 16. 游戏通知app层播放音效的状态(2022-01-07新增,现在只支持碰碰我最强) 模型
+     * 游戏通知app层播放音效的状态
+     */
+    public static class MGCommonGameSoundState implements Serializable {
+        // 背景音乐的开关状态 true: 开,false: 关
+        public boolean state;
+    }
+
+    /**
+     * 17. ASR状态(开启和关闭语音识别状态,v1.1.45.xx 版本新增)
+     */
+    public static final String MG_COMMON_GAME_ASR = "mg_common_game_asr";
+
+    /**
+     * 17. ASR状态(开启和关闭语音识别状态,v1.1.45.xx 版本新增) 模型
+     */
+    public static class MGCommonGameASR implements Serializable {
+        // true:打开语音识别 false:关闭语音识别
+        public boolean isOpen;
+    }
+
+    /**
+     * 18. 麦克风状态(2022-02-08新增)
+     */
+    public static final String MG_COMMON_SELF_MICROPHONE = "mg_common_self_microphone";
+
+    /**
+     * 18. 麦克风状态(2022-02-08新增) 模型
+     * 游戏通知app麦克风状态
+     */
+    public static class MGCommonSelfMicrophone implements Serializable {
+        // 麦克风开关状态 true: 开,false: 关
+        public boolean isOn;
+    }
+
+    /**
+     * 19. 耳机(听筒,扬声器)状态(2022-02-08新增)
+     */
+    public static final String MG_COMMON_SELF_HEADPHONE = "mg_common_self_headphone";
+
+    /**
+     * 19. 耳机(听筒,扬声器)状态(2022-02-08新增) 模型
+     */
+    public static class MGCommonSelfHeadphone implements Serializable {
+        // 耳机(听筒,喇叭)开关状态 true: 开,false: 关
+        public boolean isOn;
+    }
+
+    /**
+     * 20. App通用状态操作结果错误码(2022-05-10新增)
+     */
+    public static final String MG_COMMON_APP_COMMON_SELF_X_RESP = "mg_common_app_common_self_x_resp";
+
+    /**
+     * 20. App通用状态操作结果错误码(2022-05-10新增) 模型
+     */
+    public static class MGCommonAPPCommonSelfXResp implements Serializable {
+        public String state; // 字段必填, 参考:游戏业务错误 https://docs.sud.tech/zh-CN/app/Client/APPFST/CommonState.html
+        public int resultCode; // 字段必填,参考:游戏业务错误 https://docs.sud.tech/zh-CN/app/Server/ErrorCode.html
+        public boolean isIn; // 当state=app_common_self_in时,字段必填
+        public boolean isReady; // 当state=app_common_self_ready时,字段必填
+        public boolean isPlaying; // 当state=app_common_self_playing时,字段必填
+        public String reportGameInfoExtras; // 当state=app_common_self_playing时,字段必填
+        public String curCaptainUID; // 当state=app_common_self_captain时,字段必填
+        public String kickedUID; // 当state=app_common_self_kick时,字段必填
+    }
+
+    /**
+     * 21. 游戏通知app层添加陪玩机器人是否成功(2022-05-17新增)
+     */
+    public static final String MG_COMMON_GAME_ADD_AI_PLAYERS = "mg_common_game_add_ai_players";
+
+    /**
+     * 21. 游戏通知app层添加陪玩机器人是否成功(2022-05-17新增) 模型
+     */
+    public static class MGCommonGameAddAIPlayers implements Serializable {
+        public int resultCode; // 返回码 0:成功,非0:不成功
+        public List<String> userIds; // 加入成功的playerId列表
+    }
+
+    /**
+     * 22. 游戏通知app层添当前网络连接状态(2022-06-21新增)
+     */
+    public static final String MG_COMMON_GAME_NETWORK_STATE = "mg_common_game_network_state";
+
+    /**
+     * 22. 游戏通知app层添当前网络连接状态(2022-06-21新增) 模型
+     */
+    public static class MGCommonGameNetworkState implements Serializable {
+        public int state; // 0:closed, 1: connected
+    }
+
+    /**
+     * 23. 游戏通知app获取积分
+     */
+    public static final String MG_COMMON_GAME_GET_SCORE = "mg_common_game_get_score";
+
+    /**
+     * 23. 游戏通知app获取积分 模型
+     */
+    public static class MGCommonGameGetScore implements Serializable {
+    }
+
+    /**
+     * 24. 游戏通知app带入积分
+     */
+    public static final String MG_COMMON_GAME_SET_SCORE = "mg_common_game_set_score";
+
+    /**
+     * 24. 游戏通知app带入积分 模型
+     */
+    public static class MGCommonGameSetScore implements Serializable {
+        public String roundId; // 局id
+        public long lastRoundScore; // 本人当前积分
+        public long incrementalScore; // 充值积分
+        public long totalScore; // 充值后总积分
+    }
+
+    /**
+     * 25. 创建订单
+     */
+    public static final String MG_COMMON_GAME_CREATE_ORDER = "mg_common_game_create_order";
+
+    /**
+     * 25. 创建订单 模型
+     */
+    public static class MGCommonGameCreateOrder implements Serializable {
+        public String cmd; // 触发的行为动作,比如打赏,购买等
+        public String fromUid; // 付费用户uid
+        public String toUid; // 目标用户uid
+        public long value; // 所属的游戏价值
+        public String payload; // 扩展数据 json 字符串, 特殊可选
+    }
+
+    /**
+     * 26. 游戏通知app玩家角色(仅对狼人杀有效)
+     */
+    public static final String MG_COMMON_PLAYER_ROLE_ID = "mg_common_player_role_id";
+
+    /**
+     * 26. 游戏通知app玩家角色(仅对狼人杀有效) 模型
+     */
+    public static class MGCommonPlayerRoleId implements Serializable {
+        public List<MGCommonPlayerModel> playersRoleId; // 列表
+
+        public static class MGCommonPlayerModel implements Serializable {
+            public String uid; // 玩家id
+            public int roleId; // 角色id
+        }
+    }
+
+    /**
+     * 27. 游戏通知app玩家被扔便便(你画我猜,你说我猜,友尽闯关有效)
+     */
+    public static final String MG_COMMON_SELF_CLICK_POOP = "mg_common_self_click_poop";
+
+    /**
+     * 27. 游戏通知app玩家被扔便便(你画我猜,你说我猜,友尽闯关有效) 模型
+     */
+    public static class MGCommonSelfClickPoop implements Serializable {
+    }
+
+    /**
+     * 28. 游戏通知app玩家被点赞(你画我猜,你说我猜,友尽闯关有效)
+     */
+    public static final String MG_COMMON_SELF_CLICK_GOOD = "mg_common_self_click_good";
+
+    /**
+     * 28. 游戏通知app玩家被点赞(你画我猜,你说我猜,友尽闯关有效) 模型
+     */
+    public static class MGCommonSelfClickGood implements Serializable {
+    }
+
+    /**
+     * 29. 游戏通知app游戏FPS(仅对碰碰,多米诺骨牌,飞镖达人生效)
+     */
+    public static final String MG_COMMON_GAME_FPS = "mg_common_game_fps";
+
+    /**
+     * 29. 游戏通知app游戏FPS(仅对碰碰,多米诺骨牌,飞镖达人生效) 模型
+     */
+    public static class MGCommonGameFps implements Serializable {
+        public int fps;
+    }
+
+    /**
+     * 30. 游戏通知app游戏弹框
+     */
+    public static final String MG_COMMON_ALERT = "mg_common_alert";
+
+    /**
+     * 30. 游戏通知app游戏弹框 模型
+     */
+    public static class MGCommonAlert implements Serializable {
+        public String state; // show:显示,close:关闭
+    }
+
+    /**
+     * 31. 游戏通知app最坑队友(只支持友尽闯关)
+     */
+    public static final String MG_COMMON_WORST_TEAMMATE = "mg_common_worst_teammate";
+
+    /**
+     * 31. 游戏通知app最坑队友(只支持友尽闯关) 模型
+     */
+    public static class MGCommonWorstTeammate implements Serializable {
+        public String uid; // 最坑队友的uid
+    }
+
+    /**
+     * 32. 游戏通知app因玩家逃跑导致游戏结束(只支持友尽闯关)
+     */
+    public static final String MG_COMMON_GAME_OVER_TIP = "mg_common_game_over_tip";
+
+    /**
+     * 32. 游戏通知app因玩家逃跑导致游戏结束(只支持友尽闯关) 模型
+     */
+    public static class MGCommonGameOverTip implements Serializable {
+        public List<String> uids; // 逃跑玩家的uid数组
+    }
+
+    /**
+     * 33. 游戏通知app玩家颜色(只支持友尽闯关)
+     */
+    public static final String MG_COMMON_GAME_PLAYER_COLOR = "mg_common_game_player_color";
+
+    /**
+     * 33. 游戏通知app玩家颜色(只支持友尽闯关) 模型
+     */
+    public static class MGCommonGamePlayerColor implements Serializable {
+        public List<PlayerColorModel> players;
+
+        public static class PlayerColorModel {
+            public String uid; // 用户id
+            public int color; // color:1是粉色,2是紫色,3是绿色,4是蓝色,5是黄色,6是橙色
+        }
+    }
+
+    /**
+     * 34. 游戏通知app玩家头像的坐标(只支持ludo)
+     */
+    public static final String MG_COMMON_GAME_PLAYER_ICON_POSITION = "mg_common_game_player_icon_position";
+
+    /**
+     * 34. 游戏通知app玩家头像的坐标(只支持ludo) 模型
+     */
+    public static class MGCommonGamePlayerIconPosition implements Serializable {
+        public String uid;
+        public PlayerIconPositionModel position;
+
+        public static class PlayerIconPositionModel {
+            // 头像坐标和宽高,坐标为头像中心
+            public double x;
+            public double y;
+            public double width;
+            public double height;
+        }
+    }
+
+    /**
+     * 35. 游戏通知app退出游戏(只支持teenpattipro 与 德州pro)
+     */
+    public static final String MG_COMMON_SELF_CLICK_EXIT_GAME_BTN = "mg_common_self_click_exit_game_btn";
+
+    /**
+     * 35. 游戏通知app退出游戏(只支持teenpattipro 与 德州pro) 模型
+     */
+    public static class MGCommonSelfClickExitGameBtn implements Serializable {
+    }
+
+    /**
+     * 36. 游戏通知app是否要开启带入积分(只支持teenpattipro 与 德州pro)
+     */
+    public static final String MG_COMMON_GAME_IS_APP_CHIP = "mg_common_game_is_app_chip";
+
+    /**
+     * 36. 游戏通知app是否要开启带入积分(只支持teenpattipro 与 德州pro) 模型
+     */
+    public static class MGCommonGameIsAppChip implements Serializable {
+        public int isAppChip; // 0:不开启,1:开启
+    }
+
+    /**
+     * 37. 游戏通知app当前游戏的设置信息(只支持德州pro,teenpatti pro)
+     */
+    public static final String MG_COMMON_GAME_RULE = "mg_common_game_rule";
+
+    /**
+     * 37. 游戏通知app当前游戏的设置信息(只支持德州pro,teenpatti pro) 模型
+     */
+    public static class MGCommonGameRule implements Serializable {
+        public GameRuleModel gameMode;
+
+        // 德州与teenpatti的结构融合在一起
+        public static class GameRuleModel {
+            public Integer smallBlind; // 小盲
+            public Integer ante; // 前注
+            public Integer isStraddle; // 0:关闭,1自由,2强制
+            public Integer sBuyIn; // 带入值/最小带入配置
+            public Integer bBuyIn; // 最大带入,无限(0)
+            public Integer isAutoStart; // 是否自动开始
+            public Double tableDuration; // 牌桌时长配置(小时)
+            public Integer thinkTime; // 思考时间(秒)
+            public Integer darkCard; // 暗牌回合
+            public Integer potLimit; // 最大带入
+            public Integer round; // 最大回合
+            public Integer singleLimit; // 单注限
+        }
+    }
+
+    /**
+     * 38. 游戏通知app进行玩法设置(只支持德州pro,teenpatti pro)
+     */
+    public static final String MG_COMMON_GAME_SETTINGS = "mg_common_game_settings";
+
+    /**
+     * 38. 游戏通知app进行玩法设置(只支持德州pro,teenpatti pro) 模型
+     */
+    public static class MGCommonGameSettings implements Serializable {
+    }
+
+    /**
+     * 39. 游戏通知app钱币不足(只支持德州pro,teenpatti pro)
+     */
+    public static final String MG_COMMON_GAME_MONEY_NOT_ENOUGH = "mg_common_game_money_not_enough";
+
+    /**
+     * 39. 游戏通知app钱币不足(只支持德州pro,teenpatti pro) 模型
+     */
+    public static class MGCommonGameMoneyNotEnough implements Serializable {
+    }
+
+    /**
+     * 40. 游戏通知app下发定制ui配置表(只支持ludo)
+     */
+    public static final String MG_COMMON_GAME_UI_CUSTOM_CONFIG = "mg_common_game_ui_custom_config";
+
+    /**
+     * 40. 游戏通知app下发定制ui配置表(只支持ludo) 模型
+     */
+    public static class MGCommonGameUiCustomConfig implements Serializable {
+    }
+
+    /**
+     * 41. 设置app提供给游戏可点击区域(赛车)
+     */
+    public static final String MG_COMMON_SET_CLICK_RECT = "mg_common_set_click_rect";
+
+    /**
+     * 41. 设置app提供给游戏可点击区域(赛车) 模型
+     */
+    public static class MGCommonSetClickRect implements Serializable {
+        public List<InteractionClickRect> list; // 游戏的点击区域
+    }
+
+    /**
+     * 42. 通知app提供对应uids列表玩家的数据(赛车)
+     */
+    public static final String MG_COMMON_USERS_INFO = "mg_common_users_info";
+
+    /**
+     * 42. 通知app提供对应uids列表玩家的数据(赛车) 模型
+     */
+    public static class MGCommonUsersInfo implements Serializable {
+        public List<String> uids;
+    }
+
+    /**
+     * 43. 通知app游戏前期准备完成(赛车)
+     */
+    public static final String MG_COMMON_GAME_PREPARE_FINISH = "mg_common_game_prepare_finish";
+
+    /**
+     * 43. 通知app游戏前期准备完成(赛车) 模型
+     */
+    public static class MGCommonGamePrepareFinish implements Serializable {
+    }
+
+    /**
+     * 44. 通知app游戏主界面已显示(赛车)
+     */
+    public static final String MG_COMMON_SHOW_GAME_SCENE = "mg_common_show_game_scene";
+
+    /**
+     * 44. 通知app游戏主界面已显示(赛车) 模型
+     */
+    public static class MGCommonShowGameScene implements Serializable {
+    }
+
+    /**
+     * 45. 通知app游戏主界面已隐藏(赛车)
+     */
+    public static final String MG_COMMON_HIDE_GAME_SCENE = "mg_common_hide_game_scene";
+
+    /**
+     * 45. 通知app游戏主界面已隐藏(赛车) 模型
+     */
+    public static class MGCommonHideGameScene implements Serializable {
+    }
+    // endregion 通用状态-游戏
+
+    // region MG状态机-通用状态-玩家
+    // 参考:https://docs.sud.tech/zh-CN/app/Client/MGFSM/CommonStatePlayer.html
+
+    /**
+     * 1.加入状态(已修改)
+     * 最低版本: v1.1.30.xx
+     */
+    public static final String MG_COMMON_PLAYER_IN = "mg_common_player_in";
+
+    /**
+     * 1.加入状态(已修改) 模型
+     * 用户是否加入游戏;
+     * 游戏开始后,未加入的用户为OB视角。
+     */
+    public static class MGCommonPlayerIn implements Serializable {
+        // true 已加入,false 未加入
+        public boolean isIn;
+
+        // 加入哪支队伍
+        public int teamId;
+
+        // 当isIn==false时有效;0 主动退出,1 被踢;(reason默认-1,无意义便于处理)
+        public int reason;
+
+        // 当reason==1时有效;kickUID为踢人的用户uid;判断被踢的人是本人条件(onPlayerStateChange(userId==kickedUID == selfUID);(kickUID默认"",无意义便于处理)
+        public String kickUID;
+    }
+
+    /**
+     * 2.准备状态(已修改)
+     * 最低版本: v1.1.30.xx
+     */
+    public static final String MG_COMMON_PLAYER_READY = "mg_common_player_ready";
+
+    /**
+     * 2.准备状态(已修改) 模型
+     * 用户是否为队长,队长在游戏中会有开始游戏的权利。
+     */
+    public static class MGCommonPlayerReady implements Serializable {
+        // 当retCode==0时有效;true 已准备,false 未准备
+        public boolean isReady;
+    }
+
+    /**
+     * 3.队长状态(已修改)
+     * 最低版本: v1.1.30.xx
+     */
+    public static final String MG_COMMON_PLAYER_CAPTAIN = "mg_common_player_captain";
+
+    /**
+     * 3.队长状态(已修改) 模型
+     * 用户是否为队长,队长在游戏中会有开始游戏的权利。
+     */
+    public static class MGCommonPlayerCaptain implements Serializable {
+        // true 是队长,false 不是队长;
+        public boolean isCaptain;
+    }
+
+    /**
+     * 4.游戏状态(已修改)
+     * 最低版本: v1.1.30.xx
+     */
+    public static final String MG_COMMON_PLAYER_PLAYING = "mg_common_player_playing";
+
+    /**
+     * 4.游戏状态(已修改)模型
+     * 用户游戏状态,如果用户在游戏中,建议:
+     * a.空出屏幕中心区:
+     * 关闭全屏礼物特效;
+     * b.部分强操作类小游戏(spaceMax为true),尽量收缩原生UI,给游戏留出尽量大的操作空间:
+     * 收缩公屏;
+     * 收缩麦位;
+     * 如果不在游戏中,则恢复。
+     */
+    public static class MGCommonPlayerPlaying implements Serializable {
+        // true 游戏中,false 未在游戏中;
+        public boolean isPlaying;
+        // 本轮游戏id,当isPlaying==true时有效
+        public String gameRoundId;
+        // 当isPlaying==false时有效;isPlaying=false, 0:正常结束 1:提前结束(自己不玩了)2:无真人可以提前结束(无真人,只有机器人) 3:所有人都提前结束;(reason默认-1,无意义便于处理)
+        public int reason;
+        // true 建议尽量收缩原生UI,给游戏留出尽量大的操作空间 false 初始状态;
+        public Boolean spaceMax;
+    }
+
+    /**
+     * 5.玩家在线状态
+     */
+    public static final String MG_COMMON_PLAYER_ONLINE = "mg_common_player_online";
+
+    /**
+     * 5.玩家在线状态 模型
+     */
+    public static class MGCommonPlayerOnline implements Serializable {
+        // true:在线,false: 离线
+        public boolean isOnline;
+    }
+
+    /**
+     * 6.玩家换游戏位状态
+     */
+    public static final String MG_COMMON_PLAYER_CHANGE_SEAT = "mg_common_player_change_seat";
+
+    /**
+     * 6.玩家换游戏位状态 模型
+     */
+    public static class MGCommonPlayerChangeSeat implements Serializable {
+        // 换位前的游戏位(座位号)
+        public int preSeatIndex;
+        // 换位成功后的游戏位(座位号)
+        public int currentSeatIndex;
+    }
+
+    /**
+     * 7. 游戏通知app点击玩家头像
+     */
+    public static final String MG_COMMON_SELF_CLICK_GAME_PLAYER_ICON = "mg_common_self_click_game_player_icon";
+
+    /**
+     * 7. 游戏通知app点击玩家头像 模型
+     */
+    public static class MGCommonSelfClickGamePlayerIcon implements Serializable {
+        // 被点击头像的用户id
+        public String uid;
+    }
+
+    /**
+     * 8. 游戏通知app玩家死亡状态(2022-04-24新增)
+     */
+    public static final String MG_COMMON_SELF_DIE_STATUS = "mg_common_self_die_status";
+
+    /**
+     * 8. 游戏通知app玩家死亡状态(2022-04-24新增)模型
+     */
+    public static class MGCommonSelfDieStatus implements Serializable {
+        public String uid; // 用户id
+        public boolean isDeath; // 玩家是否死亡 true:死亡, false: 未死亡;默认 false
+    }
+
+    /**
+     * 9. 游戏通知app轮到玩家出手状态(2022-04-24新增)
+     */
+    public static final String MG_COMMON_SELF_TURN_STATUS = "mg_common_self_turn_status";
+
+    /**
+     * 9. 游戏通知app轮到玩家出手状态(2022-04-24新增)模型
+     */
+    public static class MGCommonSelfTurnStatus implements Serializable {
+        public String uid; // 用户id
+        public boolean isTurn; // 是否轮到玩家出手 true:是上面uid玩家的出手回合, false: 不是上面uid玩家的出手回合;默认false
+    }
+
+    /**
+     * 10. 游戏通知app玩家选择状态(2022-04-24新增)
+     */
+    public static final String MG_COMMON_SELF_SELECT_STATUS = "mg_common_self_select_status";
+
+    /**
+     * 10. 游戏通知app玩家选择状态(2022-04-24新增)模型
+     */
+    public static class MGCommonSelfSelectStatus implements Serializable {
+        public String uid; // 用户id
+        public boolean isSelected; // 玩家是否选择 true:选择, false: 未选择; 默认false
+    }
+
+    /**
+     * 11. 游戏通知app层当前游戏剩余时间(2022-05-23新增,目前UMO生效)
+     */
+    public static final String MG_COMMON_GAME_COUNTDOWN_TIME = "mg_common_game_countdown_time";
+
+    /**
+     * 11. 游戏通知app层当前游戏剩余时间(2022-05-23新增,目前UMO生效)模型
+     */
+    public static class MGCommonGameCountdownTime implements Serializable {
+        public int countdown;// 剩余时间,单位为秒
+    }
+
+    /**
+     * 12. 游戏通知app层当前玩家死亡后变成ob视角(2022-08-23新增,目前狼人杀生效)
+     */
+    public static final String MG_COMMON_SELF_OB_STATUS = "mg_common_self_ob_status";
+
+    /**
+     * 12. 游戏通知app层当前玩家死亡后变成ob视角(2022-08-23新增,目前狼人杀生效)模型
+     */
+    public static class MGCommonSelfObStatus implements Serializable {
+        public boolean isOb;// 是否成为ob视角
+    }
+
+    // endregion 通用状态-玩家
+
+
+    // region 碰碰我最强
+    // endregion 碰碰我最强
+
+    // region 飞刀达人
+    // endregion 飞刀达人
+
+    // region 你画我猜
+    // 参考文档:https://docs.sud.tech/zh-CN/app/Client/MGFSM/DrawGuess.html
+
+    /**
+     * 1. 选词中状态(已修改)
+     */
+    public static final String MG_DG_SELECTING = "mg_dg_selecting";
+
+    /**
+     * 1. 选词中状态(已修改) 模型
+     * 选词中,头像正下方
+     */
+    public static class MGDGSelecting implements Serializable {
+        // bool 类型 true:正在选词中,false: 不在选词中
+        public boolean isSelecting;
+    }
+
+    /**
+     * 2. 作画中状态(已修改)
+     */
+    public static final String MG_DG_PAINTING = "mg_dg_painting";
+
+    /**
+     * 2. 作画中状态(已修改) 模型
+     * 作画中,头像正下方
+     */
+    public static class MGDGPainting implements Serializable {
+        // true: 绘画中,false: 取消绘画
+        public boolean isPainting;
+    }
+
+    /**
+     * 3. 显示错误答案状态(已修改)
+     */
+    public static final String MG_DG_ERRORANSWER = "mg_dg_erroranswer";
+
+    /**
+     * 3. 显示错误答案状态(已修改) 模型
+     * 错误的答案,最多6中文,头像正下方
+     */
+    public static class MGDGErroranswer implements Serializable {
+        // 字符串类型,展示错误答案
+        public String msg;
+    }
+
+    /**
+     * 4. 显示总积分状态(已修改)
+     */
+    public static final String MG_DG_TOTALSCORE = "mg_dg_totalscore";
+
+    /**
+     * 4. 显示总积分状态(已修改) 模型
+     * 总积分,位于头像右上角
+     */
+    public static class MGDGTotalscore implements Serializable {
+        // 字符串类型 总积分
+        public String msg;
+    }
+
+    /**
+     * 5. 本次获得积分状态(已修改)
+     */
+    public static final String MG_DG_SCORE = "mg_dg_score";
+
+    /**
+     * 5. 本次获得积分状态(已修改) 模型
+     * 本次积分,头像正下方
+     */
+    public static final class MGDGScore implements Serializable {
+        // string类型,展示本次获得积分
+        public String msg;
+    }
+
+    // endregion 你画我猜
+
+    // region 元宇宙砂砂舞
+    /**
+     * 1. 元宇宙砂砂舞指令回调
+     */
+    public static final String MG_COMMON_GAME_DISCO_ACTION = "mg_common_game_disco_action";
+
+    /**
+     * 1. 元宇宙砂砂舞指令回调 模型
+     * app指令请求游戏客户端成功与否的回调
+     */
+    public static final class MGCommonGameDiscoAction implements Serializable {
+        public int actionId; // 指令序号类型
+        public boolean isSuccess; // true 指令成功,false 指令失败
+    }
+
+    /**
+     * 2. 元宇宙砂砂舞指令动作结束通知
+     */
+    public static final String MG_COMMON_GAME_DISCO_ACTION_END = "mg_common_game_disco_action_end";
+
+    /**
+     * 2. 元宇宙砂砂舞指令动作结束通知 模型
+     * 游戏客户端通知APP指令动作结束
+     */
+    public static final class MGCommonGameDiscoActionEnd implements Serializable {
+        public int actionId; // 指令序号类型
+        public String playerId; // // 玩家ID string 类型
+    }
+    // endregion 元宇宙砂砂舞
+
+    // region 定制火箭
+    /**
+     * 1. 礼物配置文件(火箭)
+     */
+    public static final String MG_CUSTOM_ROCKET_CONFIG = "mg_custom_rocket_config";
+
+    /**
+     * 1. 礼物配置文件(火箭) 模型
+     */
+    public static final class MGCustomRocketConfig implements Serializable {
+    }
+
+    /**
+     * 2. 拥有模型列表(火箭)
+     */
+    public static final String MG_CUSTOM_ROCKET_MODEL_LIST = "mg_custom_rocket_model_list";
+
+    /**
+     * 2. 拥有模型列表(火箭) 模型
+     */
+    public static final class MGCustomRocketModelList implements Serializable {
+    }
+
+    /**
+     * 3. 拥有组件列表(火箭)
+     */
+    public static final String MG_CUSTOM_ROCKET_COMPONENT_LIST = "mg_custom_rocket_component_list";
+
+    /**
+     * 3. 拥有组件列表(火箭) 模型
+     */
+    public static final class MGCustomRocketComponentList implements Serializable {
+    }
+
+    /**
+     * 4. 获取用户信息(火箭)
+     */
+    public static final String MG_CUSTOM_ROCKET_USER_INFO = "mg_custom_rocket_user_info";
+
+    /**
+     * 4. 获取用户信息 模型
+     */
+    public static final class MGCustomRocketUserInfo implements Serializable {
+        public List<String> userIdList;
+    }
+
+    /**
+     * 5. 订单记录列表(火箭)
+     */
+    public static final String MG_CUSTOM_ROCKET_ORDER_RECORD_LIST = "mg_custom_rocket_order_record_list";
+
+    /**
+     * 5. 订单记录列表(火箭) 模型
+     */
+    public static final class MGCustomRocketOrderRecordList implements Serializable {
+        public int pageIndex; // 第几页
+        public int pageSize; // 每页多少条数据
+    }
+
+    /**
+     * 6. 展馆内列表(火箭)
+     */
+    public static final String MG_CUSTOM_ROCKET_ROOM_RECORD_LIST = "mg_custom_rocket_room_record_list";
+
+    /**
+     * 6. 展馆内列表(火箭) 模型
+     */
+    public static final class MGCustomRocketRoomRecordList implements Serializable {
+        public int pageIndex; // 第几页
+        public int pageSize; // 每页多少条数据
+    }
+
+    /**
+     * 7. 展馆内玩家送出记录(火箭)
+     */
+    public static final String MG_CUSTOM_ROCKET_USER_RECORD_LIST = "mg_custom_rocket_user_record_list";
+
+    /**
+     * 7. 展馆内玩家送出记录(火箭) 模型
+     */
+    public static final class MGCustomRocketUserRecordList implements Serializable {
+        public String userId; // 用户id
+        public int pageIndex; // 第几页
+        public int pageSize; // 每页多少条数据
+    }
+
+    /**
+     * 8. 设置默认模型(火箭)
+     */
+    public static final String MG_CUSTOM_ROCKET_SET_DEFAULT_MODEL = "mg_custom_rocket_set_default_model";
+
+    /**
+     * 8. 设置默认模型(火箭) 模型
+     */
+    public static final class MGCustomRocketSetDefaultModel implements Serializable {
+        public String modelId; // 默认模型
+    }
+
+    /**
+     * 9. 动态计算一键发送价格(火箭)
+     */
+    public static final String MG_CUSTOM_ROCKET_DYNAMIC_FIRE_PRICE = "mg_custom_rocket_dynamic_fire_price";
+
+    /**
+     * 9. 动态计算一键发送价格(火箭) 模型
+     */
+    public static final class MGCustomRocketDynamicFirePrice implements Serializable {
+        public List<ComponentModel> componentList; // 组件列表
+
+        public static class ComponentModel {
+            public String itemId; // 已购买的唯一标识
+        }
+    }
+
+    /**
+     * 10. 一键发送(火箭)
+     */
+    public static final String MG_CUSTOM_ROCKET_FIRE_MODEL = "mg_custom_rocket_fire_model";
+
+    /**
+     * 10. 一键发送(火箭) 模型
+     */
+    public static final class MGCustomRocketFireModel implements Serializable {
+        public List<ComponentModel> componentList; // 组件列表
+
+        public static class ComponentModel {
+            public int type; // 类型
+            public String itemId; // 已购买的唯一标识
+        }
+    }
+
+    /**
+     * 11. 新组装模型(火箭)
+     */
+    public static final String MG_CUSTOM_ROCKET_CREATE_MODEL = "mg_custom_rocket_create_model";
+
+    /**
+     * 11. 新组装模型(火箭) 模型
+     */
+    public static final class MGCustomRocketCreateModel implements Serializable {
+        public List<ComponentModel> componentList; // 组件列表
+
+        public static class ComponentModel {
+            public String itemId; // 模型Id
+        }
+    }
+
+    /**
+     * 12. 模型更换组件(火箭)
+     */
+    public static final String MG_CUSTOM_ROCKET_REPLACE_COMPONENT = "mg_custom_rocket_replace_component";
+
+    /**
+     * 12. 模型更换组件(火箭) 模型
+     */
+    public static final class MGCustomRocketReplaceComponent implements Serializable {
+        public String modelId; // 模型ID
+        public List<ComponentModel> componentList; // 组件列表
+
+        public static class ComponentModel {
+            public String itemId; // 已购买的唯一标识
+        }
+    }
+
+    /**
+     * 13. 购买组件(火箭)
+     */
+    public static final String MG_CUSTOM_ROCKET_BUY_COMPONENT = "mg_custom_rocket_buy_component";
+
+    /**
+     * 13. 购买组件(火箭) 模型
+     */
+    public static final class MGCustomRocketBuyComponent implements Serializable {
+        public List<ComponentModel> componentList; // 组件列表
+
+        public static class ComponentModel {
+            public String componentId; // 已购买的唯一标识
+            public String value; // 值
+        }
+    }
+
+    /**
+     * 14. 播放效果开始(火箭)
+     */
+    public static final String MG_CUSTOM_ROCKET_PLAY_EFFECT_START = "mg_custom_rocket_play_effect_start";
+
+    /**
+     * 14. 播放效果开始(火箭) 模型
+     */
+    public static final class MGCustomRocketPlayEffectStart implements Serializable {
+    }
+
+    /**
+     * 15. 播放效果完成(火箭)
+     */
+    public static final String MG_CUSTOM_ROCKET_PLAY_EFFECT_FINISH = "mg_custom_rocket_play_effect_finish";
+
+    /**
+     * 15. 播放效果完成(火箭) 模型
+     */
+    public static final class MGCustomRocketPlayEffectFinish implements Serializable {
+    }
+
+    /**
+     * 16. 验证签名合规(火箭)
+     */
+    public static final String MG_CUSTOM_ROCKET_VERIFY_SIGN = "mg_custom_rocket_verify_sign";
+
+    /**
+     * 16. 验证签名合规(火箭) 模型
+     */
+    public static final class MGCustomRocketVerifySign implements Serializable {
+        public String sign; // 验证的内容
+    }
+
+    /**
+     * 17. 上传icon(火箭)
+     */
+    public static final String MG_CUSTOM_ROCKET_UPLOAD_MODEL_ICON = "mg_custom_rocket_upload_model_icon";
+
+    /**
+     * 17. 上传icon(火箭) 模型
+     */
+    public static final class MGCustomRocketUploadModelIcon implements Serializable {
+        public String data; // 图片base64数据
+    }
+
+    /**
+     * 18. 前期准备完成(火箭)
+     * 表示app此时可以向火箭发出指令了
+     */
+    public static final String MG_CUSTOM_ROCKET_PREPARE_FINISH = "mg_custom_rocket_prepare_finish";
+
+    /**
+     * 18. 前期准备完成(火箭) 模型
+     */
+    public static final class MGCustomRocketPrepareFinish implements Serializable {
+    }
+
+    /**
+     * 19. 火箭主界面已显示(火箭)
+     */
+    public static final String MG_CUSTOM_ROCKET_SHOW_GAME_SCENE = "mg_custom_rocket_show_game_scene";
+
+    /**
+     * 19. 火箭主界面已显示(火箭) 模型
+     */
+    public static final class MGCustomRocketShowGameScene implements Serializable {
+    }
+
+    /**
+     * 20. 火箭主界面已隐藏(火箭)
+     */
+    public static final String MG_CUSTOM_ROCKET_HIDE_GAME_SCENE = "mg_custom_rocket_hide_game_scene";
+
+    /**
+     * 20. 火箭主界面已隐藏(火箭) 模型
+     */
+    public static final class MGCustomRocketHideGameScene implements Serializable {
+    }
+
+    /**
+     * 21. 点击锁住组件(火箭)
+     */
+    public static final String MG_CUSTOM_ROCKET_CLICK_LOCK_COMPONENT = "mg_custom_rocket_click_lock_component";
+
+    /**
+     * 21. 点击锁住组件(火箭) 模型
+     */
+    public static final class MGCustomRocketClickLockComponent implements Serializable {
+        public int type; // 组件类型
+        public String componentId; // 组件ID
+    }
+
+    /**
+     * 22. 火箭效果飞行点击(火箭)
+     */
+    public static final String MG_CUSTOM_ROCKET_FLY_CLICK = "mg_custom_rocket_fly_click";
+
+    /**
+     * 22. 火箭效果飞行点击(火箭) 模型
+     */
+    public static final class MGCustomRocketFlyClick implements Serializable {
+    }
+
+    /**
+     * 23. 火箭效果飞行结束(火箭)
+     */
+    public static final String MG_CUSTOM_ROCKET_FLY_END = "mg_custom_rocket_fly_end";
+
+    /**
+     * 23. 火箭效果飞行结束(火箭) 模型
+     */
+    public static final class MGCustomRocketFlyEnd implements Serializable {
+        public long clickNumber; // 点击多少次
+        public long flyNumber; // 飞行多远
+    }
+
+    /**
+     * 24. 设置点击区域(火箭)
+     */
+    public static final String MG_CUSTOM_ROCKET_SET_CLICK_RECT = "mg_custom_rocket_set_click_rect";
+
+    /**
+     * 24. 设置点击区域(火箭) 模型
+     */
+    public static final class MGCustomRocketSetClickRect implements Serializable {
+        public List<InteractionClickRect> list; // 游戏的点击区域
+    }
+
+    /**
+     * 25. 颜色和签名自定义改到装配间的模式,保存颜色或签名
+     */
+    public static final String MG_CUSTOM_ROCKET_SAVE_SIGN_COLOR = "mg_custom_rocket_save_sign_color";
+
+    /**
+     * 25. 颜色和签名自定义改到装配间的模式,保存颜色或签名 模型
+     */
+    public static final class MGCustomRocketSaveSignColor implements Serializable {
+        public List<ComponentModel> componentList;
+
+        public static class ComponentModel {
+            public String componentId; // 组件的ID
+            public String value; // 颜色值,采用十六进制
+            public String modelId; // 模型id (更新模型时使用)
+        }
+    }
+    // endregion 定制火箭
+
+    // region 棒球
+    /**
+     * 1. 查询排行榜数据(棒球)
+     * 游戏客户端通知APP查询排行榜数据
+     */
+    public static final String MG_BASEBALL_RANKING = "mg_baseball_ranking";
+
+    /**
+     * 1. 查询排行榜数据(棒球) 模型
+     */
+    public static final class MGBaseballRanking implements Serializable {
+        public int page; // 页数
+        public int size; // 每页显示的数量
+    }
+
+    /**
+     * 2. 查询我的排名(棒球)
+     * 游戏客户端通知APP查询我的排名
+     */
+    public static final String MG_BASEBALL_MY_RANKING = "mg_baseball_my_ranking";
+
+    /**
+     * 2. 查询我的排名(棒球) 模型
+     */
+    public static final class MGBaseballMyRanking implements Serializable {
+    }
+
+    /**
+     * 3. 查询当前距离我的前后玩家数据(棒球)
+     * 游戏客户端通知APP查询当前距离我的前后玩家数据(需要排除自己)
+     */
+    public static final String MG_BASEBALL_RANGE_INFO = "mg_baseball_range_info";
+
+    /**
+     * 3. 查询当前距离我的前后玩家数据(棒球) 模型
+     */
+    public static final class MGBaseballRangeInfo implements Serializable {
+        public long distance; // 自己当前的距离
+    }
+
+    /**
+     * 4. 设置app提供给游戏可点击区域(棒球)
+     * 游戏客户端通知APP指令动作设置点击区域
+     */
+    public static final String MG_BASEBALL_SET_CLICK_RECT = "mg_baseball_set_click_rect";
+
+    /**
+     * 4. 设置app提供给游戏可点击区域(棒球) 模型
+     */
+    public static final class MGBaseballSetClickRect implements Serializable {
+        public List<InteractionClickRect> list;
+    }
+
+    /**
+     * 5. 前期准备完成(棒球)
+     * 游戏客户端通知APP指令动作前期准备完成
+     */
+    public static final String MG_BASEBALL_PREPARE_FINISH = "mg_baseball_prepare_finish";
+
+    /**
+     * 5. 前期准备完成(棒球) 模型
+     */
+    public static final class MGBaseballPrepareFinish implements Serializable {
+    }
+
+    /**
+     * 6. 主界面已显示(棒球)
+     * 游戏客户端通知APP指令动作主界面已显示
+     */
+    public static final String MG_BASEBALL_SHOW_GAME_SCENE = "mg_baseball_show_game_scene";
+
+    /**
+     * 6. 主界面已显示(棒球) 模型
+     */
+    public static final class MGBaseballShowGameScene implements Serializable {
+    }
+
+    /**
+     * 7. 主界面已隐藏(棒球)
+     * 游戏客户端通知APP指令动作主界面已隐藏
+     */
+    public static final String MG_BASEBALL_HIDE_GAME_SCENE = "mg_baseball_hide_game_scene";
+
+    /**
+     * 7. 主界面已隐藏(棒球) 模型
+     */
+    public static final class MGBaseballHideGameScene implements Serializable {
+    }
+
+    /**
+     * 8. 获取文本配置数据(棒球)
+     */
+    public static final String MG_BASEBALL_TEXT_CONFIG = "mg_baseball_text_config";
+
+    /**
+     * 8. 获取文本配置数据(棒球) 模型
+     */
+    public static final class MGBaseballTextConfig implements Serializable {
+    }
+    // endregion 棒球
+
+    /** 点击区域定义 */
+    public static class InteractionClickRect {
+        public float x; // 区域的x
+        public float y; // 区域的y
+        public float width; // 区域的width
+        public float height; // 区域的height
+    }
+
+}
diff --git a/common/src/main/java/com/yunbao/common/utils/ISudFSMStateHandleUtils.java b/common/src/main/java/com/yunbao/common/utils/ISudFSMStateHandleUtils.java
new file mode 100644
index 000000000..581607d77
--- /dev/null
+++ b/common/src/main/java/com/yunbao/common/utils/ISudFSMStateHandleUtils.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright © Sud.Tech
+ * https://sud.tech
+ */
+
+package com.yunbao.common.utils;
+
+import com.yunbao.common.sud.state.MGStateResponse;
+
+import tech.sud.mgp.core.ISudFSMStateHandle;
+
+public class ISudFSMStateHandleUtils {
+
+    /**
+     * 回调游戏,成功
+     *
+     * @param handle
+     */
+    public static void handleSuccess(ISudFSMStateHandle handle) {
+        MGStateResponse response = new MGStateResponse();
+        response.ret_code = MGStateResponse.SUCCESS;
+        response.ret_msg = "success";
+        handle.success(SudJsonUtils.toJson(response));
+    }
+
+}
diff --git a/common/src/main/java/com/yunbao/common/utils/SudJsonUtils.java b/common/src/main/java/com/yunbao/common/utils/SudJsonUtils.java
new file mode 100644
index 000000000..5cc790238
--- /dev/null
+++ b/common/src/main/java/com/yunbao/common/utils/SudJsonUtils.java
@@ -0,0 +1,43 @@
+package com.yunbao.common.utils;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+
+/**
+ * json解析工具
+ */
+public class SudJsonUtils {
+
+    /**
+     * 解析json
+     *
+     * @return 如果解析出错,则返回空对象
+     */
+    public static <T> T fromJson(final String json, final Class<T> type) {
+        try {
+            return getGson().fromJson(json, type);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    /**
+     * 对象解析成json
+     *
+     * @param object
+     * @return
+     */
+    public static String toJson(final Object object) {
+        return getGson().toJson(object);
+    }
+
+    public static Gson getGson() {
+        return InnerClass.gson;
+    }
+
+    public static class InnerClass {
+        public static Gson gson = new GsonBuilder().disableHtmlEscaping().create();
+    }
+
+}
diff --git a/config.gradle b/config.gradle
index 3e1349d45..7a8acf55c 100644
--- a/config.gradle
+++ b/config.gradle
@@ -9,9 +9,9 @@ ext {
     ]
     manifestPlaceholders = [
             //正式、
-//            serverHost       : "https://napi.yaoulive.com",
+            serverHost       : "https://napi.yaoulive.com",
 //             测试
-            serverHost       : " https://ceshi.yaoulive.com",
+//            serverHost       : " https://ceshi.yaoulive.com",