ゲーム開発中のprotobuf自動復号DEMO
3177 ワード
私はゲームサービスの开発者で、开発の中でprotobufの復号操作は比较的に面倒で、復号するたびに多くの重複するコードを书く必要があります.また、エラーを処理する必要があります.ツールクラスを设计しました.今、业务ロジックを简単化し、业务の敏感な情报を除去し、発表します.ソースコードを使うには以下の点に注意する必要があります.
1.すべてのprotobufメッセージはgeneratedMessageに基づく.
2.protobuf運転時にprotobuf.exe位置を設定する必要がある
3.反射は比較的に性能を消耗し、設計は反射などの操作をシステムの初期化に置いて行い、結果をmapに置いて、業務運行時に直接取り出す.
4.開発中に注釈を組み合わせることで、mapにclassを追加する必要がなく、構成をさらに簡素化することができます.
5.符号化エラーについては、第三者が悪意を持ってコマンドコードを試みる可能性があり、符号化エラーの統一管理がより容易になる.
復号コードは次のとおりです.
1.すべてのprotobufメッセージはgeneratedMessageに基づく.
2.protobuf運転時にprotobuf.exe位置を設定する必要がある
3.反射は比較的に性能を消耗し、設計は反射などの操作をシステムの初期化に置いて行い、結果をmapに置いて、業務運行時に直接取り出す.
4.開発中に注釈を組み合わせることで、mapにclassを追加する必要がなく、構成をさらに簡素化することができます.
5.符号化エラーについては、第三者が悪意を持ってコマンドコードを試みる可能性があり、符号化エラーの統一管理がより容易になる.
復号コードは次のとおりです.
package code;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import proto.gen.TestProto.MyMsgReq;
import com.google.protobuf.GeneratedMessage;
public class DecordDemo {
private final static Map<Integer, Method> DECODE_METHODS_MAP = new HashMap<Integer, Method>();// MAP
private final static Map<Integer, Class<? extends GeneratedMessage>> DECODE_CLASSES = new HashMap<Integer, Class<? extends GeneratedMessage>>();// map
private final static int MY_MSG_REQ_CMD = 100;
public static void main(String[] args) throws Exception {
initDecode();
MyMsgReq.Builder reqSrc = MyMsgReq.newBuilder().setId(1).setName("mine");
MyMsgReq req = decode(MY_MSG_REQ_CMD, reqSrc.build().toByteArray());
System.out.println(req.getId());
System.out.println(req.getName());
}
/**
* , , MAP ,
* */
public static void initDecode() {
addDecodeMethod(MY_MSG_REQ_CMD, MyMsgReq.class);
}
public static void addDecodeMethod(int cmd, Class<? extends GeneratedMessage> clazz) {
try {
Method m = clazz.getMethod("parseFrom", new Class[] { byte[].class });
if (DECODE_METHODS_MAP.get(cmd) == null) {
DECODE_METHODS_MAP.put(cmd, m);
}
if (DECODE_CLASSES.get(cmd) == null) {
DECODE_CLASSES.put(cmd, clazz);
}
} catch (NoSuchMethodException | SecurityException e) {
e.printStackTrace();
}
}
/**
*
*
* @throws Exception
* */
@SuppressWarnings("unchecked")
public static <T> T decode(int cmd, byte[] data) throws Exception {
Method decodeMethod = DECODE_METHODS_MAP.get(cmd);
Class<? extends GeneratedMessage> clazz = DECODE_CLASSES.get(cmd);
if (decodeMethod == null || clazz == null) {
throw new Exception(" ");
}
T req;
try {
req = (T) decodeMethod.invoke(clazz, new Object[] { data });
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
e.printStackTrace();
throw new Exception(" ", e);
}
return req;
}
}
protobuf :
package proto.gen;
message MyMsgReq {
required int32 id = 1;
optional string name = 2; //
}