通過分析原始碼可以得到以下MatchPlayInfo序列的生成程式碼- const protobuf = require("protobufjs");
- var i = protobuf.Reader, a = protobuf.Writer, r = protobuf.util;
- MatchStepInfo = function () {
- function t(t) {
- if (t)
- for (var e = Object.keys(t), o = 0; o < e.length; ++o) null != t[e[o]] &&
- (this[e[o]] = t[e[o]])
- }
- return t.prototype.chessIndex = 0, t.prototype.timeTag = 0, t.create = function (
- e) {
- return new t(e)
- }, t.encode = function (t, e) {
- return e || (e = a.create()), null != t.chessIndex && Object.hasOwnProperty
- .call(t, "chessIndex") && e.uint32(8).int32(t.chessIndex), null !=
- t.timeTag && Object.hasOwnProperty.call(t, "timeTag") && e.uint32(
- 16).int32(t.timeTag), e
- }, t.decode = function (t, e) {
- t instanceof i || (t = i.create(t));
- for (var o = void 0 === e ? t.len : t.pos + e, n = new MatchStepInfo; t
- .pos < o;) {
- var a = t.uint32();
- switch (a >>> 3) {
- case 1:
- n.chessIndex = t.int32();
- break;
- case 2:
- n.timeTag = t.int32();
- break;
- default:
- t.skipType(7 & a)
- }
- }
- return n
- }, t
- }(), MatchPlayInfo = function () {
- function t(t) {
- if (this.stepInfoList = [], t)
- for (var e = Object.keys(t), o = 0; o < e.length; ++o) null != t[e[o]] &&
- (this[e[o]] = t[e[o]])
- }
- return t.prototype.gameType = 0, t.prototype.mapId = 0, t.prototype.mapSeed = 0,
- t.prototype.stepInfoList = r.emptyArray, t.create = function (e) {
- return new t(e)
- }, t.encode = function (t, e) {
- if (e || (e = a.create()), null != t.gameType && Object.hasOwnProperty.call(
- t, "gameType") && e.uint32(8).int32(t.gameType), null != t.mapId &&
- Object.hasOwnProperty.call(t, "mapId") && e.uint32(16).int32(t.mapId),
- null != t.mapSeed && Object.hasOwnProperty.call(t, "mapSeed") && e.uint32(
- 24).int32(t.mapSeed), null != t.stepInfoList && t.stepInfoList.length
- )
- for (var o = 0; o < t.stepInfoList.length; ++o) MatchStepInfo
- .encode(t.stepInfoList[o], e.uint32(34).fork()).ldelim();
- return e
- }, t.decode = function (t, e) {
- t instanceof i || (t = i.create(t));
- for (var o = void 0 === e ? t.len : t.pos + e, n = new MatchPlayInfo; t
- .pos < o;) {
- var a = t.uint32();
- switch (a >>> 3) {
- case 1:
- n.gameType = t.int32();
- break;
- case 2:
- n.mapId = t.int32();
- break;
- case 3:
- n.mapSeed = t.int32();
- break;
- case 4:
- n.stepInfoList && n.stepInfoList.length || (n.stepInfoList = []),
- n.stepInfoList.push(MatchStepInfo.decode(t,
- t.uint32()));
- break;
- default:
- t.skipType(7 & a)
- }
- }
- return n
- }, t
- }()
- var operationList = []
- function addOp(t, e) { //增加操作
- void 0 === e && (e = -100);
- var o = {
- id: t, // 操作卡片的id,從levelData第一層開始按順序編號
- time: Date.now() // 操作時間
- };
- operationList.push(o)
- }
- function sleep(delay) {
- for (var t = Date.now(); Date.now() - t <= delay;);
- }
- let range = n => [...Array(n).keys()]
- for (let i of range(50)) { // 生成了50次操作
- addOp(i);
- sleep(Math.random() * 10); // 模擬操作過程中的等待
- }
- console.log(operationList)
- for (var u = operationList, p = [], d = 0, h = 0; h < u.length; h++) // 把時間戳轉換為兩次操作的間隔
- p.push({ chessIndex: u[h].id, timeTag: 0 == d ? 0 : u[h].time - d }), d = u[h].time;
- console.log(p)
- GAMEDAILY = 3
- GAMETOPIC = 4
- for (var f = { gameType: GAMEDAILY, stepInfoList: p }, y = MatchPlayInfo.create(f), v = MatchPlayInfo.encode(y).finish(), b = "", _ = 0; _ < v.length; _++)
- b += String.fromCharCode(v[_]); // 序列化
- var data = Buffer.from(b).toString('base64');
- console.log(data);
- data = Buffer.from(data, 'base64');
- console.log(data);
- console.log(MatchPlayInfo.decode(data));
複製代碼 分析一下MatchPlayInfo的生成操作
首先可以得知MatchPlayInfo是由stepInfoList和gameType組成的,stepInfoList裡有兩個參數分別是chessIndex和timeTag,分別記錄點選卡片id和兩次操作間隔
觀察MatchPlayInfo.encode可以看到會建立一個protobuf.Writer對象- e.uint32(8).int32(t.gameType)
複製代碼 會建立序列"\x08\x03",雖然寫著是32但是經過偵錯發現是1位元組的,不知道是為什麼- MatchStepInfo.encode(t.stepInfoList[o], e.uint32(34).fork()).ldelim()
複製代碼 這裡首先插入1位元組34變成"\x08\x03\x22",接著fork函數會生成一個分叉,類似於git等待處理完這個分支後呼叫ldelim就會把當前分支上內容的長度和內容合併回主分支,分析MatchStepInfo.encode後可以得知會插入4個位元組,分別是[8,chessIndex,16,timeTag],此時序列就是"\x08\x03\x22"+"\x04"+"\x08\x00\x10\x00"="\x08\x03\x22\x04\x08\x00\x10\x00",重複這個過程把stepInfoList裡的chessIndex和timeTag循環增加到序列,可以得知生成過程是MatchPlayInfo="\x08\x03“+("\x04\x08\x??\x10\x??"*卡牌個數)
然而生成的序列無法增加通關次數,研究了一下發現stepInfoList裡的值大於127的數值是錯誤的,不知道是什麼原因,於是過濾掉大於127的數可以成功增加通關次數
python程式碼如下
所有站內附件皆會附上安全掃描報告 請會員查看純淨度百分比後判斷使用
相關檔案須知: 取得檔案前,請先詳細閱讀文章內容 避免不必要錯誤與誤會發生。 也可多參考文章討論樓層內容 了解附件檔案相關討論資訊。
|